| ... | @@ -2364,24 +2364,50 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index | ... | @@ -2364,24 +2364,50 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 2364 | return; | 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 | if (is_obj) { | 2367 | if (is_obj) { |
| 2372 | const gop = try wasm.navs_obj.getOrPut(gpa, nav_index); | 2368 | var uavs_i = wasm.uavs_obj.entries.len; |
| 2373 | gop.value_ptr.* = zcu_data; | 2369 | var navs_i = wasm.navs_obj.entries.len; |
| 2374 | wasm.data_segments.putAssumeCapacity(.pack(wasm, .{ .nav_obj = @enumFromInt(gop.index) }), {}); | 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 | pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { | 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,18 +3372,23 @@ pub fn symbolNameIndex(wasm: *Wasm, name: String) Allocator.Error!SymbolTableInd |
| 3346 | return @enumFromInt(gop.index); | 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 | const comp = wasm.base.comp; | 3376 | const comp = wasm.base.comp; |
| 3351 | const gpa = comp.gpa; | 3377 | const gpa = comp.gpa; |
| 3352 | assert(comp.config.output_mode == .Obj); | 3378 | assert(comp.config.output_mode == .Obj); |
| | 3379 | try wasm.data_segments.ensureUnusedCapacity(gpa, 1); |
| 3353 | const gop = try wasm.uavs_obj.getOrPut(gpa, ip_index); | 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 | const uav_index: UavsObjIndex = @enumFromInt(gop.index); | 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 | return uav_index; | 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 | const comp = wasm.base.comp; | 3392 | const comp = wasm.base.comp; |
| 3362 | const gpa = comp.gpa; | 3393 | const gpa = comp.gpa; |
| 3363 | assert(comp.config.output_mode != .Obj); | 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,9 +3396,9 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua |
| 3365 | if (gop.found_existing) { | 3396 | if (gop.found_existing) { |
| 3366 | gop.value_ptr.count += 1; | 3397 | gop.value_ptr.count += 1; |
| 3367 | } else { | 3398 | } else { |
| 3368 | const zcu_data = try lowerZcuData(wasm, pt, ip_index); | | |
| 3369 | gop.value_ptr.* = .{ | 3399 | gop.value_ptr.* = .{ |
| 3370 | .code = zcu_data.code, | 3400 | // Lowering the value is delayed to avoid recursion. |
| | 3401 | .code = undefined, |
| 3371 | .count = 1, | 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,6 +3407,21 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua |
| 3376 | return uav_index; | 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 | pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { | 3425 | pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { |
| 3380 | const comp = wasm.base.comp; | 3426 | const comp = wasm.base.comp; |
| 3381 | const gpa = comp.gpa; | 3427 | const gpa = comp.gpa; |
| ... | @@ -3385,8 +3431,9 @@ pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { | ... | @@ -3385,8 +3431,9 @@ pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { |
| 3385 | gop.value_ptr.count += 1; | 3431 | gop.value_ptr.count += 1; |
| 3386 | } else { | 3432 | } else { |
| 3387 | gop.value_ptr.* = .{ | 3433 | gop.value_ptr.* = .{ |
| | 3434 | // Lowering the value is delayed to avoid recursion. |
| 3388 | .code = undefined, | 3435 | .code = undefined, |
| 3389 | .count = 1, | 3436 | .count = 0, |
| 3390 | }; | 3437 | }; |
| 3391 | } | 3438 | } |
| 3392 | const navs_exe_index: NavsExeIndex = @enumFromInt(gop.index); | 3439 | const navs_exe_index: NavsExeIndex = @enumFromInt(gop.index); |
| ... | @@ -3481,6 +3528,11 @@ pub fn isBss(wasm: *const Wasm, optional_name: OptionalString) bool { | ... | @@ -3481,6 +3528,11 @@ pub fn isBss(wasm: *const Wasm, optional_name: OptionalString) bool { |
| 3481 | return mem.eql(u8, s, ".bss") or mem.startsWith(u8, s, ".bss."); | 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 | fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !ZcuDataObj { | 3536 | fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !ZcuDataObj { |
| 3485 | const code_start: u32 = @intCast(wasm.string_bytes.items.len); | 3537 | const code_start: u32 = @intCast(wasm.string_bytes.items.len); |
| 3486 | const relocs_start: u32 = @intCast(wasm.out_relocs.len); | 3538 | const relocs_start: u32 = @intCast(wasm.out_relocs.len); |