This commit is contained in:
Alexander Medvednikov 2024-11-27 15:54:38 +03:00 committed by Alexander Medvednikov
parent c4d8687f74
commit f41017313c
11 changed files with 175 additions and 125 deletions

View file

@ -20,8 +20,6 @@ $if windows {
// call Windows API to get screen size
fn C.GetSystemMetrics(int) int
// fn C.WaitMessage()
pub type TouchPoint = C.sapp_touchpoint
pub struct Event {

View file

@ -7,15 +7,22 @@ import v.builder
import sync.pool
fn parallel_cc(mut b builder.Builder, header string, _res string, out_str string, out_fn_start_pos []int) {
c_files := util.nr_jobs
c_files := util.nr_jobs - 1
println('> c_files: ${c_files} | util.nr_jobs: ${util.nr_jobs}')
out_h := header.replace_once('static char * v_typeof_interface_IError', 'char * v_typeof_interface_IError')
os.write_file('out.h', out_h) or { panic(err) }
os.write_file('out_str.txt', out_str) or { panic(err) }
os.write_file('out_res.txt', _res) or { panic(err) }
// Write generated stuff in `g.out` before and after the `out_fn_start_pos` locations,
// like the `int main()` to "out_0.c" and "out_x.c"
out0 := out_str[..out_fn_start_pos[0]].replace_once('static char * v_typeof_interface_IError',
'char * v_typeof_interface_IError')
os.write_file('out_0.c', '#include "out.h"\n' + out0) or { panic(err) }
x := _res.find_between('// ZULUL1', '// ZULUL2')
os.write_file('out_x.txt', x) or { panic(err) }
out0 := '//out0\n' +
out_str[..out_fn_start_pos[0]].replace_once('static char * v_typeof_interface_IError', 'char * v_typeof_interface_IError')
// out_str[..out0_start].replace_once('static char * v_typeof_interface_IError', 'char * v_typeof_interface_IError')
// os.write_file('out.h', out_h + '\n//out0:\n' + out0) or { panic(err) }
os.write_file('out.h', out_h) or { panic(err) }
os.write_file('out_0.c', '#include "out.h"\n' + out0 + '\n//X:\n' + x) or { panic(err) }
// os.write_file('out_0.c', out0) or { panic(err) }
os.write_file('out_x.c', '#include "out.h"\n' + out_str[out_fn_start_pos.last()..]) or {
panic(err)
}
@ -41,7 +48,7 @@ fn parallel_cc(mut b builder.Builder, header string, _res string, out_str string
continue
}
fn_text := out_str[prev_fn_pos..fn_pos]
out_files[i % c_files].writeln(fn_text + '\n//////////////////////////////////////\n\n') or {
out_files[i % c_files].writeln(fn_text + '\n///////////////////////////\n\n') or {
panic(err)
}
prev_fn_pos = fn_pos
@ -56,11 +63,12 @@ fn parallel_cc(mut b builder.Builder, header string, _res string, out_str string
o_postfixes << (i + 1).str()
}
mut pp := pool.new_pool_processor(callback: build_parallel_o_cb)
nthreads := c_files + 2
pp.set_max_jobs(nthreads)
nr_threads := c_files + 2
pp.set_max_jobs(nr_threads)
pp.work_on_items(o_postfixes)
eprintln('> C compilation on ${nthreads} threads, working on ${o_postfixes.len} files took: ${sw.elapsed().milliseconds()} ms')
link_cmd := '${os.quoted_path(cc_compiler)} -o ${os.quoted_path(b.pref.out_name)} out_0.o ${fnames.map(it.replace('.c',
eprintln('> C compilation on ${nr_threads} threads, working on ${o_postfixes.len} files took: ${sw.elapsed().milliseconds()} ms')
// cc := os.quoted_path(cc_compiler)
link_cmd := '${cc} -o ${os.quoted_path(b.pref.out_name)} out_0.o ${fnames.map(it.replace('.c',
'.o')).join(' ')} out_x.o -lpthread ${cc_ldflags}'
sw_link := time.new_stopwatch()
link_res := os.execute(link_cmd)
@ -70,9 +78,10 @@ fn parallel_cc(mut b builder.Builder, header string, _res string, out_str string
fn build_parallel_o_cb(mut p pool.PoolProcessor, idx int, _wid int) voidptr {
postfix := p.get_item[string](idx)
sw := time.new_stopwatch()
cmd := '${os.quoted_path(cc_compiler)} ${cc_cflags} -c -w -o out_${postfix}.o out_${postfix}.c'
// cc := os.quoted_path(cc_compiler)
cmd := '${cc} ${cc_cflags} -O3 -c -w -o out_${postfix}.o out_${postfix}.c'
res := os.execute(cmd)
eprint_time('c cmd', cmd, res, sw)
eprint_time('c cmd2', cmd, res, sw)
return unsafe { nil }
}
@ -83,6 +92,8 @@ fn eprint_time(label string, cmd string, res os.Result, sw time.StopWatch) {
}
}
// const cc = '/Users/work5/code/v/thirdparty/tcc/tcc.exe'
const cc = os.quoted_path(cc_compiler)
const cc_compiler = os.getenv_opt('CC') or { 'cc' }
const cc_ldflags = os.getenv_opt('LDFLAGS') or { '' }

View file

@ -1096,8 +1096,8 @@ fn (mut g Gen) gen_array_contains_methods() {
left_type_str = 'Array_voidptr'
elem_type_str = 'voidptr'
}
g.type_definitions.writeln('static bool ${fn_name}(${left_type_str} a, ${elem_type_str} v); // auto')
fn_builder.writeln('static bool ${fn_name}(${left_type_str} a, ${elem_type_str} v) {')
g.type_definitions.writeln('bool ${fn_name}(${left_type_str} a, ${elem_type_str} v); // auto')
fn_builder.writeln('bool ${fn_name}(${left_type_str} a, ${elem_type_str} v) {')
fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i) {')
if elem_kind == .string {
fn_builder.writeln('\t\tif (fast_string_eq(((string*)a.data)[i], v)) {')
@ -1138,8 +1138,8 @@ fn (mut g Gen) gen_array_contains_methods() {
if elem_kind == .function {
elem_type_str = 'voidptr'
}
g.type_definitions.writeln('static bool ${fn_name}(${left_type_str} a, ${elem_type_str} v); // auto')
fn_builder.writeln('static bool ${fn_name}(${left_type_str} a, ${elem_type_str} v) {')
g.type_definitions.writeln('/*KU*/bool ${fn_name}(${left_type_str} a, ${elem_type_str} v); // auto')
fn_builder.writeln('bool ${fn_name}(${left_type_str} a, ${elem_type_str} v) {')
fn_builder.writeln('\tfor (int i = 0; i < ${size}; ++i) {')
if elem_kind == .string {
fn_builder.writeln('\t\tif (fast_string_eq(a[i], v)) {')
@ -1244,8 +1244,8 @@ fn (mut g Gen) gen_array_index_methods() {
left_type_str = 'Array_voidptr'
elem_type_str = 'voidptr'
}
g.type_definitions.writeln('static int ${fn_name}(${left_type_str} a, ${elem_type_str} v); // auto')
fn_builder.writeln('static int ${fn_name}(${left_type_str} a, ${elem_type_str} v) {')
g.type_definitions.writeln('int ${fn_name}(${left_type_str} a, ${elem_type_str} v); // auto')
fn_builder.writeln('int ${fn_name}(${left_type_str} a, ${elem_type_str} v) {')
fn_builder.writeln('\t${elem_type_str}* pelem = a.data;')
fn_builder.writeln('\tfor (int i = 0; i < a.len; ++i, ++pelem) {')
if elem_sym.kind == .string {
@ -1288,8 +1288,8 @@ fn (mut g Gen) gen_array_index_methods() {
if elem_sym.kind == .function {
elem_type_str = 'voidptr'
}
g.type_definitions.writeln('static int ${fn_name}(${left_type_str} a, ${elem_type_str} v); // auto')
fn_builder.writeln('static int ${fn_name}(${left_type_str} a, ${elem_type_str} v) {')
g.type_definitions.writeln('int ${fn_name}(${left_type_str} a, ${elem_type_str} v); // auto')
fn_builder.writeln('int ${fn_name}(${left_type_str} a, ${elem_type_str} v) {')
fn_builder.writeln('\tfor (int i = 0; i < ${info.size}; ++i) {')
if elem_sym.kind == .string {
fn_builder.writeln('\t\tif (fast_string_eq(a[i], v)) {')

View file

@ -60,13 +60,13 @@ fn (mut g Gen) gen_sumtype_equality_fn(left_type ast.Type) string {
g.generated_eq_fns << left_no_ptr
info := left.sym.sumtype_info()
g.definitions.writeln('static bool ${ptr_styp}_sumtype_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
g.definitions.writeln('bool ${ptr_styp}_sumtype_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
left_typ := g.read_field(left_type, '_typ', 'a')
right_typ := g.read_field(left_type, '_typ', 'b')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static inline bool ${ptr_styp}_sumtype_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('inline bool ${ptr_styp}_sumtype_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('\tif (${left_typ} != ${right_typ}) { return false; }')
fn_builder.writeln('\tif (${left_typ} == ${right_typ} && ${right_typ} == 0) { return true; } // uninitialized')
for typ in info.variants {
@ -184,13 +184,13 @@ fn (mut g Gen) gen_struct_equality_fn(left_type ast.Type) string {
g.generated_eq_fns << left_no_ptr
info := left.sym.struct_info()
g.definitions.writeln('static bool ${fn_name}_struct_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
g.definitions.writeln('bool ${fn_name}_struct_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
mut fn_builder := strings.new_builder(512)
defer {
g.auto_fn_definitions << fn_builder.str()
}
fn_builder.writeln('static inline bool ${fn_name}_struct_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('inline bool ${fn_name}_struct_eq(${ptr_styp} a, ${ptr_styp} b) {')
// overloaded
if left.sym.has_method('==') {
@ -287,10 +287,10 @@ fn (mut g Gen) gen_alias_equality_fn(left_type ast.Type) string {
g.generated_eq_fns << left_no_ptr
info := left.sym.info as ast.Alias
g.definitions.writeln('static bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
g.definitions.writeln('bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static inline bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('inline bool ${ptr_styp}_alias_eq(${ptr_styp} a, ${ptr_styp} b) {')
is_option := left.typ.has_flag(.option)
@ -348,10 +348,10 @@ fn (mut g Gen) gen_array_equality_fn(left_type ast.Type) string {
elem := g.unwrap(left.sym.array_info().elem_type)
ptr_elem_styp := g.styp(elem.typ)
g.definitions.writeln('static bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
g.definitions.writeln('bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('inline bool ${ptr_styp}_arr_eq(${ptr_styp} a, ${ptr_styp} b) {')
left_len := g.read_field(left_type, 'len', 'a')
right_len := g.read_field(left_type, 'len', 'b')
@ -430,13 +430,13 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left_type ast.Type) string {
if elem_info.is_fn_ret {
arg_styp = ptr_styp[3..] // removes the _v_ prefix for returning fixed array
}
g.definitions.writeln('static bool ${ptr_styp}_arr_eq(${arg_styp} a, ${arg_styp} b); // auto')
g.definitions.writeln('bool ${ptr_styp}_arr_eq(${arg_styp} a, ${arg_styp} b); // auto')
left := if left_type.has_flag(.option) { 'a.data' } else { 'a' }
right := if left_type.has_flag(.option) { 'b.data' } else { 'b' }
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static inline bool ${ptr_styp}_arr_eq(${arg_styp} a, ${arg_styp} b) {')
fn_builder.writeln('inline bool ${ptr_styp}_arr_eq(${arg_styp} a, ${arg_styp} b) {')
fn_builder.writeln('\tfor (int i = 0; i < ${size}; ++i) {')
// compare every pair of elements of the two fixed arrays
if elem.sym.kind == .string {
@ -488,7 +488,7 @@ fn (mut g Gen) gen_map_equality_fn(left_type ast.Type) string {
value := g.unwrap(left.sym.map_info().value_type)
ptr_value_styp := g.styp(value.typ)
g.definitions.writeln('static bool ${ptr_styp}_map_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
g.definitions.writeln('bool ${ptr_styp}_map_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
left_len := g.read_map_field_from_option(left.typ, 'len', 'a')
right_len := g.read_map_field_from_option(left.typ, 'len', 'b')
@ -498,7 +498,7 @@ fn (mut g Gen) gen_map_equality_fn(left_type ast.Type) string {
b := if left.typ.has_flag(.option) { g.read_map_from_option(left.typ, 'b') } else { '&b' }
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static inline bool ${ptr_styp}_map_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('inline bool ${ptr_styp}_map_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('\tif (${left_len} != ${right_len}) {')
fn_builder.writeln('\t\treturn false;')
fn_builder.writeln('\t}')
@ -580,7 +580,7 @@ fn (mut g Gen) gen_interface_equality_fn(left_type ast.Type) string {
g.generated_eq_fns << left_no_ptr
info := left.sym.info
g.definitions.writeln('static bool ${ptr_styp}_interface_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
g.definitions.writeln('bool ${ptr_styp}_interface_eq(${ptr_styp} a, ${ptr_styp} b); // auto')
mut fn_builder := strings.new_builder(512)
defer {
@ -590,8 +590,8 @@ fn (mut g Gen) gen_interface_equality_fn(left_type ast.Type) string {
left_arg := g.read_field(left_type, '_typ', 'a')
right_arg := g.read_field(left_type, '_typ', 'b')
fn_builder.writeln('static int v_typeof_interface_idx_${idx_fn}(int sidx); // for auto eq method')
fn_builder.writeln('static inline bool ${fn_name}_interface_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('int v_typeof_interface_idx_${idx_fn}(int sidx); // for auto eq method')
fn_builder.writeln('inline bool ${fn_name}_interface_eq(${ptr_styp} a, ${ptr_styp} b) {')
fn_builder.writeln('\tif (${left_arg} == ${right_arg}) {')
fn_builder.writeln('\t\tint idx = v_typeof_interface_idx_${idx_fn}(${left_arg});')
if info is ast.Interface {

View file

@ -84,12 +84,12 @@ fn (mut g Gen) gen_free_method(typ ast.Type) string {
}
fn (mut g Gen) gen_free_for_interface(sym ast.TypeSymbol, info ast.Interface, styp string, fn_name string) {
g.definitions.writeln('${g.static_modifier} void ${fn_name}(${styp}* it); // auto')
g.definitions.writeln('void ${fn_name}(${styp}* it); // auto')
mut fn_builder := strings.new_builder(128)
defer {
g.auto_fn_definitions << fn_builder.str()
}
fn_builder.writeln('${g.static_modifier} void ${fn_name}(${styp}* it) {')
fn_builder.writeln('void ${fn_name}(${styp}* it) {')
for t in info.types {
typ_ := g.unwrap_generic(t)
sub_sym := g.table.sym(typ_)
@ -106,12 +106,12 @@ fn (mut g Gen) gen_free_for_interface(sym ast.TypeSymbol, info ast.Interface, st
}
fn (mut g Gen) gen_free_for_struct(typ ast.Type, info ast.Struct, styp string, fn_name string) {
g.definitions.writeln('${g.static_modifier} void ${fn_name}(${styp}* it); // auto')
g.definitions.writeln('void ${fn_name}(${styp}* it); // auto')
mut fn_builder := strings.new_builder(128)
defer {
g.auto_fn_definitions << fn_builder.str()
}
fn_builder.writeln('${g.static_modifier} void ${fn_name}(${styp}* it) {')
fn_builder.writeln('void ${fn_name}(${styp}* it) {')
for field in info.fields {
field_name := c_name(field.name)
sym := g.table.sym(g.unwrap_generic(field.typ))
@ -176,12 +176,12 @@ fn (mut g Gen) gen_type_name_for_free_call(typ ast.Type) string {
}
fn (mut g Gen) gen_free_for_array(info ast.Array, styp string, fn_name string) {
g.definitions.writeln('${g.static_modifier} void ${fn_name}(${styp}* it); // auto')
g.definitions.writeln('void ${fn_name}(${styp}* it); // auto')
mut fn_builder := strings.new_builder(128)
defer {
g.auto_fn_definitions << fn_builder.str()
}
fn_builder.writeln('${g.static_modifier} void ${fn_name}(${styp}* it) {')
fn_builder.writeln('void ${fn_name}(${styp}* it) {')
sym := g.table.sym(g.unwrap_generic(info.elem_type))
if sym.kind in [.string, .array, .map, .struct] {
@ -201,12 +201,12 @@ fn (mut g Gen) gen_free_for_array(info ast.Array, styp string, fn_name string) {
}
fn (mut g Gen) gen_free_for_map(typ ast.Type, styp string, fn_name string) {
g.definitions.writeln('${g.static_modifier} void ${fn_name}(${styp}* it); // auto')
g.definitions.writeln('void ${fn_name}(${styp}* it); // auto')
mut fn_builder := strings.new_builder(128)
defer {
g.auto_fn_definitions << fn_builder.str()
}
fn_builder.writeln('${g.static_modifier} void ${fn_name}(${styp}* it) {')
fn_builder.writeln('void ${fn_name}(${styp}* it) {')
if typ.has_flag(.option) {
fn_builder.writeln('\tif (it->state != 2) {')

View file

@ -279,10 +279,10 @@ fn (mut g Gen) gen_str_for_alias(info ast.Alias, styp string, str_fn_name string
is_c_struct := parent_sym.is_c_struct() && str_method_expects_ptr
arg_def := if is_c_struct { '${styp}* it' } else { '${styp} it' }
g.definitions.writeln('static string ${str_fn_name}(${arg_def}); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${arg_def}) { return indent_${str_fn_name}(it, 0); }')
g.definitions.writeln('static string indent_${str_fn_name}(${arg_def}, int indent_count); // auto')
g.auto_str_funcs.writeln('static string indent_${str_fn_name}(${arg_def}, int indent_count) {')
g.definitions.writeln('string ${str_fn_name}(${arg_def}); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${arg_def}) { return indent_${str_fn_name}(it, 0); }')
g.definitions.writeln('string indent_${str_fn_name}(${arg_def}, int indent_count); // auto')
g.auto_str_funcs.writeln('string indent_${str_fn_name}(${arg_def}, int indent_count) {')
g.auto_str_funcs.writeln('\tstring indents = string_repeat(_SLIT(" "), indent_count);')
if str_method_expects_ptr {
it_arg := if is_c_struct { 'it' } else { '&it' }
@ -306,9 +306,9 @@ fn (mut g Gen) gen_str_for_multi_return(info ast.MultiReturn, styp string, str_f
$if trace_autostr ? {
eprintln('> gen_str_for_multi_return: ${info.types} | ${styp} | ${str_fn_name}')
}
g.definitions.writeln('static string ${str_fn_name}(${styp} a); // auto')
g.definitions.writeln('string ${str_fn_name}(${styp} a); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static string ${str_fn_name}(${styp} a) {')
fn_builder.writeln('string ${str_fn_name}(${styp} a) {')
fn_builder.writeln('\tstrings__Builder sb = strings__new_builder(${info.types.len} * 10);')
fn_builder.writeln('\tstrings__Builder_write_string(&sb, _SLIT("("));')
for i, typ in info.types {
@ -354,8 +354,8 @@ fn (mut g Gen) gen_str_for_enum(info ast.Enum, styp string, str_fn_name string)
eprintln('> gen_str_for_enum: ${info} | ${styp} | ${str_fn_name}')
}
s := util.no_dots(styp)
g.definitions.writeln('static string ${str_fn_name}(${styp} it); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${styp} it) { /* gen_str_for_enum */')
g.definitions.writeln('string ${str_fn_name}(${styp} it); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${styp} it) { /* gen_str_for_enum */')
// Enums tagged with `@[flag]` are special in that they can be a combination of enum values
if info.is_flag {
clean_name := util.strip_main_name(styp.replace('__', '.'))
@ -391,12 +391,12 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, typ_str st
eprintln('> gen_str_for_interface: ${info.types} | ${styp} | ${str_fn_name}')
}
// _str() functions should have a single argument, the indenting ones take 2:
g.definitions.writeln('static string ${str_fn_name}(${styp} x); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${styp} x) { return indent_${str_fn_name}(x, 0); }')
g.definitions.writeln('static string indent_${str_fn_name}(${styp} x, int indent_count); // auto')
g.definitions.writeln('string ${str_fn_name}(${styp} x); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${styp} x) { return indent_${str_fn_name}(x, 0); }')
g.definitions.writeln('string indent_${str_fn_name}(${styp} x, int indent_count); // auto')
mut fn_builder := strings.new_builder(512)
clean_interface_v_type_name := util.strip_main_name(typ_str)
fn_builder.writeln('static string indent_${str_fn_name}(${styp} x, int indent_count) { /* gen_str_for_interface */')
fn_builder.writeln('string indent_${str_fn_name}(${styp} x, int indent_count) { /* gen_str_for_interface */')
for typ in info.types {
sub_sym := g.table.sym(ast.mktyp(typ))
mut func_name := g.get_str_fn(typ)
@ -448,11 +448,11 @@ fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, typ_str
eprintln('> gen_str_for_union_sum_type: ${info.variants} | ${styp} | ${str_fn_name}')
}
// _str() functions should have a single argument, the indenting ones take 2:
g.definitions.writeln('static string ${str_fn_name}(${styp} x); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${styp} x) { return indent_${str_fn_name}(x, 0); }')
g.definitions.writeln('static string indent_${str_fn_name}(${styp} x, int indent_count); // auto')
g.definitions.writeln('string ${str_fn_name}(${styp} x); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${styp} x) { return indent_${str_fn_name}(x, 0); }')
g.definitions.writeln('string indent_${str_fn_name}(${styp} x, int indent_count); // auto')
mut fn_builder := strings.new_builder(512)
fn_builder.writeln('static string indent_${str_fn_name}(${styp} x, int indent_count) {')
fn_builder.writeln('string indent_${str_fn_name}(${styp} x, int indent_count) {')
mut clean_sum_type_v_type_name := ''
if info.is_anon {
variant_names := info.variants.map(util.strip_main_name(g.table.sym(it).name))
@ -549,8 +549,8 @@ fn (mut g Gen) gen_str_for_fn_type(info ast.FnType, styp string, str_fn_name str
$if trace_autostr ? {
eprintln('> gen_str_for_fn_type: ${info.func.name} | ${styp} | ${str_fn_name}')
}
g.definitions.writeln('static string ${str_fn_name}(); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}() { return _SLIT("${g.fn_decl_str(info)}");}')
g.definitions.writeln('string ${str_fn_name}(); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}() { return _SLIT("${g.fn_decl_str(info)}");}')
}
fn (mut g Gen) gen_str_for_chan(info ast.Chan, styp string, str_fn_name string) {
@ -558,8 +558,8 @@ fn (mut g Gen) gen_str_for_chan(info ast.Chan, styp string, str_fn_name string)
eprintln('> gen_str_for_chan: ${info.elem_type.debug()} | ${styp} | ${str_fn_name}')
}
elem_type_name := util.strip_main_name(g.table.get_type_name(g.unwrap_generic(info.elem_type)))
g.definitions.writeln('static string ${str_fn_name}(${styp} x); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${styp} x) { return sync__Channel_auto_str(x, _SLIT("${elem_type_name}")); }')
g.definitions.writeln('string ${str_fn_name}(${styp} x); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${styp} x) { return sync__Channel_auto_str(x, _SLIT("${elem_type_name}")); }')
}
fn (mut g Gen) gen_str_for_thread(info ast.Thread, styp string, str_fn_name string) {
@ -567,8 +567,8 @@ fn (mut g Gen) gen_str_for_thread(info ast.Thread, styp string, str_fn_name stri
eprintln('> gen_str_for_thread: ${info.return_type.debug()} | ${styp} | ${str_fn_name}')
}
ret_type_name := util.strip_main_name(g.table.get_type_name(info.return_type))
g.definitions.writeln('static string ${str_fn_name}(${styp} _); // auto}')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${styp} _) { return _SLIT("thread(${ret_type_name})");}')
g.definitions.writeln('string ${str_fn_name}(${styp} _); // auto}')
g.auto_str_funcs.writeln('string ${str_fn_name}(${styp} _) { return _SLIT("thread(${ret_type_name})");}')
}
@[inline]
@ -607,10 +607,10 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
elem_str_fn_name := g.get_str_fn(typ)
g.definitions.writeln('static string ${str_fn_name}(${styp} a); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${styp} a) { return indent_${str_fn_name}(a, 0);}')
g.definitions.writeln('static string indent_${str_fn_name}(${styp} a, int indent_count); // auto')
g.auto_str_funcs.writeln('static string indent_${str_fn_name}(${styp} a, int indent_count) {')
g.definitions.writeln('string ${str_fn_name}(${styp} a); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${styp} a) { return indent_${str_fn_name}(a, 0);}')
g.definitions.writeln('string indent_${str_fn_name}(${styp} a, int indent_count); // auto')
g.auto_str_funcs.writeln('string indent_${str_fn_name}(${styp} a, int indent_count) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(a.len * 10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _SLIT("["));')
g.auto_str_funcs.writeln('\tfor (int i = 0; i < a.len; ++i) {')
@ -714,10 +714,10 @@ fn (mut g Gen) gen_str_for_array_fixed(info ast.ArrayFixed, styp string, str_fn_
elem_str_fn_name := g.get_str_fn(typ)
def_arg := if info.is_fn_ret { '${g.styp(typ)} a[${info.size}]' } else { '${styp} a' }
g.definitions.writeln('static string ${str_fn_name}(); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${def_arg}) { return indent_${str_fn_name}(a, 0);}')
g.definitions.writeln('static string indent_${str_fn_name}(${def_arg}, int indent_count); // auto')
g.auto_str_funcs.writeln('static string indent_${str_fn_name}(${def_arg}, int indent_count) {')
g.definitions.writeln('string ${str_fn_name}(); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${def_arg}) { return indent_${str_fn_name}(a, 0);}')
g.definitions.writeln('string indent_${str_fn_name}(${def_arg}, int indent_count); // auto')
g.auto_str_funcs.writeln('string indent_${str_fn_name}(${def_arg}, int indent_count) {')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(${info.size} * 10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _SLIT("["));')
g.auto_str_funcs.writeln('\tfor (int i = 0; i < ${info.size}; ++i) {')
@ -810,10 +810,10 @@ fn (mut g Gen) gen_str_for_map(info ast.Map, styp string, str_fn_name string) {
g.get_str_fn(val_typ)
}
g.definitions.writeln('static string ${str_fn_name}(${styp} m); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${styp} m) { return indent_${str_fn_name}(m, 0);}')
g.definitions.writeln('static string indent_${str_fn_name}(${styp} m, int indent_count); // auto')
g.auto_str_funcs.writeln('static string indent_${str_fn_name}(${styp} m, int indent_count) { /* gen_str_for_map */')
g.definitions.writeln('string ${str_fn_name}(${styp} m); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${styp} m) { return indent_${str_fn_name}(m, 0);}')
g.definitions.writeln('string indent_${str_fn_name}(${styp} m, int indent_count); // auto')
g.auto_str_funcs.writeln('string indent_${str_fn_name}(${styp} m, int indent_count) { /* gen_str_for_map */')
g.auto_str_funcs.writeln('\tstrings__Builder sb = strings__new_builder(m.key_values.len*10);')
g.auto_str_funcs.writeln('\tstrings__Builder_write_string(&sb, _SLIT("{"));')
g.auto_str_funcs.writeln('\tbool is_first = true;')
@ -945,14 +945,14 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, lang ast.Language, styp strin
// _str() functions should have a single argument, the indenting ones take 2:
is_c_struct := lang == .c
arg_def := if is_c_struct { '${styp}* it' } else { '${styp} it' }
g.definitions.writeln('static string ${str_fn_name}(${arg_def}); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}(${arg_def}) { return indent_${str_fn_name}(it, 0);}')
g.definitions.writeln('static string indent_${str_fn_name}(${arg_def}, int indent_count); // auto')
g.definitions.writeln('string ${str_fn_name}(${arg_def}); // auto')
g.auto_str_funcs.writeln('string ${str_fn_name}(${arg_def}) { return indent_${str_fn_name}(it, 0);}')
g.definitions.writeln('string indent_${str_fn_name}(${arg_def}, int indent_count); // auto')
mut fn_builder := strings.new_builder(512)
defer {
g.auto_fn_definitions << fn_builder.str()
}
fn_builder.writeln('static string indent_${str_fn_name}(${arg_def}, int indent_count) {')
fn_builder.writeln('string indent_${str_fn_name}(${arg_def}, int indent_count) {')
clean_struct_v_type_name := if info.is_anon { 'struct ' } else { util.strip_main_name(typ_str) }
// generate ident / indent length = 4 spaces
@ -1281,9 +1281,9 @@ fn (mut g Gen) gen_enum_static_from_string(fn_name string, mod_enum_name string,
enum_field_vals := g.table.get_enum_field_vals(mod_enum_name)
mut fn_builder := strings.new_builder(512)
g.definitions.writeln('static ${option_enum_styp} ${fn_name}(string name); // auto')
g.definitions.writeln('${option_enum_styp} ${fn_name}(string name); // auto')
fn_builder.writeln('static ${option_enum_styp} ${fn_name}(string name) {')
fn_builder.writeln('${option_enum_styp} ${fn_name}(string name) {')
fn_builder.writeln('\t${option_enum_styp} t1;')
fn_builder.writeln('\tbool exists = false;')
fn_builder.writeln('\tint inx = 0;')

View file

@ -51,7 +51,8 @@ pub struct Gen {
module_built string
timers_should_print bool
mut:
out strings.Builder
out strings.Builder
// line_nr int
cheaders strings.Builder
preincludes strings.Builder // allows includes to go before `definitions`
includes strings.Builder // all C #includes required by V modules
@ -261,7 +262,8 @@ mut:
/////////
// 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
out_fn_start_pos []int // for generating multiple .c files, stores locations of all fn positions in `out` string builder
out0_start int
static_modifier string // for parallel_cc
has_reflection bool // v.reflection has been imported
has_debugger bool // $dbg has been used in the code
@ -643,34 +645,51 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
if g.channel_definitions.len > 0 {
b.write_string2('\n// V channel code:\n', g.channel_definitions.str())
}
if g.auto_str_funcs.len > 0 {
b.write_string2('\n// V auto str functions:\n', g.auto_str_funcs.str())
}
if g.dump_funcs.len > 0 {
b.write_string2('\n// V dump functions:\n', g.dump_funcs.str())
}
if g.auto_fn_definitions.len > 0 {
b.writeln('\n// V auto functions:')
for fn_def in g.auto_fn_definitions {
b.writeln(fn_def)
}
}
if g.anon_fn_definitions.len > 0 {
if g.nr_closures > 0 {
b.writeln2('\n// V closure helpers', c_closure_helpers(g.pref))
}
/*
b.writeln('\n// V anon functions:')
for fn_def in g.anon_fn_definitions {
b.writeln(fn_def)
}
*/
}
if g.pref.is_coverage {
b.write_string2('\n// V coverage:\n', g.cov_declarations.str())
}
b.writeln('\n// end of V out (header)')
mut header := b.last_n(b.len)
header = '#ifndef V_HEADER_FILE\n#define V_HEADER_FILE' + header
header += '\n#endif\n'
g.out0_start = b.len
b.writeln('// ZULUL1')
// Code added here (after the header) goes to out_0.c in parallel cc mode
// Previously it went to the header which resulted in duplicated code and more code
// to compile for the C compiler
if g.auto_str_funcs.len > 0 {
b.write_string2('\n// V auto str functions:\n', g.auto_str_funcs.str())
}
if g.auto_fn_definitions.len > 0 {
b.writeln('\n// V auto functions2:')
for fn_def in g.auto_fn_definitions {
b.writeln(fn_def)
}
b.writeln('\n// end of V auto functions2:')
}
if g.dump_funcs.len > 0 {
b.write_string2('\n// V dump functions2:\n', g.dump_funcs.str())
}
if g.anon_fn_definitions.len > 0 {
b.writeln('\n// V anon functions:')
for fn_def in g.anon_fn_definitions {
b.writeln(fn_def)
}
}
if g.pref.is_coverage {
b.write_string2('\n// V coverage:\n', g.cov_declarations.str())
}
b.writeln('\n// end of V out')
mut header := b.last_n(b.len)
header = '#ifndef V_HEADER_FILE\n#define V_HEADER_FILE' + header
header += '\n#endif\n'
// End of out_0.c
b.writeln('// ZULUL2')
// The rest of the output
out_str := g.out.str()
b.write_string(out_str)
b.writeln('// THE END.')
@ -1014,7 +1033,8 @@ pub fn (mut g Gen) get_sumtype_variant_name(typ ast.Type, sym ast.TypeSymbol) st
}
pub fn (mut g Gen) write_typeof_functions() {
g.writeln2('', '// >> typeof() support for sum types / interfaces')
g.writeln('')
g.writeln('// >> typeof() support for sum types / interfaces')
for ityp, sym in g.table.type_symbols {
if sym.kind == .sum_type {
static_prefix := if g.pref.build_mode == .build_module { 'static ' } else { '' }
@ -1022,7 +1042,8 @@ pub fn (mut g Gen) write_typeof_functions() {
if sum_info.is_generic {
continue
}
g.writeln('${static_prefix}char * v_typeof_sumtype_${sym.cname}(int sidx) {')
g.writeln('/*C1*/${static_prefix}char * v_typeof_sumtype_${sym.cname}(int sidx) {')
g.definitions.writeln('/*C1*/${static_prefix}char * v_typeof_sumtype_${sym.cname}(int);')
if g.pref.build_mode == .build_module {
g.writeln('\t\tif( sidx == _v_type_idx_${sym.cname}() ) return "${util.strip_main_name(sym.name)}";')
for v in sum_info.variants {
@ -2489,7 +2510,13 @@ fn (mut g Gen) get_sumtype_casting_fn(got_ ast.Type, exp_ ast.Type) string {
g.get_sumtype_variant_name(exp_, exp_sym)
}
// fn_name := '${got_sym.cname}_to_sumtype_${exp_sym.cname}'
fn_name := '${g.get_sumtype_variant_name(got_, got_sym)}_to_sumtype_${cname}'
sumtype_variant_name := g.get_sumtype_variant_name(got_, got_sym)
fn_name := '${sumtype_variant_name}_to_sumtype_${cname}'
if g.pref.experimental && fn_name.contains('v__ast__Struct_to_sumtype_v__ast__TypeInfo') {
print_backtrace()
eprintln('======\n\n')
// exit(0)
}
if got == exp || g.sumtype_definitions[i] {
return fn_name
}
@ -2498,7 +2525,7 @@ fn (mut g Gen) get_sumtype_casting_fn(got_ ast.Type, exp_ ast.Type) string {
}
g.sumtype_definitions[i] = true
g.sumtype_casting_fns << SumtypeCastingFn{
fn_name: fn_name
fn_name: fn_name + '/*ISEE*/'
got: if got_.has_flag(.option) {
new_got := ast.idx_to_type(got_sym.idx).set_flag(.option)
new_got
@ -2544,7 +2571,10 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) {
is_anon_fn = true
}
if !is_anon_fn {
sb.writeln('static inline ${exp_cname} ${fun.fn_name}(${got_cname}* x) {')
// g.definitions.writeln('${g.static_modifier} inline ${exp_cname} ${fun.fn_name}(${got_cname}* x);//OK')
// sb.writeln('${g.static_modifier} inline ${exp_cname} ${fun.fn_name}(${got_cname}* x) {')
g.definitions.writeln('${exp_cname} ${fun.fn_name}(${got_cname}* x);//OK')
sb.writeln('${exp_cname} ${fun.fn_name}(${got_cname}* x) {')
sb.writeln('\t${got_cname}* ptr = memdup(x, sizeof(${got_cname}));')
}
for embed_hierarchy in g.table.get_embeds(got_sym) {
@ -2783,7 +2813,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
unwrapped_got_sym = g.table.sym(unwrapped_got_type)
}
fname := g.get_sumtype_casting_fn(unwrapped_got_type, unwrapped_expected_type)
fname := g.get_sumtype_casting_fn(unwrapped_got_type, unwrapped_expected_type) +
'/*Q*/'
if expr is ast.ArrayInit && got_sym.kind == .array_fixed {
stmt_str := g.go_before_last_stmt().trim_space()
@ -3164,7 +3195,7 @@ fn (mut g Gen) gen_clone_assignment(var_type ast.Type, val ast.Expr, typ ast.Typ
is_sumtype := g.table.type_kind(var_type) == .sum_type
if is_sumtype {
variant_typ := g.styp(typ).replace('*', '')
fn_name := g.get_sumtype_casting_fn(typ, var_type)
fn_name := g.get_sumtype_casting_fn(typ, var_type) + '/*L*/'
g.write('${fn_name}(ADDR(${variant_typ}, array_clone_static_to_depth(')
if typ.is_ptr() {
g.write('*')
@ -6163,7 +6194,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
val := g.expr_string(field.expr)
g.global_const_defs[util.no_dots(field.name)] = GlobalConstDef{
mod: field.mod
def: '${styp} ${const_name} = ${val}; // fixed array const'
def: '${g.static_modifier} ${styp} ${const_name} = ${val}; // fixed array const'
dep_names: g.table.dependent_names_in_expr(field_expr)
}
} else if field.expr.is_fixed && !field.expr.has_index
@ -6229,7 +6260,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) {
val := g.expr_string(field.expr.expr)
g.global_const_defs[util.no_dots(field.name)] = GlobalConstDef{
mod: field.mod
def: '${styp} ${const_name} = ${val}; // fixed array const'
def: '${g.static_modifier} ${styp} ${const_name} = ${val}; // fixed array const'
dep_names: g.table.dependent_names_in_expr(field_expr)
}
continue
@ -6429,6 +6460,10 @@ fn (mut g Gen) const_decl_init_later(mod string, name string, expr ast.Expr, typ
init.writeln('}')
}
mut def := '${styp} ${cname}'
if g.pref.parallel_cc {
// So that the const is usable in other files
// def = 'extern ${def}'
}
expr_sym := g.table.sym(typ)
if expr_sym.kind == .function {
// allow for: `const xyz = abc`, where `abc` is `fn abc() {}`
@ -6499,7 +6534,8 @@ fn (mut g Gen) global_decl(node ast.GlobalDecl) {
&& !util.should_bundle_module(node.mod) {
'extern '
} else {
g.static_modifier // TODO: used to be '' before parallel_cc, may cause issues
''
// g.static_modifier // TODO: used to be '' before parallel_cc, may cause issues
}
// should the global be initialized now, not later in `vinit()`
cinit := node.attrs.contains('cinit')

View file

@ -213,7 +213,7 @@ void __closure_init() {
_closure_cap--;
}
#else
void __closure_init() {
static void __closure_init() {
uint32_t page_size = sysconf(_SC_PAGESIZE);
page_size = page_size * (((ASSUMED_PAGE_SIZE - 1) / page_size) + 1);
_V_page_size = page_size;

View file

@ -61,8 +61,8 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
if g.pref.parallel_cc {
if node.is_anon {
g.write('static ')
g.definitions.write_string('static ')
// g.write('static ')
// g.definitions.write_string('static ')
}
if !node.is_anon {
g.out_fn_start_pos << g.out.len
@ -376,6 +376,7 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
// If we are building vlib/builtin, we need all private functions like array_get
// to be public, so that all V programs can access them.
g.write('VV_LOCAL_SYMBOL ')
// g.definitions.write_string('${g.static_modifier} VV_LOCAL_SYMBOL ')
g.definitions.write_string('VV_LOCAL_SYMBOL ')
}
}
@ -674,24 +675,25 @@ fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) {
}
node.has_gen[fn_name] = true
mut builder := strings.new_builder(256)
builder.writeln('/*F*/')
builder.writeln('/*F1*/')
// Generate a closure struct
if node.inherited_vars.len > 0 {
ctx_struct := g.closure_ctx(node.decl)
if ctx_struct !in g.closure_structs {
g.closure_structs << ctx_struct
builder.writeln('${ctx_struct} {')
g.definitions.writeln('/*HALLO*/${ctx_struct} {')
for var in node.inherited_vars {
var_sym := g.table.sym(var.typ)
if var_sym.info is ast.FnType {
sig := g.fn_var_signature(var_sym.info.func.return_type, var_sym.info.func.params.map(it.typ),
c_name(var.name))
builder.writeln('\t' + sig + ';')
g.definitions.writeln('\t' + sig + ';')
} else {
styp := g.styp(var.typ)
builder.writeln('\t${styp} ${c_name(var.name)};')
g.definitions.writeln('\t${styp} ${c_name(var.name)};')
}
}
builder.writeln('};\n')
g.definitions.writeln('};\n')
}
}
pos := g.out.len
@ -699,7 +701,9 @@ fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) {
g.anon_fn = true
g.fn_decl(node.decl)
g.anon_fn = was_anon_fn
builder.write_string('/*LOL*/')
builder.write_string(g.out.cut_to(pos))
builder.writeln('/*F2*/')
g.anon_fn_definitions << builder.str()
}

View file

@ -421,7 +421,7 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
// Helpers for decoding
g.get_sumtype_casting_fn(variant, typ)
g.definitions.writeln('static inline ${sym.cname} ${variant_typ}_to_sumtype_${sym.cname}(${variant_typ}* x);')
g.definitions.writeln('/*KEK*/static inline ${sym.cname} ${variant_typ}_to_sumtype_${sym.cname}(${variant_typ}* x);')
// ENCODING
enc.writeln('\tif (${var_data}${field_op}_typ == ${int(variant.idx())}) {')

View file

@ -86,6 +86,7 @@ fn (mut g Gen) writeln(s string) {
g.out.writeln(s)
// g.out_parallel[g.out_idx].writeln(s)
g.empty_line = true
// g.line_nr++
}
fn (mut g Gen) writeln2(s1 string, s2 string) {