native: support defining functions in any order (#12511)

pull/12518/head
pancake 2021-11-19 09:25:42 +01:00 committed by GitHub
parent d498c365c2
commit b367ed9ba3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 8 deletions

View File

@ -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 {

View File

@ -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()