1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: sort const inits/cleanups topologically too

This commit is contained in:
Delyan Angelov 2020-07-08 11:20:13 +03:00
parent 97ef860acb
commit 38000f8622
6 changed files with 37 additions and 16 deletions

View File

@ -142,6 +142,7 @@ pub mut:
pub struct ConstField { pub struct ConstField {
pub: pub:
mod string
name string name string
expr Expr expr Expr
is_pub bool is_pub bool

View File

@ -12,10 +12,10 @@ import v.depgraph
pub struct Builder { pub struct Builder {
pub: pub:
table &table.Table
compiled_dir string // contains os.real_path() of the dir of the final file beeing compiled, or the dir itself when doing `v .` compiled_dir string // contains os.real_path() of the dir of the final file beeing compiled, or the dir itself when doing `v .`
module_path string module_path string
mut: mut:
table &table.Table
checker checker.Checker checker checker.Checker
pref &pref.Preferences pref &pref.Preferences
global_scope &ast.Scope global_scope &ast.Scope
@ -146,6 +146,7 @@ pub fn (mut b Builder) resolve_deps() {
} }
} }
} }
b.table.modules = mods
b.parsed_files = reordered_parsed_files b.parsed_files = reordered_parsed_files
} }

View File

@ -35,8 +35,8 @@ mut:
typedefs2 strings.Builder typedefs2 strings.Builder
type_definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file) 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) definitions strings.Builder // typedefs, defines etc (everything that goes to the top of the file)
inits strings.Builder // contents of `void _vinit(){}` inits map[string]strings.Builder // contents of `void _vinit(){}`
cleanups strings.Builder // contents of `void _vcleanup(){}` cleanups map[string]strings.Builder // contents of `void _vcleanup(){}`
gowrappers strings.Builder // all go callsite wrappers gowrappers strings.Builder // all go callsite wrappers
stringliterals strings.Builder // all string literals (they depend on tos3() beeing defined stringliterals strings.Builder // all string literals (they depend on tos3() beeing defined
auto_str_funcs strings.Builder // function bodies of all auto generated _str funcs auto_str_funcs strings.Builder // function bodies of all auto generated _str funcs
@ -119,8 +119,6 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string
stringliterals: strings.new_builder(100) stringliterals: strings.new_builder(100)
auto_str_funcs: strings.new_builder(100) auto_str_funcs: strings.new_builder(100)
comptime_defines: strings.new_builder(100) comptime_defines: strings.new_builder(100)
inits: strings.new_builder(100)
cleanups: strings.new_builder(100)
pcs_declarations: strings.new_builder(100) pcs_declarations: strings.new_builder(100)
hotcode_definitions: strings.new_builder(100) hotcode_definitions: strings.new_builder(100)
options: strings.new_builder(100) options: strings.new_builder(100)
@ -134,6 +132,10 @@ pub fn cgen(files []ast.File, table &table.Table, pref &pref.Preferences) string
indent: -1 indent: -1
module_built: pref.path.after('vlib/') module_built: pref.path.after('vlib/')
} }
for mod in g.table.modules {
g.inits[mod] = strings.new_builder(100)
g.cleanups[mod] = strings.new_builder(100)
}
g.init() g.init()
// //
mut tests_inited := false mut tests_inited := false
@ -2706,7 +2708,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
styp := g.typ(it.typ) styp := g.typ(it.typ)
g.definitions.writeln('$styp _const_$name = $val; // fixed array const') g.definitions.writeln('$styp _const_$name = $val; // fixed array const')
} else { } else {
g.const_decl_init_later(name, val, field.typ) g.const_decl_init_later(field.mod, name, val, field.typ)
} }
} }
ast.StringLiteral { ast.StringLiteral {
@ -2716,7 +2718,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
} }
} }
else { else {
g.const_decl_init_later(name, val, field.typ) g.const_decl_init_later(field.mod, name, val, field.typ)
} }
} }
} }
@ -2731,20 +2733,20 @@ fn (mut g Gen) const_decl_simple_define(name, val string) {
g.definitions.writeln(val) g.definitions.writeln(val)
} }
fn (mut g Gen) const_decl_init_later(name, val string, typ table.Type) { fn (mut g Gen) const_decl_init_later(mod, name, val string, typ table.Type) {
// Initialize more complex consts in `void _vinit(){}` // Initialize more complex consts in `void _vinit(){}`
// (C doesn't allow init expressions that can't be resolved at compile time). // (C doesn't allow init expressions that can't be resolved at compile time).
styp := g.typ(typ) styp := g.typ(typ)
// //
cname := '_const_$name' cname := '_const_$name'
g.definitions.writeln('$styp $cname; // inited later') g.definitions.writeln('$styp $cname; // inited later')
g.inits.writeln('\t$cname = $val;') g.inits[mod].writeln('\t$cname = $val;')
if g.pref.autofree { if g.pref.autofree {
if styp.starts_with('array_') { if styp.starts_with('array_') {
g.cleanups.writeln('\tarray_free(&$cname);') g.cleanups[mod].writeln('\tarray_free(&$cname);')
} }
if styp == 'string' { if styp == 'string' {
g.cleanups.writeln('\tstring_free(&$cname);') g.cleanups[mod].writeln('\tstring_free(&$cname);')
} }
} }
} }
@ -2992,8 +2994,10 @@ fn (mut g Gen) write_init_function() {
} }
g.writeln('\tbuiltin_init();') g.writeln('\tbuiltin_init();')
g.writeln('\tvinit_string_literals();') g.writeln('\tvinit_string_literals();')
g.write(g.inits.str()) //
for mod_name in g.table.imports { for mod_name in g.table.modules {
g.writeln('\t// Initializations for module $mod_name :')
g.write(g.inits[mod_name].str())
init_fn_name := '${mod_name}.init' init_fn_name := '${mod_name}.init'
if _ := g.table.find_fn(init_fn_name) { if _ := g.table.find_fn(init_fn_name) {
mod_c_name := util.no_dots(mod_name) mod_c_name := util.no_dots(mod_name)
@ -3001,6 +3005,7 @@ fn (mut g Gen) write_init_function() {
g.writeln('\t${init_fn_c_name}();') g.writeln('\t${init_fn_c_name}();')
} }
} }
//
g.writeln('}') g.writeln('}')
if g.pref.printfn_list.len > 0 && '_vinit' in g.pref.printfn_list { if g.pref.printfn_list.len > 0 && '_vinit' in g.pref.printfn_list {
println(g.out.after(fn_vinit_start_pos)) println(g.out.after(fn_vinit_start_pos))
@ -3009,7 +3014,11 @@ fn (mut g Gen) write_init_function() {
fn_vcleanup_start_pos := g.out.len fn_vcleanup_start_pos := g.out.len
g.writeln('void _vcleanup() {') g.writeln('void _vcleanup() {')
// g.writeln('puts("cleaning up...");') // g.writeln('puts("cleaning up...");')
g.writeln(g.cleanups.str()) reversed_table_modules := g.table.modules.reverse()
for mod_name in reversed_table_modules {
g.writeln('\t// Cleanups for module $mod_name :')
g.writeln(g.cleanups[mod_name].str())
}
// g.writeln('\tfree(g_str_buf);') // g.writeln('\tfree(g_str_buf);')
g.writeln('}') g.writeln('}')
if g.pref.printfn_list.len > 0 && '_vcleanup' in g.pref.printfn_list { if g.pref.printfn_list.len > 0 && '_vcleanup' in g.pref.printfn_list {

View File

@ -1376,6 +1376,7 @@ fn (mut p Parser) const_decl() ast.ConstDecl {
expr := p.expr(0) expr := p.expr(0)
field := ast.ConstField{ field := ast.ConstField{
name: full_name name: full_name
mod: p.mod
expr: expr expr: expr
pos: pos pos: pos
comments: comments comments: comments

View File

@ -13,7 +13,7 @@ pub mut:
type_idxs map[string]int type_idxs map[string]int
fns map[string]Fn fns map[string]Fn
imports []string // List of all imports imports []string // List of all imports
modules []string // List of all modules registered by the application modules []string // Topologically sorted list of all modules registered by the application
cflags []cflag.CFlag cflags []cflag.CFlag
redefined_fns []string redefined_fns []string
fn_gen_types map[string][]Type // for generic functions fn_gen_types map[string][]Type // for generic functions
@ -510,4 +510,3 @@ pub fn (table &Table) sumtype_has_variant(parent Type, variant Type) bool {
} }
return false return false
} }

View File

@ -0,0 +1,10 @@
import rand
const (
my_random_letter_const = byte(65 + rand.u32n(25))
)
fn test_rand_is_initialized_before_main(){
eprintln('random letter: $my_random_letter_const.str() | ASCII code: $my_random_letter_const')
assert my_random_letter_const.is_capital()
}