| ... | ... | @@ -2364,24 +2364,50 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 2364 | 2364 | return; |
| 2365 | 2365 | } |
| 2366 | 2366 | |
| 2367 | | const zcu_data = try lowerZcuData(wasm, pt, nav_init); |
| 2368 | | |
| 2369 | | try wasm.data_segments.ensureUnusedCapacity(gpa, 1); |
| 2370 | | |
| 2371 | 2367 | if (is_obj) { |
| 2372 | | const gop = try wasm.navs_obj.getOrPut(gpa, nav_index); |
| 2373 | | gop.value_ptr.* = zcu_data; |
| 2374 | | wasm.data_segments.putAssumeCapacity(.pack(wasm, .{ .nav_obj = @enumFromInt(gop.index) }), {}); |
| 2368 | var uavs_i = wasm.uavs_obj.entries.len; |
| 2369 | var navs_i = wasm.navs_obj.entries.len; |
| 2370 | _ = try refNavObj(wasm, nav_index); // Possibly creates an entry in `Wasm.navs_obj`. |
| 2371 | while (true) { |
| 2372 | while (navs_i < wasm.navs_obj.entries.len) : (navs_i += 1) { |
| 2373 | const elem_nav = ip.getNav(wasm.navs_obj.keys()[navs_i]); |
| 2374 | const elem_nav_init = switch (ip.indexToKey(elem_nav.status.resolved.val)) { |
| 2375 | .variable => |variable| variable.init, |
| 2376 | else => elem_nav.status.resolved.val, |
| 2377 | }; |
| 2378 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 2379 | wasm.navs_obj.values()[navs_i] = try lowerZcuData(wasm, pt, elem_nav_init); |
| 2380 | } |
| 2381 | while (uavs_i < wasm.uavs_obj.entries.len) : (uavs_i += 1) { |
| 2382 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 2383 | wasm.uavs_obj.values()[uavs_i] = try lowerZcuData(wasm, pt, wasm.uavs_obj.keys()[uavs_i]); |
| 2384 | } |
| 2385 | if (navs_i >= wasm.navs_obj.entries.len) break; |
| 2386 | } |
| 2387 | } else { |
| 2388 | var uavs_i = wasm.uavs_exe.entries.len; |
| 2389 | var navs_i = wasm.navs_exe.entries.len; |
| 2390 | _ = try refNavExe(wasm, nav_index); // Possibly creates an entry in `Wasm.navs_exe`. |
| 2391 | while (true) { |
| 2392 | while (navs_i < wasm.navs_exe.entries.len) : (navs_i += 1) { |
| 2393 | const elem_nav = ip.getNav(wasm.navs_exe.keys()[navs_i]); |
| 2394 | const elem_nav_init = switch (ip.indexToKey(elem_nav.status.resolved.val)) { |
| 2395 | .variable => |variable| variable.init, |
| 2396 | else => elem_nav.status.resolved.val, |
| 2397 | }; |
| 2398 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 2399 | const zcu_data = try lowerZcuData(wasm, pt, elem_nav_init); |
| 2400 | assert(zcu_data.relocs.len == 0); |
| 2401 | wasm.navs_exe.values()[navs_i].code = zcu_data.code; |
| 2402 | } |
| 2403 | while (uavs_i < wasm.uavs_exe.entries.len) : (uavs_i += 1) { |
| 2404 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 2405 | const zcu_data = try lowerZcuData(wasm, pt, wasm.uavs_exe.keys()[uavs_i]); |
| 2406 | wasm.uavs_exe.values()[uavs_i].code = zcu_data.code; |
| 2407 | } |
| 2408 | if (navs_i >= wasm.navs_exe.entries.len) break; |
| 2409 | } |
| 2375 | 2410 | } |
| 2376 | | |
| 2377 | | assert(zcu_data.relocs.len == 0); |
| 2378 | | |
| 2379 | | const gop = try wasm.navs_exe.getOrPut(gpa, nav_index); |
| 2380 | | gop.value_ptr.* = .{ |
| 2381 | | .code = zcu_data.code, |
| 2382 | | .count = if (gop.found_existing) gop.value_ptr.count else 0, |
| 2383 | | }; |
| 2384 | | wasm.data_segments.putAssumeCapacity(.pack(wasm, .{ .nav_exe = @enumFromInt(gop.index) }), {}); |
| 2385 | 2411 | } |
| 2386 | 2412 | |
| 2387 | 2413 | pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { |
| ... | ... | @@ -3346,18 +3372,23 @@ pub fn symbolNameIndex(wasm: *Wasm, name: String) Allocator.Error!SymbolTableInd |
| 3346 | 3372 | return @enumFromInt(gop.index); |
| 3347 | 3373 | } |
| 3348 | 3374 | |
| 3349 | | pub fn refUavObj(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !UavsObjIndex { |
| 3375 | pub fn refUavObj(wasm: *Wasm, ip_index: InternPool.Index) !UavsObjIndex { |
| 3350 | 3376 | const comp = wasm.base.comp; |
| 3351 | 3377 | const gpa = comp.gpa; |
| 3352 | 3378 | assert(comp.config.output_mode == .Obj); |
| 3379 | try wasm.data_segments.ensureUnusedCapacity(gpa, 1); |
| 3353 | 3380 | const gop = try wasm.uavs_obj.getOrPut(gpa, ip_index); |
| 3354 | | if (!gop.found_existing) gop.value_ptr.* = try lowerZcuData(wasm, pt, ip_index); |
| 3381 | if (!gop.found_existing) gop.value_ptr.* = .{ |
| 3382 | // Lowering the value is delayed to avoid recursion. |
| 3383 | .code = undefined, |
| 3384 | .relocs = undefined, |
| 3385 | }; |
| 3355 | 3386 | const uav_index: UavsObjIndex = @enumFromInt(gop.index); |
| 3356 | | try wasm.data_segments.put(gpa, .pack(wasm, .{ .uav_obj = uav_index }), {}); |
| 3387 | wasm.data_segments.putAssumeCapacity(.pack(wasm, .{ .uav_obj = uav_index }), {}); |
| 3357 | 3388 | return uav_index; |
| 3358 | 3389 | } |
| 3359 | 3390 | |
| 3360 | | pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !UavsExeIndex { |
| 3391 | pub fn refUavExe(wasm: *Wasm, ip_index: InternPool.Index) !UavsExeIndex { |
| 3361 | 3392 | const comp = wasm.base.comp; |
| 3362 | 3393 | const gpa = comp.gpa; |
| 3363 | 3394 | assert(comp.config.output_mode != .Obj); |
| ... | ... | @@ -3365,9 +3396,9 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua |
| 3365 | 3396 | if (gop.found_existing) { |
| 3366 | 3397 | gop.value_ptr.count += 1; |
| 3367 | 3398 | } else { |
| 3368 | | const zcu_data = try lowerZcuData(wasm, pt, ip_index); |
| 3369 | 3399 | gop.value_ptr.* = .{ |
| 3370 | | .code = zcu_data.code, |
| 3400 | // Lowering the value is delayed to avoid recursion. |
| 3401 | .code = undefined, |
| 3371 | 3402 | .count = 1, |
| 3372 | 3403 | }; |
| 3373 | 3404 | } |
| ... | ... | @@ -3376,6 +3407,21 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua |
| 3376 | 3407 | return uav_index; |
| 3377 | 3408 | } |
| 3378 | 3409 | |
| 3410 | pub fn refNavObj(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsObjIndex { |
| 3411 | const comp = wasm.base.comp; |
| 3412 | const gpa = comp.gpa; |
| 3413 | assert(comp.config.output_mode != .Obj); |
| 3414 | const gop = try wasm.navs_obj.getOrPut(gpa, nav_index); |
| 3415 | if (!gop.found_existing) gop.value_ptr.* = .{ |
| 3416 | // Lowering the value is delayed to avoid recursion. |
| 3417 | .code = undefined, |
| 3418 | .relocs = undefined, |
| 3419 | }; |
| 3420 | const navs_obj_index: NavsObjIndex = @enumFromInt(gop.index); |
| 3421 | try wasm.data_segments.put(gpa, .pack(wasm, .{ .nav_obj = navs_obj_index }), {}); |
| 3422 | return navs_obj_index; |
| 3423 | } |
| 3424 | |
| 3379 | 3425 | pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { |
| 3380 | 3426 | const comp = wasm.base.comp; |
| 3381 | 3427 | const gpa = comp.gpa; |
| ... | ... | @@ -3385,8 +3431,9 @@ pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { |
| 3385 | 3431 | gop.value_ptr.count += 1; |
| 3386 | 3432 | } else { |
| 3387 | 3433 | gop.value_ptr.* = .{ |
| 3434 | // Lowering the value is delayed to avoid recursion. |
| 3388 | 3435 | .code = undefined, |
| 3389 | | .count = 1, |
| 3436 | .count = 0, |
| 3390 | 3437 | }; |
| 3391 | 3438 | } |
| 3392 | 3439 | const navs_exe_index: NavsExeIndex = @enumFromInt(gop.index); |
| ... | ... | @@ -3481,6 +3528,11 @@ pub fn isBss(wasm: *const Wasm, optional_name: OptionalString) bool { |
| 3481 | 3528 | return mem.eql(u8, s, ".bss") or mem.startsWith(u8, s, ".bss."); |
| 3482 | 3529 | } |
| 3483 | 3530 | |
| 3531 | /// After this function is called, there may be additional entries in |
| 3532 | /// `Wasm.uavs_obj`, `Wasm.uavs_exe`, `Wasm.navs_obj`, and `Wasm.navs_exe` |
| 3533 | /// which have uninitialized code and relocations. This function is |
| 3534 | /// non-recursive, so callers must coordinate additional calls to populate |
| 3535 | /// those entries. |
| 3484 | 3536 | fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !ZcuDataObj { |
| 3485 | 3537 | const code_start: u32 = @intCast(wasm.string_bytes.items.len); |
| 3486 | 3538 | const relocs_start: u32 = @intCast(wasm.out_relocs.len); |