all: -usecache fixes and self compilation & some type cname optimisation (#7015)

pull/6213/head
joe-conigliaro 2020-11-30 00:10:45 +11:00 committed by GitHub
parent 3afa606154
commit 91eca539d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 126 additions and 47 deletions

View File

@ -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{

View File

@ -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')
}

View File

@ -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)
}

View File

@ -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

View File

@ -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{

View File

@ -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: []

View File

@ -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

View File

@ -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
})