Skip to content

Commit b831b0e

Browse files
authored
v2: move all generics logic to transformer; fixes to compile the 3d game engine Viper (#27304)
1 parent f5e464e commit b831b0e

65 files changed

Lines changed: 21298 additions & 2953 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎cmd/v2/test_ssa_backends.v‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() {
1414
vroot := os.dir(@VEXE)
1515
v2_source := os.join_path(vroot, 'cmd', 'v2', 'v2.v')
1616
v2_binary := os.join_path(vroot, 'cmd', 'v2', 'v2')
17-
build_res := os.execute('${@VEXE} -gc none ${v2_source} -o ${v2_binary}')
17+
build_res := os.execute('${@VEXE} -gc none -cc cc ${v2_source} -o ${v2_binary}')
1818
if build_res.exit_code != 0 {
1919
eprintln('Error: Failed to build v2')
2020
eprintln(build_res.output)

‎vlib/v2/builder/builder.v‎

Lines changed: 154 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,33 @@ fn (b &Builder) cached_called_fn_name_list() []string {
857857
return names
858858
}
859859

860+
fn cached_called_fn_names_path(cache_dir string, cache_name string) string {
861+
return cache_path_join(cache_dir, '${cache_name}.calls')
862+
}
863+
864+
fn (mut b Builder) load_cached_called_fn_names(cache_dir string, cache_name string) bool {
865+
data := os.read_file(cached_called_fn_names_path(cache_dir, cache_name)) or { return false }
866+
for line in data.split_into_lines() {
867+
name := line.trim_space()
868+
if name.len > 0 {
869+
b.cached_called_fn_names[name] = true
870+
}
871+
}
872+
return true
873+
}
874+
875+
fn (mut b Builder) write_cached_called_fn_names(cache_dir string, cache_name string, before map[string]bool) {
876+
mut names := []string{}
877+
for name, _ in b.cached_called_fn_names {
878+
if name.len == 0 || name in before {
879+
continue
880+
}
881+
names << name
882+
}
883+
names.sort()
884+
os.write_file(cached_called_fn_names_path(cache_dir, cache_name), names.join('\n')) or {}
885+
}
886+
860887
fn cache_type_module_names(cache_bundle_name string, emit_modules []string) []string {
861888
if cache_bundle_name == '' {
862889
return emit_modules
@@ -901,6 +928,43 @@ fn (b &Builder) expand_type_modules_with_imports(modules []string) []string {
901928
return unique_sorted_strings(type_modules.keys())
902929
}
903930

931+
fn (b &Builder) has_external_cache_module_name_collision(module_names []string) bool {
932+
mut module_set := map[string]bool{}
933+
for module_name in module_names {
934+
if module_name != '' {
935+
module_set[module_name] = true
936+
}
937+
}
938+
mut vlib_modules := map[string]bool{}
939+
mut external_modules := map[string]bool{}
940+
for file in b.files {
941+
if file.name == '' || file.name.ends_with('.vh') {
942+
continue
943+
}
944+
module_name := ast_file_module_name(file)
945+
if module_name !in module_set {
946+
continue
947+
}
948+
if b.is_vlib_source_file(file.name) {
949+
vlib_modules[module_name] = true
950+
} else {
951+
external_modules[module_name] = true
952+
}
953+
}
954+
for module_name, _ in external_modules {
955+
if module_name in vlib_modules {
956+
return true
957+
}
958+
}
959+
return false
960+
}
961+
962+
fn (b &Builder) is_vlib_source_file(file_name string) bool {
963+
root := if b.pref.vroot.len > 0 { b.pref.vroot } else { os.getwd() }
964+
vlib_root := os.norm_path(os.join_path(root, 'vlib')) + os.path_separator
965+
return os.norm_path(os.abs_path(file_name)).starts_with(vlib_root)
966+
}
967+
904968
fn import_module_name(name string) string {
905969
return name.all_after_last('.').replace('.', '_')
906970
}
@@ -956,13 +1020,21 @@ fn (mut b Builder) gen_cleanc_with_cached_core(output_name string, cc string, cc
9561020
mut optional_cached_cache_names := []string{}
9571021
mut optional_cached_module_names := []string{}
9581022
if veb_cached_module_paths.len > 0 && b.has_module('veb') {
959-
veb_obj := b.ensure_cached_module_object(cache_dir, veb_cache_name,
960-
veb_cached_module_paths, veb_cached_module_names, cc, cc_flags, cc_link_flags,
961-
error_limit_flag, true) or {
1023+
veb_cache_type_modules := b.expand_type_modules_with_imports(cache_type_module_names(veb_cache_name,
1024+
veb_cached_module_names))
1025+
veb_obj := if b.has_external_cache_module_name_collision(veb_cache_type_modules) {
9621026
if os.getenv('V2_TRACE_CACHE') != '' {
963-
eprintln('TRACE_CACHE optional_cache=veb reason=${err}')
1027+
eprintln('TRACE_CACHE optional_cache=veb reason=external_module_name_collision')
9641028
}
9651029
''
1030+
} else {
1031+
b.ensure_cached_module_object(cache_dir, veb_cache_name, veb_cached_module_paths,
1032+
veb_cached_module_names, cc, cc_flags, cc_link_flags, error_limit_flag, true) or {
1033+
if os.getenv('V2_TRACE_CACHE') != '' {
1034+
eprintln('TRACE_CACHE optional_cache=veb reason=${err}')
1035+
}
1036+
''
1037+
}
9661038
}
9671039
if veb_obj.len > 0 {
9681040
b.print_cached_bundle_modules(veb_cache_name, veb_cached_module_names)
@@ -1288,20 +1360,26 @@ fn (mut b Builder) ensure_cached_module_object(cache_dir string, cache_name stri
12881360
if os.exists(obj_path) && os.exists(stamp_path) {
12891361
if current_stamp := os.read_file(stamp_path) {
12901362
if current_stamp == expected_stamp {
1291-
if os.getenv('V2VERBOSE') != '' {
1292-
println('[*] Reusing ${obj_path}')
1363+
if b.load_cached_called_fn_names(cache_dir, cache_name) {
1364+
if os.getenv('V2VERBOSE') != '' {
1365+
println('[*] Reusing ${obj_path}')
1366+
}
1367+
return obj_path
12931368
}
1294-
return obj_path
12951369
}
12961370
}
12971371
}
12981372
if b.used_vh_for_parse {
12991373
if os.exists(obj_path) && os.exists(stamp_path) {
1300-
return obj_path
1374+
if b.load_cached_called_fn_names(cache_dir, cache_name) {
1375+
return obj_path
1376+
}
1377+
return error('missing cached ${cache_name} call metadata for .vh parse')
13011378
}
13021379
return error('missing cached ${cache_name} object for .vh parse')
13031380
}
13041381

1382+
cached_called_before := b.cached_called_fn_names.clone()
13051383
module_source := b.gen_cleanc_source_for_cache(emit_modules, cache_name, use_markused)
13061384
if module_source == '' {
13071385
return error('failed to generate C source for ${cache_name}')
@@ -1310,6 +1388,7 @@ fn (mut b Builder) ensure_cached_module_object(cache_dir string, cache_name stri
13101388

13111389
compile_cmd := '${cc} ${cc_flags} -w -Wno-incompatible-function-pointer-types -c "${c_path}" -o "${obj_path}"${error_limit_flag}'
13121390
run_cc_cmd_or_exit(compile_cmd, 'C compilation', b.pref.show_cc)
1391+
b.write_cached_called_fn_names(cache_dir, cache_name, cached_called_before)
13131392
os.write_file(stamp_path, expected_stamp)!
13141393
return obj_path
13151394
}
@@ -1323,20 +1402,26 @@ fn (mut b Builder) ensure_cached_parsed_module_object(cache_dir string, cache_na
13231402
if os.exists(obj_path) && os.exists(stamp_path) {
13241403
if current_stamp := os.read_file(stamp_path) {
13251404
if current_stamp == expected_stamp {
1326-
if os.getenv('V2VERBOSE') != '' {
1327-
println('[*] Reusing ${obj_path}')
1405+
if b.load_cached_called_fn_names(cache_dir, cache_name) {
1406+
if os.getenv('V2VERBOSE') != '' {
1407+
println('[*] Reusing ${obj_path}')
1408+
}
1409+
return obj_path
13281410
}
1329-
return obj_path
13301411
}
13311412
}
13321413
}
13331414
if b.used_import_vh_for_parse {
13341415
if os.exists(obj_path) && os.exists(stamp_path) {
1335-
return obj_path
1416+
if b.load_cached_called_fn_names(cache_dir, cache_name) {
1417+
return obj_path
1418+
}
1419+
return error('missing cached ${cache_name} call metadata for .vh parse')
13361420
}
13371421
return error('missing cached ${cache_name} object for .vh parse')
13381422
}
13391423

1424+
cached_called_before := b.cached_called_fn_names.clone()
13401425
mut module_source := b.gen_cleanc_source_for_cache(module_names, cache_name, use_markused)
13411426
if module_source == '' {
13421427
return error('failed to generate C source for ${cache_name}')
@@ -1345,6 +1430,7 @@ fn (mut b Builder) ensure_cached_parsed_module_object(cache_dir string, cache_na
13451430

13461431
compile_cmd := '${cc} ${cc_flags} -w -Wno-incompatible-function-pointer-types -c "${c_path}" -o "${obj_path}"${error_limit_flag}'
13471432
run_cc_cmd_or_exit(compile_cmd, 'C compilation', b.pref.show_cc)
1433+
b.write_cached_called_fn_names(cache_dir, cache_name, cached_called_before)
13481434
os.write_file(stamp_path, expected_stamp)!
13491435
return obj_path
13501436
}
@@ -1358,21 +1444,27 @@ fn (mut b Builder) ensure_cached_virtual_module_object(cache_dir string, groups
13581444
if os.exists(obj_path) && os.exists(stamp_path) {
13591445
if current_stamp := os.read_file(stamp_path) {
13601446
if current_stamp == expected_stamp {
1361-
if os.getenv('V2VERBOSE') != '' {
1362-
println('[*] Reusing ${obj_path}')
1447+
if b.load_cached_called_fn_names(cache_dir, virtuals_cache_name) {
1448+
if os.getenv('V2VERBOSE') != '' {
1449+
println('[*] Reusing ${obj_path}')
1450+
}
1451+
return obj_path
13631452
}
1364-
return obj_path
13651453
}
13661454
}
13671455
}
13681456
if b.used_virtual_vh_for_parse {
13691457
if os.exists(obj_path) && os.exists(stamp_path) {
1370-
return obj_path
1458+
if b.load_cached_called_fn_names(cache_dir, virtuals_cache_name) {
1459+
return obj_path
1460+
}
1461+
return error('missing cached ${virtuals_cache_name} call metadata for .vh parse')
13711462
}
13721463
return error('missing cached ${virtuals_cache_name} object for .vh parse')
13731464
}
13741465

13751466
emit_files := virtual_module_source_files(groups)
1467+
cached_called_before := b.cached_called_fn_names.clone()
13761468
mut module_source := b.gen_cleanc_source_for_cache_files(['main'], emit_files,
13771469
virtuals_cache_name, use_markused)
13781470
if module_source == '' {
@@ -1382,6 +1474,7 @@ fn (mut b Builder) ensure_cached_virtual_module_object(cache_dir string, groups
13821474

13831475
compile_cmd := '${cc} ${cc_flags} -w -Wno-incompatible-function-pointer-types -c "${c_path}" -o "${obj_path}"${error_limit_flag}'
13841476
run_cc_cmd_or_exit(compile_cmd, 'C compilation', b.pref.show_cc)
1477+
b.write_cached_called_fn_names(cache_dir, virtuals_cache_name, cached_called_before)
13851478
os.write_file(stamp_path, expected_stamp)!
13861479
return obj_path
13871480
}
@@ -1738,6 +1831,13 @@ fn parse_flag_directive_line_with_pref(line string, file_path string, prefs &pre
17381831

17391832
fn parse_flag_directive_line_with_context(line string, file_path string, target_os string, prefs &pref.Preferences) ?string {
17401833
trimmed := line.trim_space()
1834+
if trimmed.starts_with('#pkgconfig') {
1835+
if prefs != unsafe { nil } && prefs.is_cross_target() {
1836+
return none
1837+
}
1838+
rest := trimmed['#pkgconfig'.len..].trim_space()
1839+
return resolve_pkgconfig_directive_flags(rest)
1840+
}
17411841
if !trimmed.starts_with('#flag') {
17421842
return none
17431843
}
@@ -1772,6 +1872,22 @@ fn parse_flag_directive_line_with_context(line string, file_path string, target_
17721872
return normalize_flag_value_for_file(rest, file_path)
17731873
}
17741874

1875+
fn resolve_pkgconfig_directive_flags(value string) ?string {
1876+
if value == '' {
1877+
return none
1878+
}
1879+
args := if value.contains('--') {
1880+
value.fields()
1881+
} else {
1882+
'--cflags --libs ${value}'.fields()
1883+
}
1884+
flags := pref.pkgconfig_result(args) or { return none }
1885+
if flags == '' {
1886+
return none
1887+
}
1888+
return flags
1889+
}
1890+
17751891
fn flag_references_missing_file(flag string, include_flags []string) bool {
17761892
for tok in flag.fields() {
17771893
clean := tok.trim('"').trim("'")
@@ -2027,6 +2143,12 @@ fn comptime_cond_matches_with_context(cond string, target_os string, prefs &pref
20272143
}
20282144
return pref.comptime_optional_flag_value(prefs, optional_name)
20292145
}
2146+
if pkg_name := pkgconfig_cond_name(trimmed) {
2147+
if prefs != unsafe { nil } && prefs.is_cross_target() {
2148+
return false
2149+
}
2150+
return pref.comptime_pkgconfig_value(pkg_name)
2151+
}
20302152
if prefs != unsafe { nil } {
20312153
return flag_os_matches(trimmed, target_os) || flag_pref_matches(trimmed, prefs)
20322154
}
@@ -2055,6 +2177,22 @@ fn comptime_cond_matches_with_context(cond string, target_os string, prefs &pref
20552177
}
20562178
}
20572179

2180+
fn pkgconfig_cond_name(cond string) ?string {
2181+
trimmed := cond.trim_space()
2182+
if !trimmed.starts_with(r'$pkgconfig(') || !trimmed.ends_with(')') {
2183+
return none
2184+
}
2185+
arg := trimmed[r'$pkgconfig('.len..trimmed.len - 1].trim_space()
2186+
if arg.len < 2 {
2187+
return none
2188+
}
2189+
quote := arg[0]
2190+
if (quote != `'` && quote != `"`) || arg[arg.len - 1] != quote {
2191+
return none
2192+
}
2193+
return arg[1..arg.len - 1]
2194+
}
2195+
20582196
fn optional_user_ct_flag_name(cond string) ?string {
20592197
trimmed := cond.trim_space()
20602198
if !trimmed.ends_with('?') {

0 commit comments

Comments
 (0)