Skip to content

v.gen.c #

fn gen #

fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) (string, string, string, []int)

fn get_guarded_include_text #

fn get_guarded_include_text(iname string, imessage string) string

struct Gen #

struct Gen {
	pref                &pref.Preferences = unsafe { nil }
	field_data_type     ast.Type // cache her to avoid map lookups
	module_built        string
	timers_should_print bool
	table               &ast.Table = unsafe { nil }
mut:
	out                       strings.Builder
	cheaders                  strings.Builder
	preincludes               strings.Builder // allows includes to go before `definitions`
	includes                  strings.Builder // all C #includes required by V modules
	typedefs                  strings.Builder
	enum_typedefs             strings.Builder // enum types
	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)
	alias_definitions         strings.Builder // alias fixed array of non-builtin
	hotcode_definitions       strings.Builder // -live declarations & functions
	channel_definitions       strings.Builder // channel related code
	thread_definitions        strings.Builder // thread defines
	comptime_definitions      strings.Builder // custom defines, given by -d/-define flags on the CLI
	cleanup                   strings.Builder
	cleanups                  map[string]strings.Builder // contents of `void _vcleanup(){}`
	gowrappers                strings.Builder // all go callsite wrappers
	auto_str_funcs            strings.Builder // function bodies of all auto generated _str funcs
	dump_funcs                strings.Builder // function bodies of all auto generated _str funcs
	pcs_declarations          strings.Builder // -prof profile counter declarations for each function
	embedded_data             strings.Builder // data to embed in the executable/binary
	shared_types              strings.Builder // shared/lock types
	shared_functions          strings.Builder // shared constructors
	options                   strings.Builder // `option_xxxx` types
	out_results               strings.Builder // `result_xxxx` types
	json_forward_decls        strings.Builder // json type forward decls
	sql_buf                   strings.Builder // for writing exprs to args via `sqlite3_bind_int()` etc
	global_const_defs         map[string]GlobalConstDef
	sorted_global_const_names []string
	file                      &ast.File = unsafe { nil }
	unique_file_path_hash     u64 // a hash of file.path, used for making auxilary fn generation unique (like `compare_xyz`)
	fn_decl                   &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0
	last_fn_c_name            string
	tmp_count                 int         // counter for unique tmp vars (_tmp1, _tmp2 etc); resets at the start of each fn.
	tmp_count_af              int  // a separate tmp var counter for autofree fn calls
	tmp_count_declarations    int  // counter for unique tmp names (_d1, _d2 etc); does NOT reset, used for C declarations
	global_tmp_count          int  // like tmp_count but global and not resetted in each function
	discard_or_result         bool // do not safe last ExprStmt of `or` block in tmp variable to defer ongoing expr usage
	is_assign_lhs             bool // inside left part of assign expr (for array_set(), etc)
	is_void_expr_stmt         bool // ExprStmt whos result is discarded
	is_arraymap_set           bool // map or array set value state
	is_amp                    bool // for `&Foo{}` to merge PrefixExpr `&` and StructInit `Foo{}`; also for `&u8(0)` etc
	is_sql                    bool // Inside `sql db{}` statement, generating sql instead of C (e.g. `and` instead of `&&` etc)
	is_shared                 bool // for initialization of hidden mutex in `[rw]shared` literals
	is_vlines_enabled         bool // is it safe to generate #line directives when -g is passed
	is_autofree               bool // false, inside the bodies of fns marked with [manualfree], otherwise === g.pref.autofree
	is_builtin_mod            bool
	is_json_fn                bool // inside json.encode()
	is_js_call                bool // for handling a special type arg #1 `json.decode(User, ...)`
	is_fn_index_call          bool
	is_cc_msvc                bool   // g.pref.ccompiler == 'msvc'
	vlines_path               string // set to the proper path for generating #line directives
	optionals                 map[string]string // to avoid duplicates
	results                   map[string]string // to avoid duplicates
	done_optionals            shared []string   // to avoid duplicates
	chan_pop_optionals        map[string]string // types for `x := <-ch or {...}`
	chan_push_optionals       map[string]string // types for `ch <- x or {...}`
	mtxs                      string // array of mutexes if the `lock` has multiple variables
	labeled_loops             map[string]&ast.Stmt
	inner_loop                &ast.Stmt = unsafe { nil }
	shareds                   map[int]string // types with hidden mutex for which decl has been emitted
	inside_ternary            int  // ?: comma separated statements on a single line
	inside_map_postfix        bool // inside map++/-- postfix expr
	inside_map_infix          bool // inside map<
	inside_map_index          bool
	inside_opt_data           bool
	inside_if_optional        bool
	inside_if_result          bool
	inside_match_optional     bool
	inside_match_result       bool
	inside_vweb_tmpl          bool
	inside_return             bool
	inside_struct_init        bool
	inside_or_block           bool
	inside_call               bool
	inside_for_c_stmt         bool
	inside_comptime_for_field bool
	inside_cast_in_heap       int // inside cast to interface type in heap (resolve recursive calls)
	inside_const              bool
	inside_const_opt_or_res   bool
	inside_lambda             bool
	inside_for_in_any_cond    bool
	loop_depth                int
	ternary_names             map[string]string
	ternary_level_names       map[string][]string
	arraymap_set_pos          int   // map or array set value position
	stmt_path_pos             []int // positions of each statement start, for inserting C statements before the current statement
	skip_stmt_pos             bool  // for handling if expressions + autofree (since both prepend C statements)
	right_is_opt              bool
	indent                    int
	empty_line                bool
	assign_op                 token.Kind // *=, =, etc (for array_set)
	defer_stmts               []ast.DeferStmt
	defer_ifdef               string
	defer_profile_code        string
	defer_vars                []string
	str_types                 []StrType       // types that need automatic str() generation
	generated_str_fns         []StrType       // types that already have a str() function
	threaded_fns              shared []string // for generating unique wrapper types and fns for `go xxx()`
	waiter_fns                shared []string // functions that wait for `go xxx()` to finish
	needed_equality_fns       []ast.Type
	generated_eq_fns          []ast.Type
	array_sort_fn             shared []string
	array_contains_types      []ast.Type
	array_index_types         []ast.Type
	auto_fn_definitions       []string // auto generated functions defination list
	sumtype_casting_fns       []SumtypeCastingFn
	anon_fn_definitions       []string     // anon generated functions defination list
	sumtype_definitions       map[int]bool // `_TypeA_to_sumtype_TypeB()` fns that have been generated
	json_types                []ast.Type   // to avoid json gen duplicates
	pcs                       []ProfileCounterMeta // -prof profile counter fn_names => fn counter name
	hotcode_fn_names          []string
	embedded_files            []ast.EmbeddedFile
	sql_i                     int
	sql_stmt_name             string
	sql_bind_name             string
	sql_idents                []string
	sql_idents_types          []ast.Type
	sql_left_type             ast.Type
	sql_table_name            string
	sql_fkey                  string
	sql_parent_id             string
	sql_side                  SqlExprSide // left or right, to distinguish idents in `name == name`
	strs_to_free0             []string    // strings.Builder
// strs_to_free          []string // strings.Builder
// tmp_arg_vars_to_free  []string
// autofree_pregen       map[string]string
// autofree_pregen_buf   strings.Builder
// autofree_tmp_vars     []string // to avoid redefining the same tmp vars in a single function
// nr_vars_to_free       int
// doing_autofree_tmp    bool
	comptime_for_method              string // $for method in T.methods {}
	comptime_for_field_var           string // $for field in T.fields {}; the variable name
	comptime_for_field_value         ast.StructField // value of the field variable
	comptime_for_field_type          ast.Type        // type of the field variable inferred from `$if field.typ is T {}`
	comptime_var_type_map            map[string]ast.Type
	prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type
// used in match multi branch
// TypeOne, TypeTwo {}
// where an aggregate (at least two types) is generated
// sum type deref needs to know which index to deref because unions take care of the correct field
	aggregate_type_idx  int
	branch_parent_pos   int    // used in BranchStmt (continue/break) for autofree stop position
	returned_var_name   string // to detect that a var doesn't need to be freed since it's being returned
	infix_left_var_name string // a && if expr
	called_fn_name      string
	timers              &util.Timers = util.get_timers()
	force_main_console  bool // true when [console] used on fn main()
	as_cast_type_names  map[string]string // table for type name lookup in runtime (for __as_cast)
	obf_table           map[string]string
	referenced_fns      shared map[string]bool // functions that have been referenced
	nr_closures         int
	expected_cast_type  ast.Type // for match expr of sumtypes
	or_expr_return_type ast.Type // or { 0, 1 } return type
	anon_fn             bool
	tests_inited        bool
	has_main            bool
// main_fn_decl_node  ast.FnDecl
	cur_mod                ast.Module
	cur_concrete_types     []ast.Type  // do not use table.cur_concrete_types because table is global, so should not be accessed by different threads
	cur_fn                 &ast.FnDecl = unsafe { nil } // same here
	cur_lock               ast.LockExpr
	autofree_methods       map[int]bool
	generated_free_methods map[int]bool
	autofree_scope_stmts   []string
	use_segfault_handler   bool = true
	test_function_names    []string
/////////
// out_parallel []strings.Builder
// out_idx      int
	out_fn_start_pos []int  // for generating multiple .c files, stores locations of all fn positions in `out` string builder
	static_modifier  string // for parallel_cc
}

fn (Gen) contains_ptr #

fn (mut g Gen) contains_ptr(el_typ ast.Type) bool

returns true if t includes any pointer(s) - during garbage collection heap regions that contain no pointers do not have to be scanned

fn (Gen) current_tmp_var #

fn (mut g Gen) current_tmp_var() string

fn (Gen) filter_only_matching_fn_names #

fn (mut g Gen) filter_only_matching_fn_names(fnames []string) []string

fn (Gen) finish #

fn (mut g Gen) finish()

fn (Gen) free_builders #

unsafe
fn (mut g Gen) free_builders()

free_builders should be called only when a Gen would NOT be used anymore it frees the bulk of the memory that is private to the Gen instance (the various string builders)

fn (Gen) gen_c_android_sokol_main #

fn (mut g Gen) gen_c_android_sokol_main()

fn (Gen) gen_c_main #

fn (mut g Gen) gen_c_main()

fn (Gen) gen_c_main_for_tests #

fn (mut g Gen) gen_c_main_for_tests()

fn (Gen) gen_c_main_profile_hook #

fn (mut g Gen) gen_c_main_profile_hook()

fn (Gen) gen_failing_error_propagation_for_test_fn #

fn (mut g Gen) gen_failing_error_propagation_for_test_fn(or_block ast.OrExpr, cvar_name string)

fn (Gen) gen_failing_return_error_for_test_fn #

fn (mut g Gen) gen_failing_return_error_for_test_fn(return_stmt ast.Return, cvar_name string)

fn (Gen) gen_file #

fn (mut g Gen) gen_file()

fn (Gen) gen_vprint_profile_stats #

fn (mut g Gen) gen_vprint_profile_stats()

fn (Gen) get_array_depth #

fn (mut g Gen) get_array_depth(el_typ ast.Type) int

fn (Gen) hashes #

fn (g &Gen) hashes() string

fn (Gen) init #

fn (mut g Gen) init()

fn (Gen) new_global_tmp_var #

fn (mut g Gen) new_global_tmp_var() string

fn (Gen) new_tmp_declaration_name #

fn (mut g Gen) new_tmp_declaration_name() string

fn (Gen) new_tmp_var #

fn (mut g Gen) new_tmp_var() string

fn (Gen) reset_tmp_count #

fn (mut g Gen) reset_tmp_count()

fn (Gen) write_alias_typesymbol_declaration #

fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol)

fn (Gen) write_fn_typesymbol_declaration #

fn (mut g Gen) write_fn_typesymbol_declaration(sym ast.TypeSymbol)

fn (Gen) write_interface_typedef #

fn (mut g Gen) write_interface_typedef(sym ast.TypeSymbol)

fn (Gen) write_interface_typesymbol_declaration #

fn (mut g Gen) write_interface_typesymbol_declaration(sym ast.TypeSymbol)

fn (Gen) write_multi_return_types #

fn (mut g Gen) write_multi_return_types()

fn (Gen) write_tests_definitions #

fn (mut g Gen) write_tests_definitions()

fn (Gen) write_typedef_types #

fn (mut g Gen) write_typedef_types()

fn (Gen) write_typeof_functions #

fn (mut g Gen) write_typeof_functions()

struct ProfileCounterMeta #

struct ProfileCounterMeta {
	fn_name   string
	vpc_name  string
	vpc_calls string
}