|
203 | 203 | anon_fns shared []string // remove duplicate anon generated functions |
204 | 204 | sumtype_definitions map[u32]bool // `_TypeA_to_sumtype_TypeB()` fns that have been generated |
205 | 205 | trace_fn_definitions []string |
206 | | - json_types []ast.Type // to avoid json gen duplicates |
| 206 | + json_types []ast.Type // to avoid json gen duplicates |
| 207 | + json_types_pos map[ast.Type]token.Pos |
| 208 | + json_gen_pos token.Pos |
207 | 209 | pcs []ProfileCounterMeta // -prof profile counter fn_names => fn counter name |
208 | 210 | hotcode_fn_names []string |
209 | 211 | hotcode_fpaths []string |
@@ -485,6 +487,11 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) GenO |
485 | 487 | global_g.array_last_index_types << g.array_last_index_types |
486 | 488 | global_g.pcs << g.pcs |
487 | 489 | global_g.json_types << g.json_types |
| 490 | + for k, v in g.json_types_pos { |
| 491 | + if k !in global_g.json_types_pos || global_g.json_types_pos[k] == token.Pos{} { |
| 492 | + global_g.json_types_pos[k] = v |
| 493 | + } |
| 494 | + } |
488 | 495 | global_g.hotcode_fn_names << g.hotcode_fn_names |
489 | 496 | global_g.hotcode_fpaths << g.hotcode_fpaths |
490 | 497 | global_g.test_function_names << g.test_function_names |
@@ -1118,6 +1125,10 @@ pub fn (mut g Gen) init() { |
1118 | 1125 | // muttable.used_features.used_fns['exit'] = true |
1119 | 1126 | } |
1120 | 1127 |
|
| 1128 | +fn (g &Gen) should_use_object_local_linkage(mod string) bool { |
| 1129 | + return g.pref.is_o && g.module_built != '' && mod != g.module_built |
| 1130 | +} |
| 1131 | + |
1121 | 1132 | pub fn (mut g Gen) finish() { |
1122 | 1133 | if g.pref.is_prof && g.pref.build_mode != .build_module { |
1123 | 1134 | g.gen_vprint_profile_stats() |
@@ -9160,6 +9171,52 @@ fn (mut g Gen) check_noscan(elem_typ ast.Type) string { |
9160 | 9171 | return '' |
9161 | 9172 | } |
9162 | 9173 |
|
| 9174 | +// vgc_ptrmap computes a precise pointer bitmap for simple VGC heap allocations. |
| 9175 | +fn (mut g Gen) vgc_ptrmap(typ ast.Type) (string, string) { |
| 9176 | + if g.pref.gc_mode != .vgc { |
| 9177 | + return '', '' |
| 9178 | + } |
| 9179 | + if !g.contains_ptr(typ) { |
| 9180 | + return '', '' |
| 9181 | + } |
| 9182 | + unwrapped := g.unwrap_generic(typ) |
| 9183 | + sym := g.table.final_sym(unwrapped) |
| 9184 | + if sym.kind != .struct { |
| 9185 | + return '', '' |
| 9186 | + } |
| 9187 | + info := sym.info as ast.Struct |
| 9188 | + styp := g.styp(unwrapped) |
| 9189 | + mut parts := []string{} |
| 9190 | + mut nptrs := 0 |
| 9191 | + for embed in info.embeds { |
| 9192 | + if g.contains_ptr(embed) { |
| 9193 | + return '', '' |
| 9194 | + } |
| 9195 | + } |
| 9196 | + for field in info.fields { |
| 9197 | + if field.typ.is_any_kind_of_pointer() || field.typ.is_ptr() { |
| 9198 | + fname := c_name(field.name) |
| 9199 | + parts << '(1ULL << (offsetof(${styp}, ${fname}) / sizeof(void*)))' |
| 9200 | + nptrs++ |
| 9201 | + } else { |
| 9202 | + fsym := g.table.final_sym(field.typ) |
| 9203 | + if fsym.kind in [.array, .map, .string] { |
| 9204 | + fname := c_name(field.name) |
| 9205 | + parts << '(1ULL << (offsetof(${styp}, ${fname}) / sizeof(void*)))' |
| 9206 | + nptrs++ |
| 9207 | + } else if fsym.kind in [.interface, .sum_type] { |
| 9208 | + return '', '' |
| 9209 | + } else if g.contains_ptr(field.typ) { |
| 9210 | + return '', '' |
| 9211 | + } |
| 9212 | + } |
| 9213 | + } |
| 9214 | + if parts.len == 0 { |
| 9215 | + return '', '' |
| 9216 | + } |
| 9217 | + return '(uint64_t)(${parts.join(' | ')})', '${nptrs}' |
| 9218 | +} |
| 9219 | + |
9163 | 9220 | // vint2int rename `_vint_t` to `int` |
9164 | 9221 | fn vint2int(name string) string { |
9165 | 9222 | $if new_int ? && x64 { |
|
0 commit comments