From 627400723c6bf95078768ee9e14ab8f2cdb5b17f Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 17 May 2020 15:45:11 +0300 Subject: [PATCH] x64 gen: improve error handling for unknown nodes --- vlib/v/builder/builder.v | 3 ++- vlib/v/builder/x64.v | 2 +- vlib/v/gen/x64/gen.v | 37 ++++++++++++++++++++++++++++--- vlib/v/gen/x64/tests/hello.vv | 2 +- vlib/v/gen/x64/tests/hello.vv.out | 1 - 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index a19859e4c5..9d0ae9e81d 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -95,7 +95,8 @@ pub fn (mut b Builder) parse_imports() { pub fn (mut b Builder) resolve_deps() { graph := b.import_graph() deps_resolved := graph.resolve() - if !deps_resolved.acyclic { + is_main_to_builtin := deps_resolved.nodes.len == 1 && deps_resolved.nodes[0].name == 'main' && deps_resolved.nodes[0].deps.len == 1 && deps_resolved.nodes[0].deps[0] == 'builtin' + if !deps_resolved.acyclic && !is_main_to_builtin { eprintln('warning: import cycle detected between the following modules: \n' + deps_resolved.display_cycles()) // TODO: error, when v itself does not have v.table -> v.ast -> v.table cycles anymore return diff --git a/vlib/v/builder/x64.v b/vlib/v/builder/x64.v index e2cd86802c..2c89c98584 100644 --- a/vlib/v/builder/x64.v +++ b/vlib/v/builder/x64.v @@ -21,7 +21,7 @@ pub fn (mut b Builder) build_x64(v_files []string, out_file string) { t2 := time.ticks() check_time := t2 - t1 b.info('CHECK: ${check_time}ms') - x64.gen(b.parsed_files, out_file) + x64.gen(b.parsed_files, out_file, b.pref) t3 := time.ticks() gen_time := t3 - t2 b.info('x64 GEN: ${gen_time}ms') diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index 79a02aac9e..6486a03052 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -5,11 +5,15 @@ module x64 import v.ast import v.util +import v.token +import v.errors +import v.pref import term import strings pub struct Gen { out_name string + pref &pref.Preferences // Preferences shared from V struct mut: buf []byte sect_header_name_pos int @@ -23,6 +27,8 @@ mut: var_offset map[string]int // local var stack offset stack_var_pos int debug_pos int + errors []errors.Error + warnings []errors.Warning } // string_addr map[string]i64 @@ -72,10 +78,11 @@ enum Size { _64 } -pub fn gen(files []ast.File, out_name string) { +pub fn gen(files []ast.File, out_name string, pref &pref.Preferences) { mut g := Gen{ sect_header_name_pos: 0 out_name: out_name + pref: pref } g.generate_elf_header() for file in files { @@ -306,6 +313,8 @@ fn (mut g Gen) mov_from_reg(var_offset int, reg Register) { match reg { .edi, .rdi { g.write8(0x7d) } .rsi { g.write8(0x75) } + .rdx { g.write8(0x55) } + .rcx { g.write8(0x4d) } else { verror('mov_from_reg $reg') } } g.write8(0xff - var_offset + 1) @@ -537,6 +546,9 @@ fn (mut g Gen) stmt(node ast.Stmt) { g.ret() } ast.StructDecl {} + ast.UnsafeStmt { + g.stmts(it.stmts) + } else { println('x64.stmt(): bad node: ' + typeof(node)) } @@ -572,7 +584,7 @@ fn (mut g Gen) expr(node ast.Expr) { ast.StructInit {} ast.BoolLiteral {} else { - // println(term.red('x64.expr(): bad node')) + println(term.red('x64.expr(): unhandled node: ' + typeof(node))) } } } @@ -624,7 +636,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { g.allocate_var(ident.name, 4, 0) } else { - verror('assign_stmt unhandled expr') + g.error_with_pos('assign_stmt unhandled expr: ' + typeof(node.right[0]), node.right[0].position()) } } } @@ -741,3 +753,22 @@ fn (mut g Gen) postfix_expr(node ast.PostfixExpr) { fn verror(s string) { util.verror('x64 gen error', s) } + +pub fn (mut g Gen) error_with_pos(s string, pos token.Position) { + // TODO: store a file index in the Position too, + // so that the file path can be retrieved from the pos, instead + // of guessed from the pref.path ... + mut kind := 'error:' + if g.pref.output_mode == .stdout { + ferror := util.formatted_error(kind, s, g.pref.path, pos) + eprintln(ferror) + exit(1) + } else { + g.errors << errors.Error{ + file_path: g.pref.path + pos: pos + reporter: .gen + message: s + } + } +} diff --git a/vlib/v/gen/x64/tests/hello.vv b/vlib/v/gen/x64/tests/hello.vv index 74fb3286d9..606fe42ec0 100644 --- a/vlib/v/gen/x64/tests/hello.vv +++ b/vlib/v/gen/x64/tests/hello.vv @@ -1,3 +1,3 @@ fn main() { - print('hello from x64') + println('hello from x64') } diff --git a/vlib/v/gen/x64/tests/hello.vv.out b/vlib/v/gen/x64/tests/hello.vv.out index 3584c32f4a..985a7456fb 100644 --- a/vlib/v/gen/x64/tests/hello.vv.out +++ b/vlib/v/gen/x64/tests/hello.vv.out @@ -1,2 +1 @@ hello from x64 -