From 91eca539d026b538a87d240f47d5210fccba29b7 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Mon, 30 Nov 2020 00:10:45 +1100 Subject: [PATCH] all: -usecache fixes and self compilation & some type cname optimisation (#7015) --- vlib/v/checker/checker.v | 11 ++-- vlib/v/gen/auto_str_methods.v | 2 +- vlib/v/gen/cgen.v | 113 ++++++++++++++++++++++------------ vlib/v/parser/parse_type.v | 3 + vlib/v/parser/parser.v | 4 ++ vlib/v/parser/struct.v | 2 + vlib/v/table/table.v | 8 +++ vlib/v/table/types.v | 30 +++++++++ 8 files changed, 126 insertions(+), 47 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 9142767b24..c128732f04 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3558,23 +3558,24 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol mut expr_type := table.Type(0) if expr_types.len > 1 { mut agg_name := strings.new_builder(20) + mut agg_cname := strings.new_builder(20) agg_name.write('(') for i, expr in expr_types { if i > 0 { agg_name.write(' | ') + agg_cname.write('___') } type_str := c.table.type_to_str(expr.typ) - agg_name.write(if c.is_builtin_mod { - type_str - } else { - '${c.mod}.$type_str' - }) + name := if c.is_builtin_mod { type_str } else { '${c.mod}.$type_str' } + agg_name.write(name) + agg_cname.write(util.no_dots(name)) } agg_name.write(')') name := agg_name.str() expr_type = c.table.register_type_symbol(table.TypeSymbol{ name: name source_name: name + cname: agg_cname.str() kind: .aggregate mod: c.mod info: table.Aggregate{ diff --git a/vlib/v/gen/auto_str_methods.v b/vlib/v/gen/auto_str_methods.v index 062b6eae5a..2a4c9085a9 100644 --- a/vlib/v/gen/auto_str_methods.v +++ b/vlib/v/gen/auto_str_methods.v @@ -521,7 +521,7 @@ fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_f if sym.kind == .struct_ { func_name = 'indent_$func_name' } - g.auto_str_funcs.write('\t\tcase $typ: return _STR("${clean_sum_type_v_type_name}($value_fmt)", 2, ${func_name}(*($typ_str*)x._$typ.idx()') + g.auto_str_funcs.write('\t\tcase $typ: return _STR("${clean_sum_type_v_type_name}($value_fmt)", 2, ${func_name}(*($typ_str*)x._$sym.cname') if sym.kind == .struct_ { g.auto_str_funcs.write(', indent_count') } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index efde24cf2e..0c9aa092e6 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -201,6 +201,22 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string if autofree_used { g.autofree = true // so that void _vcleanup is generated } + // to make sure type idx's are the same in cached mods + if g.pref.build_mode == .build_module { + for idx, typ in g.table.types { + if idx == 0 { + continue + } + g.definitions.writeln('int _v_type_idx_${typ.cname}();') + } + } else if g.pref.use_cache { + for idx, typ in g.table.types { + if idx == 0 { + continue + } + g.definitions.writeln('int _v_type_idx_${typ.cname}() { return $idx; };') + } + } g.write_variadic_types() // g.write_str_definitions() // v files are finished, what remains is pure C code @@ -268,10 +284,10 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string b.write(g.stringliterals.str()) } if g.auto_str_funcs.len > 0 { - if g.pref.build_mode != .build_module { - b.writeln('\n// V auto str functions:') - b.write(g.auto_str_funcs.str()) - } + // if g.pref.build_mode != .build_module { + b.writeln('\n// V auto str functions:') + b.write(g.auto_str_funcs.str()) + // } } b.writeln('\n// V out') b.write(g.out.str()) @@ -499,7 +515,7 @@ static inline $opt_el_type __Option_${styp}_popval($styp ch) { // cc_type but without the `struct` prefix fn (g &Gen) cc_type2(t table.Type) string { sym := g.table.get_type_symbol(g.unwrap_generic(t)) - mut styp := util.no_dots(sym.name) + mut styp := sym.cname if mut sym.info is table.Struct { if sym.info.generic_types.len > 0 { mut sgtyps := '_T' @@ -532,6 +548,15 @@ fn (g &Gen) cc_type(t table.Type) string { return styp } +[inline] +fn (g &Gen) type_sidx(t table.Type) string { + if g.pref.build_mode == .build_module { + sym := g.table.get_type_symbol(t) + return '_v_type_idx_${sym.cname}()' + } + return '$t.idx()' +} + // pub fn (mut g Gen) write_typedef_types() { g.typedefs.writeln(' @@ -544,39 +569,35 @@ typedef struct { match typ.kind { .alias { parent := unsafe {&g.table.types[typ.parent_idx]} - styp := util.no_dots(typ.name) is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.` - parent_styp := if is_c_parent { 'struct ' + util.no_dots(parent.name[2..]) } else { util.no_dots(parent.name) } - g.type_definitions.writeln('typedef $parent_styp $styp;') + parent_styp := if is_c_parent { 'struct ' + parent.cname[3..] } else { parent.cname } + g.type_definitions.writeln('typedef $parent_styp $typ.cname;') } .array { - styp := util.no_dots(typ.name) - g.type_definitions.writeln('typedef array $styp;') + g.type_definitions.writeln('typedef array $typ.cname;') } .interface_ { g.type_definitions.writeln('typedef _Interface ${c_name(typ.name)};') } .chan { if typ.name != 'chan' { - styp := util.no_dots(typ.name) - g.type_definitions.writeln('typedef chan $styp;') + g.type_definitions.writeln('typedef chan $typ.cname;') chan_inf := typ.chan_info() el_stype := g.typ(chan_inf.elem_type) g.channel_definitions.writeln(' -static inline $el_stype __${styp}_popval($styp ch) { +static inline $el_stype __${typ.cname}_popval($typ.cname ch) { $el_stype val; sync__Channel_try_pop_priv(ch, &val, false); return val; }') g.channel_definitions.writeln(' -static inline void __${styp}_pushval($styp ch, $el_stype val) { +static inline void __${typ.cname}_pushval($typ.cname ch, $el_stype val) { sync__Channel_try_push_priv(ch, &val, false); }') } } .map { - styp := util.no_dots(typ.name) - g.type_definitions.writeln('typedef map $styp;') + g.type_definitions.writeln('typedef map $typ.cname;') } .function { g.write_fn_typesymbol_declaration(typ) @@ -621,7 +642,6 @@ pub fn (mut g Gen) write_multi_return_type_declaration(mut sym table.TypeSymbol) if sym.is_written { return } - name := util.no_dots(sym.name) info := sym.info as table.MultiReturn g.type_definitions.writeln('typedef struct {') // TODO copy pasta StructDecl @@ -630,7 +650,7 @@ pub fn (mut g Gen) write_multi_return_type_declaration(mut sym table.TypeSymbol) type_name := g.typ(mr_typ) g.type_definitions.writeln('\t$type_name arg$i;') } - g.type_definitions.writeln('} $name;\n') + g.type_definitions.writeln('} $sym.cname;\n') // g.typedefs.writeln('typedef struct $name $name;') sym.is_written = true } @@ -1260,23 +1280,24 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type table.Type, expected_type if g.table.sumtype_has_variant(expected_deref_type, got_deref_type) { exp_styp := g.typ(expected_type) got_styp := g.typ(got_type) - got_idx := got_type.idx() + // got_idx := got_type.idx() got_sym := g.table.get_type_symbol(got_type) + got_sidx := g.type_sidx(got_type) // TODO: do we need 1-3? if expected_is_ptr && got_is_ptr { exp_der_styp := g.typ(expected_deref_type) - g.write('/* sum type cast 1 */ ($exp_styp) memdup(&($exp_der_styp){._$got_type = ') + g.write('/* sum type cast 1 */ ($exp_styp) memdup(&($exp_der_styp){._$got_sym.cname = ') g.expr(expr) - g.write(', .typ = $got_type /* $got_sym.name */}, sizeof($exp_der_styp))') + g.write(', .typ = $got_sidx /* $got_sym.name */}, sizeof($exp_der_styp))') } else if expected_is_ptr { exp_der_styp := g.typ(expected_deref_type) - g.write('/* sum type cast 2 */ ($exp_styp) memdup(&($exp_der_styp){._$got_type = memdup(&($got_styp[]){') + g.write('/* sum type cast 2 */ ($exp_styp) memdup(&($exp_der_styp){._$got_sym.cname = memdup(&($got_styp[]){') g.expr(expr) - g.write('}, sizeof($got_styp)), .typ = $got_type /* $got_sym.name */}, sizeof($exp_der_styp))') + g.write('}, sizeof($got_styp)), .typ = $got_sidx /* $got_sym.name */}, sizeof($exp_der_styp))') } else if got_is_ptr { - g.write('/* sum type cast 3 */ ($exp_styp){._$got_idx = ') + g.write('/* sum type cast 3 */ ($exp_styp){._$got_sym.cname = ') g.expr(expr) - g.write(', .typ = $got_type /* $got_sym.name */}') + g.write(', .typ = $got_sidx /* $got_sym.name */}') } else { mut is_already_sum_type := false scope := g.file.scope.innermost(expr.position().pos) @@ -1296,9 +1317,9 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type table.Type, expected_type g.prevent_sum_type_unwrapping_once = true g.expr(expr) } else { - g.write('/* sum type cast 4 */ ($exp_styp){._$got_type = memdup(&($got_styp[]){') + g.write('/* sum type cast 4 */ ($exp_styp){._$got_sym.cname = memdup(&($got_styp[]){') g.expr(expr) - g.write('}, sizeof($got_styp)), .typ = $got_type /* $got_sym.name */}') + g.write('}, sizeof($got_styp)), .typ = $got_sidx /* $got_sym.name */}') } } return @@ -2508,9 +2529,11 @@ fn (mut g Gen) expr(node ast.Expr) { sum_type_deref_field += ').' } if mut cast_sym.info is table.Aggregate { - sum_type_deref_field += '_${cast_sym.info.types[g.aggregate_type_idx]}' + agg_sym := g.table.get_type_symbol(cast_sym.info.types[g.aggregate_type_idx]) + sum_type_deref_field += '_$agg_sym.cname' + // sum_type_deref_field += '_${cast_sym.info.types[g.aggregate_type_idx]}' } else { - sum_type_deref_field += '_$typ' + sum_type_deref_field += '_$cast_sym.cname' } } } @@ -2549,9 +2572,11 @@ fn (mut g Gen) expr(node ast.Expr) { ast.Type { // match sum Type // g.write('/* Type */') - type_idx := node.typ.idx() + // type_idx := node.typ.idx() sym := g.table.get_type_symbol(node.typ) - g.write('$type_idx /* $sym.name */') + sidx := g.type_sidx(node.typ) + // g.write('$type_idx /* $sym.name */') + g.write('$sidx /* $sym.name */') } ast.TypeOf { g.typeof_expr(node) @@ -3321,9 +3346,10 @@ fn (mut g Gen) ident(node ast.Ident) { g.write(name) } if mut cast_sym.info is table.Aggregate { - g.write('._${cast_sym.info.types[g.aggregate_type_idx]}') + sym := g.table.get_type_symbol(cast_sym.info.types[g.aggregate_type_idx]) + g.write('._$sym.cname') } else { - g.write('._$typ') + g.write('._$cast_sym.cname') } g.write(')') } @@ -4450,7 +4476,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { continue } // sym := g.table.get_type_symbol(typ) - mut name := util.no_dots(typ.name) + mut name := typ.cname match mut typ.info { table.Struct { if typ.info.generic_types.len > 0 { @@ -4509,7 +4535,8 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { g.type_definitions.writeln('struct $name {') g.type_definitions.writeln(' union {') for variant in typ.info.variants { - g.type_definitions.writeln(' ${g.typ(variant.to_ptr())} _$variant.idx();') + variant_sym := g.table.get_type_symbol(variant) + g.type_definitions.writeln(' ${g.typ(variant.to_ptr())} _$variant_sym.cname;') } g.type_definitions.writeln(' };') g.type_definitions.writeln(' int typ;') @@ -4518,7 +4545,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { } table.ArrayFixed { // .array_fixed { - styp := util.no_dots(typ.name) + styp := typ.cname // array_fixed_char_300 => char x[300] mut fixed := styp[12..] len := styp.after('_') @@ -5446,6 +5473,7 @@ fn (mut g Gen) as_cast(node ast.AsCast) { // are the same), otherwise panic. // g.insert_before(' styp := g.typ(node.typ) + sym := g.table.get_type_symbol(node.typ) expr_type_sym := g.table.get_type_symbol(node.expr_type) if expr_type_sym.kind == .sum_type { dot := if node.expr_type.is_ptr() { '->' } else { '.' } @@ -5453,11 +5481,13 @@ fn (mut g Gen) as_cast(node ast.AsCast) { g.expr(node.expr) g.write(')') g.write(dot) - g.write('_$node.typ.idx(), (') + g.write('_$sym.cname, (') g.expr(node.expr) g.write(')') g.write(dot) - g.write('typ, /*expected:*/$node.typ)') + // g.write('typ, /*expected:*/$node.typ)') + sidx := g.type_sidx(node.typ) + g.write('typ, /*expected:*/$sidx)') } } @@ -5492,9 +5522,10 @@ fn styp_to_str_fn_name(styp string) string { [inline] fn (mut g Gen) gen_str_for_type(typ table.Type) string { - if g.pref.build_mode == .build_module { - return '' - } + // note: why was this here, removed for --usecache fix + // if g.pref.build_mode == .build_module { + // return '' + // } styp := g.typ(typ) return g.gen_str_for_type_with_styp(typ, styp) } diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 1dfcaa9c94..87194f5697 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -4,6 +4,7 @@ module parser import v.table +import v.util pub fn (mut p Parser) parse_array_type() table.Type { p.check(.lsbr) @@ -333,6 +334,7 @@ pub fn (mut p Parser) parse_generic_template_type(name string) table.Type { idx = p.table.register_type_symbol(table.TypeSymbol{ name: name source_name: name + cname: util.no_dots(name) mod: p.mod kind: .any is_public: true @@ -378,6 +380,7 @@ pub fn (mut p Parser) parse_generic_struct_inst_type(name string) table.Type { kind: .generic_struct_inst name: bs_name source_name: bs_name + cname: util.no_dots(bs_name) mod: p.mod info: table.GenericStructInst{ parent_idx: parent_idx diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 80cbc34609..3ad42b4f3c 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1635,6 +1635,7 @@ fn (mut p Parser) import_syms(mut parent ast.Import) { kind: .alias name: prepend_mod_name source_name: prepend_mod_name + cname: util.no_dots(prepend_mod_name) mod: p.mod parent_idx: idx info: table.Alias{ @@ -1889,6 +1890,7 @@ $pubfn (mut e $enum_name) toggle(flag $enum_name) { unsafe{ *e = int(*e) ^ ( kind: .enum_ name: name source_name: name + cname: util.no_dots(name) mod: p.mod info: table.Enum{ vals: vals @@ -1971,6 +1973,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl { kind: .sum_type name: prepend_mod_name source_name: prepend_mod_name + cname: util.no_dots(prepend_mod_name) mod: p.mod info: table.SumType{ variants: variant_types @@ -2002,6 +2005,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl { kind: .alias name: prepend_mod_name source_name: prepend_mod_name + cname: util.no_dots(prepend_mod_name) mod: p.mod parent_idx: pid info: table.Alias{ diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 8b1acdaef2..4d245503cd 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -252,6 +252,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { name: name language: language source_name: name + cname: util.no_dots(name) mod: p.mod info: table.Struct{ fields: fields @@ -380,6 +381,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { kind: .interface_ name: interface_name source_name: interface_name + cname: util.no_dots(interface_name) mod: p.mod info: table.Interface{ types: [] diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index a049c365ad..4192176c3d 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -6,6 +6,7 @@ module table import os import v.cflag import v.token +import v.util pub struct Table { pub mut: @@ -506,6 +507,7 @@ pub fn (mut t Table) find_or_register_chan(elem_type Type, is_mut bool) int { kind: .chan name: name source_name: source_name + cname: util.no_dots(name) info: Chan{ elem_type: elem_type is_mut: is_mut @@ -528,6 +530,7 @@ pub fn (mut t Table) find_or_register_map(key_type Type, value_type Type) int { kind: .map name: name source_name: source_name + cname: util.no_dots(name) info: Map{ key_type: key_type value_type: value_type @@ -550,6 +553,7 @@ pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int, mod str kind: .array name: name source_name: source_name + cname: util.no_dots(name) info: Array{ elem_type: elem_type nr_dims: nr_dims @@ -572,6 +576,7 @@ pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size int, nr_d kind: .array_fixed name: name source_name: source_name + cname: util.no_dots(name) info: ArrayFixed{ elem_type: elem_type size: size @@ -603,6 +608,7 @@ pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int { kind: .multi_return name: name source_name: source_name + cname: util.no_dots(name) info: MultiReturn{ types: mr_typs } @@ -618,6 +624,7 @@ pub fn (mut t Table) find_or_register_fn_type(mod string, f Fn, is_anon bool, ha kind: .function name: name source_name: source_name + cname: util.no_dots(name) mod: mod info: FnType{ is_anon: anon @@ -635,6 +642,7 @@ pub fn (mut t Table) add_placeholder_type(name string, language Language) int { ph_type := TypeSymbol{ kind: .placeholder name: name + cname: util.no_dots(name) language: language source_name: name mod: modname diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index 85b38cf874..82961c22b9 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -39,6 +39,7 @@ pub mut: kind Kind name string // the internal name of the type or underlying type, i.e. `array_fixed_int_5`. See also .source_name below. source_name string // the original source name of the type, i.e. `[5]int`. + cname string // the name with no dots for use in the generated C code methods []Fn mod string is_public bool @@ -505,95 +506,111 @@ pub fn (mut t Table) register_builtin_type_symbols() { kind: .void name: 'void' source_name: 'void' + cname: 'void' mod: 'builtin' }) t.register_type_symbol({ kind: .voidptr name: 'voidptr' source_name: 'voidptr' + cname: 'voidptr' mod: 'builtin' }) t.register_type_symbol({ kind: .byteptr name: 'byteptr' source_name: 'byteptr' + cname: 'byteptr' mod: 'builtin' }) t.register_type_symbol({ kind: .charptr name: 'charptr' source_name: 'charptr' + cname: 'charptr' mod: 'builtin' }) t.register_type_symbol({ kind: .i8 name: 'i8' source_name: 'i8' + cname: 'i8' mod: 'builtin' }) t.register_type_symbol({ kind: .i16 name: 'i16' source_name: 'i16' + cname: 'i16' mod: 'builtin' }) t.register_type_symbol({ kind: .int name: 'int' source_name: 'int' + cname: 'int' mod: 'builtin' }) t.register_type_symbol({ kind: .i64 name: 'i64' source_name: 'i64' + cname: 'i64' mod: 'builtin' }) t.register_type_symbol({ kind: .byte name: 'byte' source_name: 'byte' + cname: 'byte' mod: 'builtin' }) t.register_type_symbol({ kind: .u16 name: 'u16' source_name: 'u16' + cname: 'u16' mod: 'builtin' }) t.register_type_symbol({ kind: .u32 name: 'u32' source_name: 'u32' + cname: 'u32' mod: 'builtin' }) t.register_type_symbol({ kind: .u64 name: 'u64' source_name: 'u64' + cname: 'u64' mod: 'builtin' }) t.register_type_symbol({ kind: .f32 name: 'f32' source_name: 'f32' + cname: 'f32' mod: 'builtin' }) t.register_type_symbol({ kind: .f64 name: 'f64' source_name: 'f64' + cname: 'f64' mod: 'builtin' }) t.register_type_symbol({ kind: .char name: 'char' source_name: 'char' + cname: 'char' mod: 'builtin' }) t.register_type_symbol({ kind: .bool name: 'bool' + cname: 'bool' source_name: 'bool' mod: 'builtin' }) @@ -601,66 +618,77 @@ pub fn (mut t Table) register_builtin_type_symbols() { kind: .none_ name: 'none' source_name: 'none' + cname: 'none' mod: 'builtin' }) t.register_type_symbol({ kind: .string name: 'string' source_name: 'string' + cname: 'string' mod: 'builtin' }) t.register_type_symbol({ kind: .ustring name: 'ustring' source_name: 'ustring' + cname: 'ustring' mod: 'builtin' }) t.register_type_symbol({ kind: .array name: 'array' source_name: 'array' + cname: 'array' mod: 'builtin' }) t.register_type_symbol({ kind: .map name: 'map' source_name: 'map' + cname: 'map' mod: 'builtin' }) t.register_type_symbol({ kind: .chan name: 'chan' source_name: 'chan' + cname: 'chan' mod: 'builtin' }) t.register_type_symbol({ kind: .size_t name: 'size_t' source_name: 'size_t' + cname: 'size_t' mod: 'builtin' }) t.register_type_symbol({ kind: .rune name: 'rune' source_name: 'rune' + cname: 'rune' mod: 'builtin' }) t.register_type_symbol({ kind: .any name: 'any' source_name: 'any' + cname: 'any' mod: 'builtin' }) t.register_type_symbol({ kind: .any_float name: 'any_float' source_name: 'any_float' + cname: 'any_float' mod: 'builtin' }) t.register_type_symbol({ kind: .any_int name: 'any_int' source_name: 'any_int' + cname: 'any_int' mod: 'builtin' }) // TODO: remove. for v1 map compatibility @@ -670,6 +698,7 @@ pub fn (mut t Table) register_builtin_type_symbols() { kind: .alias name: 'map_string' source_name: 'map_string' + cname: 'map_string' mod: 'builtin' parent_idx: map_string_string_idx }) @@ -677,6 +706,7 @@ pub fn (mut t Table) register_builtin_type_symbols() { kind: .alias name: 'map_int' source_name: 'map_int' + cname: 'map_int' mod: 'builtin' parent_idx: map_string_int_idx })