native: support defining functions in any order (#12511)
parent
d498c365c2
commit
b367ed9ba3
|
@ -778,10 +778,6 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
|
|||
n = 'main.$n'
|
||||
}
|
||||
addr := g.fn_addr[n]
|
||||
if addr == 0 {
|
||||
// g.warning('fn addr of `$name` = 0')
|
||||
g.n_error('fn addr of `$name` = 0')
|
||||
}
|
||||
// Copy values to registers (calling convention)
|
||||
// g.mov(.eax, 0)
|
||||
for i in 0 .. node.args.len {
|
||||
|
@ -808,11 +804,41 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
|
|||
if node.args.len > 6 {
|
||||
g.v_error('more than 6 args not allowed for now', node.pos)
|
||||
}
|
||||
g.call(int(addr))
|
||||
if addr == 0 {
|
||||
g.delay_fn_call(name)
|
||||
g.call(int(0))
|
||||
} else {
|
||||
g.call(int(addr))
|
||||
}
|
||||
g.println('fn call `${name}()`')
|
||||
// println('call $name $addr')
|
||||
}
|
||||
|
||||
fn (mut g Gen) patch_calls() {
|
||||
for c in g.callpatches {
|
||||
addr := g.fn_addr[c.name]
|
||||
if addr == 0 {
|
||||
g.n_error('fn addr of `$c.name` = 0')
|
||||
return
|
||||
}
|
||||
last := g.buf.len
|
||||
g.call(int(addr + last - c.pos))
|
||||
mut patch := []byte{}
|
||||
for last < g.buf.len {
|
||||
patch << g.buf.pop()
|
||||
}
|
||||
for i := 0; i < patch.len; i++ {
|
||||
g.buf[c.pos + i] = patch[patch.len - i - 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) delay_fn_call(name string) {
|
||||
pos := g.buf.len
|
||||
g.callpatches << CallPatch{name, pos}
|
||||
// do nothing for now
|
||||
}
|
||||
|
||||
fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
|
||||
// `a := 1` | `a,b := 1,2`
|
||||
for i, left in node.left {
|
||||
|
|
|
@ -44,9 +44,15 @@ mut:
|
|||
errors []errors.Error
|
||||
warnings []errors.Warning
|
||||
syms []Symbol
|
||||
relocs []Reloc
|
||||
size_pos []int
|
||||
nlines int
|
||||
// UNUSED relocs []Reloc
|
||||
size_pos []int
|
||||
nlines int
|
||||
callpatches []CallPatch
|
||||
}
|
||||
|
||||
struct CallPatch {
|
||||
name string
|
||||
pos int
|
||||
}
|
||||
|
||||
enum Size {
|
||||
|
@ -141,6 +147,7 @@ pub fn (mut g Gen) create_executable() {
|
|||
}
|
||||
|
||||
pub fn (mut g Gen) generate_footer() {
|
||||
g.patch_calls()
|
||||
match g.pref.os {
|
||||
.macos {
|
||||
g.generate_macho_footer()
|
||||
|
|
Loading…
Reference in New Issue