cgen: initialize globals with default initializer when none is given. (#10979)

pull/10981/head
Uwe Krüger 2021-07-27 19:14:30 +02:00 committed by GitHub
parent a56f579e0d
commit abd17ddb6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 2 deletions

View File

@ -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<string>(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"'
}

View File

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

View File

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