diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v index 25d7cabb89..fd44bed67c 100644 --- a/vlib/v/gen/native/amd64.v +++ b/vlib/v/gen/native/amd64.v @@ -361,10 +361,40 @@ pub fn (mut g Gen) gen_print(s string) { g.syscall() } -pub fn (mut g Gen) gen_exit() { - // Return 0 - g.mov(.edi, 0) // ret value - g.mov(.eax, 60) +fn (mut g Gen) nsyscall_exit() int { + match g.pref.os { + .linux { + return 60 + } + .macos { + return 0x2000001 + } + else { + verror('unsupported exit syscall for this platform') + } + } + return 0 +} + +pub fn (mut g Gen) gen_amd64_exit(expr ast.Expr) { + // ret value + match expr { + ast.CallExpr { + right := expr.return_type + verror('native exit builtin: Unsupported call $right') + } + ast.Ident { + var_offset := g.get_var_offset(expr.name) + g.mov_var_to_reg(.edi, var_offset) + } + ast.IntegerLiteral { + g.mov(.edi, expr.val.int()) + } + else { + verror('native builtin exit expects a numeric argument') + } + } + g.mov(.eax, g.nsyscall_exit()) g.syscall() } @@ -626,7 +656,8 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) { g.stmts(node.stmts) if is_main { // println('end of main: gen exit') - g.gen_exit() + zero := ast.IntegerLiteral{} + g.gen_exit(zero) // return } if !is_main { diff --git a/vlib/v/gen/native/arm64.v b/vlib/v/gen/native/arm64.v index c0974648ca..f6f6f496a6 100644 --- a/vlib/v/gen/native/arm64.v +++ b/vlib/v/gen/native/arm64.v @@ -100,3 +100,16 @@ fn (mut g Gen) svc() { g.write32(0xd4001001) g.println('svc') } + +pub fn (mut g Gen) gen_arm64_exit(expr ast.Expr) { + match expr { + ast.IntegerLiteral { + g.mov_arm(.x16, expr.val.u64()) + } + else { + verror('native builtin exit expects a numeric argument') + } + } + g.mov_arm(.x0, 0) + g.svc() +} diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index 2b895fe639..ea1dce15da 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -259,6 +259,20 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { */ } +pub fn (mut g Gen) gen_exit(node ast.Expr) { + match g.pref.arch { + .amd64 { + g.gen_amd64_exit(node) + } + .arm64 { + g.gen_arm64_exit(node) + } + else { + verror('native exit not implemented for this architecture $g.pref.arch') + } + } +} + fn (mut g Gen) stmt(node ast.Stmt) { match node { ast.AssignStmt { @@ -294,7 +308,8 @@ fn (mut g Gen) stmt(node ast.Stmt) { } ast.Module {} ast.Return { - g.gen_exit() + zero := ast.IntegerLiteral{} + g.gen_exit(zero) g.ret() } ast.StructDecl {} @@ -311,6 +326,11 @@ fn (mut g Gen) expr(node ast.Expr) { ast.ArrayInit {} ast.BoolLiteral {} ast.CallExpr { + if node.name == 'exit' { + expr := node.args[0].expr + g.gen_exit(expr) + return + } if node.name in ['println', 'print', 'eprintln', 'eprint'] { expr := node.args[0].expr g.gen_print_from_expr(expr, node.name in ['println', 'eprintln']) diff --git a/vlib/v/gen/native/macho.v b/vlib/v/gen/native/macho.v index 7005263cc5..122441f665 100644 --- a/vlib/v/gen/native/macho.v +++ b/vlib/v/gen/native/macho.v @@ -101,7 +101,6 @@ pub fn (mut g Gen) generate_macho_header() { if g.pref.arch == .arm64 { g.gen_arm64_helloworld() } - } pub fn (mut g Gen) generate_macho_footer() {