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'
|
n = 'main.$n'
|
||||||
}
|
}
|
||||||
addr := g.fn_addr[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)
|
// Copy values to registers (calling convention)
|
||||||
// g.mov(.eax, 0)
|
// g.mov(.eax, 0)
|
||||||
for i in 0 .. node.args.len {
|
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 {
|
if node.args.len > 6 {
|
||||||
g.v_error('more than 6 args not allowed for now', node.pos)
|
g.v_error('more than 6 args not allowed for now', node.pos)
|
||||||
}
|
}
|
||||||
|
if addr == 0 {
|
||||||
|
g.delay_fn_call(name)
|
||||||
|
g.call(int(0))
|
||||||
|
} else {
|
||||||
g.call(int(addr))
|
g.call(int(addr))
|
||||||
|
}
|
||||||
g.println('fn call `${name}()`')
|
g.println('fn call `${name}()`')
|
||||||
// println('call $name $addr')
|
// 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) {
|
fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
|
||||||
// `a := 1` | `a,b := 1,2`
|
// `a := 1` | `a,b := 1,2`
|
||||||
for i, left in node.left {
|
for i, left in node.left {
|
||||||
|
|
|
@ -44,9 +44,15 @@ mut:
|
||||||
errors []errors.Error
|
errors []errors.Error
|
||||||
warnings []errors.Warning
|
warnings []errors.Warning
|
||||||
syms []Symbol
|
syms []Symbol
|
||||||
relocs []Reloc
|
// UNUSED relocs []Reloc
|
||||||
size_pos []int
|
size_pos []int
|
||||||
nlines int
|
nlines int
|
||||||
|
callpatches []CallPatch
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CallPatch {
|
||||||
|
name string
|
||||||
|
pos int
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Size {
|
enum Size {
|
||||||
|
@ -141,6 +147,7 @@ pub fn (mut g Gen) create_executable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut g Gen) generate_footer() {
|
pub fn (mut g Gen) generate_footer() {
|
||||||
|
g.patch_calls()
|
||||||
match g.pref.os {
|
match g.pref.os {
|
||||||
.macos {
|
.macos {
|
||||||
g.generate_macho_footer()
|
g.generate_macho_footer()
|
||||||
|
|
Loading…
Reference in New Issue