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:
parent
97ef860acb
commit
38000f8622
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
vlib/v/tests/const_init_order_test.v
Normal file
10
vlib/v/tests/const_init_order_test.v
Normal 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()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user