From 871c29ea5d11253e9aab4488b010946c04af190c Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Mon, 20 Apr 2020 22:21:29 +0200 Subject: [PATCH] x64: fn calls; return; --- vlib/v/gen/x64/elf.v | 1 + vlib/v/gen/x64/gen.v | 41 +++++++++++++++++++++++------------------ vlib/v/token/token.v | 4 +--- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/vlib/v/gen/x64/elf.v b/vlib/v/gen/x64/elf.v index b9bdde1397..2098e9ef9f 100644 --- a/vlib/v/gen/x64/elf.v +++ b/vlib/v/gen/x64/elf.v @@ -66,6 +66,7 @@ pub fn (var g Gen) generate_elf_header() { g.write64(0x1000) // p_align // user code starts here at // address: 00070 and a half + println('code_start_pos = $g.buf.len.hex()') g.code_start_pos = g.buf.len g.call(PLACEHOLDER) // call main function, it's not guaranteed to be the first, we don't know its address yet } diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index 53525ff788..02dc911d4f 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -194,11 +194,14 @@ fn (var g Gen) mov64(reg Register, val i64) { } fn (var g Gen) call(addr int) { - // rel := g.abs_to_rel_addr(addr) - // rel := 0xffffffff - int(abs(addr - g.buf.len))-1 - println('call addr=$addr rel_addr=$addr pos=$g.buf.len') + // Need to calculate the difference between current position (position after the e8 call) + // and the function to call. + // +5 is to get the posistion "e8 xx xx xx xx" + // Not sure about the -1. + rel := 0xffffffff - (g.buf.len + 5 - addr - 1) + println('call addr=$addr.hex() rel_addr=$rel.hex() pos=$g.buf.len') g.write8(0xe8) - g.write32(addr) + g.write32(rel) } fn (var g Gen) syscall() { @@ -300,10 +303,14 @@ pub fn (g &Gen) writeln(s string) { } pub fn (var g Gen) call_fn(name string) { + println('call fn $name') if !name.contains('__') { - return + // return } addr := g.fn_addr[name] + if addr == 0 { + verror('fn addr of `$name` = 0') + } g.call(int(addr)) println('call $name $addr') } @@ -313,8 +320,11 @@ fn (var g Gen) stmt(node ast.Stmt) { ast.ConstDecl {} ast.FnDecl { is_main := it.name == 'main' + println('saving addr $it.name $g.buf.len.hex()') if is_main { g.save_main_fn_addr() + } else { + g.register_function_address(it.name) } for arg in it.args { } @@ -324,11 +334,14 @@ fn (var g Gen) stmt(node ast.Stmt) { if is_main { println('end of main: gen exit') g.gen_exit() - // g.write32(0x88888888) + // return } - // g.ret() + g.ret() + } + ast.Return { + g.gen_exit() + g.ret() } - ast.Return {} ast.AssignStmt {} ast.ForStmt {} ast.StructDecl {} @@ -360,17 +373,9 @@ fn (var g Gen) expr(node ast.Expr) { if it.name in ['println', 'print', 'eprintln', 'eprint'] { expr := it.args[0].expr g.gen_print_from_expr(expr, it.name in ['println', 'eprintln']) + return } - /* - g.write('${it.name}(') - for i, expr in it.args { - g.expr(expr) - if i != it.args.len - 1 { - g.write(', ') - } - } - g.write(')') -*/ + g.call_fn(it.name) } ast.ArrayInit {} ast.Ident {} diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index d49831a366..b348062361 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -98,7 +98,6 @@ pub enum Kind { key_goto key_if key_import - key_import_const key_in key_interface key_is @@ -234,7 +233,6 @@ fn build_token_str() []string { s[Kind.key_enum] = 'enum' s[Kind.key_interface] = 'interface' s[Kind.key_pub] = 'pub' - s[Kind.key_import_const] = 'import_const' s[Kind.key_in] = 'in' s[Kind.key_atomic] = 'atomic' s[Kind.key_orelse] = 'or' @@ -267,7 +265,7 @@ pub fn is_key(key string) bool { } pub fn is_decl(t Kind) bool { - return t in [.key_enum, .key_interface, .key_fn, .key_struct, .key_type, .key_const, .key_import_const, .key_pub, .eof] + return t in [.key_enum, .key_interface, .key_fn, .key_struct, .key_type, .key_const, .key_pub, .eof] } pub fn (t Kind) is_assign() bool {