diff --git a/cmd/tools/modules/testing/common.v b/cmd/tools/modules/testing/common.v index 2c4bfb2db1..ebc61d6b03 100644 --- a/cmd/tools/modules/testing/common.v +++ b/cmd/tools/modules/testing/common.v @@ -266,6 +266,10 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { tls_bench.no_cstep = true dot_relative_file := p.get_item(idx) mut relative_file := dot_relative_file.replace('./', '') + mut cmd_options := [ts.vargs] + if relative_file.contains('global') && !ts.vargs.contains('fmt') { + cmd_options << ' -enable-globals' + } if ts.root_relative { relative_file = relative_file.replace(ts.vroot + os.path_separator, '') } @@ -285,7 +289,6 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr { os.rm(generated_binary_fpath) or { panic(err) } } } - mut cmd_options := [ts.vargs] if !ts.vargs.contains('fmt') { cmd_options << ' -o "$generated_binary_fpath"' } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index e093d7cfa7..eeba8e8adb 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -49,6 +49,7 @@ mut: typedefs2 strings.Builder type_definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) + global_initializations strings.Builder // default initializers for globals (goes in _vinit()) inits map[string]strings.Builder // contents of `void _vinit/2{}` cleanups map[string]strings.Builder // contents of `void _vcleanup(){}` gowrappers strings.Builder // all go callsite wrappers @@ -205,6 +206,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string { typedefs2: strings.new_builder(100) type_definitions: strings.new_builder(100) definitions: strings.new_builder(100) + global_initializations: strings.new_builder(100) gowrappers: strings.new_builder(100) stringliterals: strings.new_builder(100) auto_str_funcs: strings.new_builder(100) @@ -5115,7 +5117,15 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) { if field.has_expr { g.definitions.writeln('$mod$styp $field.name = $field.expr; // global') } else { - g.definitions.writeln('$mod$styp $field.name; // global') + default_initializer := g.type_default(field.typ) + if default_initializer == '{0}' { + g.definitions.writeln('$mod$styp $field.name = {0}; // global') + } else { + g.definitions.writeln('$mod$styp $field.name; // global') + if field.name !in ['as_cast_type_indexes', 'g_memory_block'] { + g.global_initializations.writeln('\t$field.name = *($styp*)&(($styp[]){${g.type_default(field.typ)}}[0]); // global') + } + } } } } @@ -5442,6 +5452,9 @@ fn (mut g Gen) write_init_function() { g.writeln('\tbuiltin_init();') g.writeln('\tvinit_string_literals();') // + g.writeln('\t// Initializations for global variables with default initializers') + g.write(g.global_initializations.str()) + // for mod_name in g.table.modules { g.writeln('\t// Initializations for module $mod_name :') g.write(g.inits[mod_name].str()) diff --git a/vlib/v/tests/init_global_test.v b/vlib/v/tests/init_global_test.v new file mode 100644 index 0000000000..afa41395db --- /dev/null +++ b/vlib/v/tests/init_global_test.v @@ -0,0 +1,33 @@ +fn one() int { + return 1 +} + +fn pushf64() { + ch <- 12.5 +} + +fn test_global_init() { + intmap['two'] = 27 + key := 'two' + assert intmap[key] == 27 + t := go pushf64() + numberfns['one'] = one + numberfns['two'] = fn () int { + return 2 + } + f := numberfns['one'] + n := f() + assert n == 1 + m := numberfns['two']() + assert m == 2 + got := <-ch + assert got == 12.5 + t.wait() + assert true +} + +__global ( + intmap map[string]int + numberfns map[string]fn () int + ch chan f64 +)