native: handle some more statements and dont echo warnings (#12518)

pull/12519/head
pancake 2021-11-19 12:50:44 +01:00 committed by GitHub
parent fa995ca537
commit 80a4ff9900
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 55 deletions

View File

@ -1,6 +1,5 @@
module native module native
import term
import v.ast import v.ast
import v.token import v.token
@ -153,8 +152,6 @@ fn (mut g Gen) cjmp(op JumpOp) int {
return int(pos) return int(pos)
} }
// Returns the position of the address to jump to (set later).
fn (mut g Gen) jmp(addr int) { fn (mut g Gen) jmp(addr int) {
g.write8(0xe9) g.write8(0xe9)
g.write32(addr) // 0xffffff g.write32(addr) // 0xffffff
@ -426,10 +423,6 @@ pub fn (mut g Gen) gen_loop_end(to int, label int) {
g.jl(label) g.jl(label)
} }
pub fn (mut g Gen) save_main_fn_addr() {
g.main_fn_addr = i64(g.buf.len)
}
pub fn (mut g Gen) allocate_string(s string, opsize int) int { pub fn (mut g Gen) allocate_string(s string, opsize int) int {
g.strings << s g.strings << s
str_pos := g.buf.len + opsize str_pos := g.buf.len + opsize
@ -1373,39 +1366,13 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
g.println('jmp after for') g.println('jmp after for')
} }
fn (mut g Gen) fn_decl(node ast.FnDecl) { fn (mut g Gen) fn_decl_amd64(node ast.FnDecl) {
if g.pref.is_verbose {
println(term.green('\n$node.name:'))
}
// if g.is_method
if node.is_deprecated {
eprintln('fn_decl: $node.name is deprecated')
}
if node.is_builtin {
eprintln('fn_decl: $node.name is builtin')
}
g.stack_var_pos = 0
is_main := node.name == 'main.main'
// println('saving addr $node.name $g.buf.len.hex2()')
if is_main {
g.save_main_fn_addr()
} else {
g.register_function_address(node.name)
}
if g.pref.arch == .arm64 {
g.fn_decl_arm64(node)
return
}
g.push(.rbp) g.push(.rbp)
g.mov_rbp_rsp() g.mov_rbp_rsp()
locals_count := node.scope.objects.len + node.params.len locals_count := node.scope.objects.len + node.params.len
g.stackframe_size = (locals_count * 8) + 0x10 g.stackframe_size = (locals_count * 8) + 0x10
g.sub8(.rsp, g.stackframe_size) g.sub8(.rsp, g.stackframe_size)
if node.params.len > 0 {
// g.mov(.r12, 0x77777777)
}
// Copy values from registers to local vars (calling convention) // Copy values from registers to local vars (calling convention)
mut offset := 0 mut offset := 0
for i in 0 .. node.params.len { for i in 0 .. node.params.len {
@ -1418,6 +1385,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
} }
// //
g.stmts(node.stmts) g.stmts(node.stmts)
is_main := node.name == 'main.main'
if is_main { if is_main {
// println('end of main: gen exit') // println('end of main: gen exit')
zero := ast.IntegerLiteral{} zero := ast.IntegerLiteral{}
@ -1442,8 +1410,7 @@ pub fn (mut g Gen) allocate_array(name string, size int, items int) int {
} }
pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) int { pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) int {
// `a := 3` => // `a := 3` => `mov DWORD [rbp-0x4],0x3`
// `move DWORD [rbp-0x4],0x3`
match size { match size {
1 { 1 {
// BYTE // BYTE
@ -1473,6 +1440,6 @@ pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) int {
// Generate the value assigned to the variable // Generate the value assigned to the variable
g.write32(initial_val) g.write32(initial_val)
// println('allocate_var(size=$size, initial_val=$initial_val)') // println('allocate_var(size=$size, initial_val=$initial_val)')
g.println('mov DWORD [rbp-$n.hex2()],$initial_val (Allocate var `$name`)') g.println('mov [rbp-$n.hex2()], $initial_val (Allocate var `$name`)')
return g.stack_var_pos return g.stack_var_pos
} }

View File

@ -44,10 +44,9 @@ mut:
errors []errors.Error errors []errors.Error
warnings []errors.Warning warnings []errors.Warning
syms []Symbol syms []Symbol
// UNUSED relocs []Reloc size_pos []int
size_pos []int nlines int
nlines int callpatches []CallPatch
callpatches []CallPatch
} }
struct CallPatch { struct CallPatch {
@ -99,9 +98,11 @@ pub fn gen(files []&ast.File, table &ast.Table, out_name string, pref &pref.Pref
g.code_gen.g = g g.code_gen.g = g
g.generate_header() g.generate_header()
for file in files { for file in files {
/*
if file.warnings.len > 0 { if file.warnings.len > 0 {
eprintln('warning: ${file.warnings[0]}') eprintln('warning: ${file.warnings[0]}')
} }
*/
if file.errors.len > 0 { if file.errors.len > 0 {
g.n_error(file.errors[0].str()) g.n_error(file.errors[0].str())
} }
@ -307,6 +308,9 @@ pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, name string) {
} }
} }
ast.None {} ast.None {}
ast.EmptyExpr {
g.n_error('unhandled EmptyExpr')
}
ast.PostfixExpr {} ast.PostfixExpr {}
ast.PrefixExpr {} ast.PrefixExpr {}
ast.SelectorExpr { ast.SelectorExpr {
@ -323,6 +327,7 @@ g.expr
dump(expr) dump(expr)
g.v_error('struct.field selector not yet implemented for this backend', expr.pos) g.v_error('struct.field selector not yet implemented for this backend', expr.pos)
} }
ast.NodeError {}
/* /*
ast.AnonFn {} ast.AnonFn {}
ast.ArrayDecompose {} ast.ArrayDecompose {}
@ -339,45 +344,72 @@ g.expr
ast.ComptimeSelector {} ast.ComptimeSelector {}
ast.ConcatExpr {} ast.ConcatExpr {}
ast.DumpExpr {} ast.DumpExpr {}
ast.EmptyExpr {}
ast.EnumVal {} ast.EnumVal {}
ast.FloatLiteral {}
ast.GoExpr {} ast.GoExpr {}
ast.IfExpr {}
ast.IfGuardExpr {} ast.IfGuardExpr {}
ast.IndexExpr {} ast.IndexExpr {}
ast.InfixExpr {} ast.InfixExpr {}
ast.IsRefType {} ast.IsRefType {}
ast.Likely {}
ast.LockExpr {}
ast.MapInit {} ast.MapInit {}
ast.MatchExpr {} ast.MatchExpr {}
ast.NodeError {}
ast.OrExpr {} ast.OrExpr {}
ast.ParExpr {} ast.ParExpr {}
ast.RangeExpr {} ast.RangeExpr {}
ast.SelectExpr {} ast.SelectExpr {}
ast.SqlExpr {} ast.SqlExpr {}
ast.StringInterLiteral {}
ast.StructInit {}
ast.TypeNode {} ast.TypeNode {}
ast.TypeOf {} ast.TypeOf {}
ast.UnsafeExpr {}
*/ */
ast.LockExpr {
// passthru
eprintln('Warning: locks not implemented yet in the native backend')
g.expr(expr)
}
ast.Likely {
// passthru
g.expr(expr)
}
ast.UnsafeExpr {
// passthru
g.expr(expr)
}
ast.StringInterLiteral {
g.n_error('Interlaced string literals are not yet supported in the native backend.') // , expr.pos)
}
else { else {
dump(typeof(expr).name) dump(typeof(expr).name)
dump(expr) dump(expr)
// g.v_error('expected string as argument for print', expr.pos) // g.v_error('expected string as argument for print', expr.pos)
g.n_error('expected string as argument for print') // , expr.pos) g.n_error('expected string as argument for print') // , expr.pos)
// g.warning('expected string as argument for print')
} }
} }
} }
fn (mut g Gen) fn_decl(node ast.FnDecl) {
if g.pref.is_verbose {
println(term.green('\n$node.name:'))
}
if node.is_deprecated {
g.warning('fn_decl: $node.name is deprecated', node.pos)
}
if node.is_builtin {
g.warning('fn_decl: $node.name is builtin', node.pos)
}
g.stack_var_pos = 0
g.register_function_address(node.name)
if g.pref.arch == .arm64 {
g.fn_decl_arm64(node)
} else {
g.fn_decl_amd64(node)
}
}
pub fn (mut g Gen) register_function_address(name string) { pub fn (mut g Gen) register_function_address(name string) {
addr := g.pos() if name == 'main.main' {
// eprintln('register function $name = $addr') g.main_fn_addr = i64(g.buf.len)
g.fn_addr[name] = addr } else {
g.fn_addr[name] = g.pos()
}
} }
fn (mut g Gen) println(comment string) { fn (mut g Gen) println(comment string) {
@ -604,7 +636,7 @@ fn (mut g Gen) expr(node ast.Expr) {
ast.StringLiteral {} ast.StringLiteral {}
ast.StructInit {} ast.StructInit {}
ast.GoExpr { ast.GoExpr {
g.v_error('native backend doesnt support threads yet', node.pos) // token.Position{}) g.v_error('native backend doesnt support threads yet', node.pos)
} }
else { else {
g.n_error('expr: unhandled node type: $node.type_name()') g.n_error('expr: unhandled node type: $node.type_name()')