| ... | ... | @@ -675,6 +675,88 @@ pub const ZcuDataExe = extern struct { |
| 675 | 675 | count: u32, |
| 676 | 676 | }; |
| 677 | 677 | |
| 678 | /// An abstraction for calling `lowerZcuData` repeatedly until all data entries |
| 679 | /// are populated. |
| 680 | const ZcuDataStarts = struct { |
| 681 | uavs_i: u32, |
| 682 | navs_i: u32, |
| 683 | |
| 684 | fn init(wasm: *const Wasm) ZcuDataStarts { |
| 685 | const comp = wasm.base.comp; |
| 686 | const is_obj = comp.config.output_mode == .Obj; |
| 687 | return if (is_obj) initObj(wasm) else initExe(wasm); |
| 688 | } |
| 689 | |
| 690 | fn initObj(wasm: *const Wasm) ZcuDataStarts { |
| 691 | return .{ |
| 692 | .uavs_i = @intCast(wasm.uavs_obj.entries.len), |
| 693 | .navs_i = @intCast(wasm.navs_obj.entries.len), |
| 694 | }; |
| 695 | } |
| 696 | |
| 697 | fn initExe(wasm: *const Wasm) ZcuDataStarts { |
| 698 | return .{ |
| 699 | .uavs_i = @intCast(wasm.uavs_exe.entries.len), |
| 700 | .navs_i = @intCast(wasm.navs_exe.entries.len), |
| 701 | }; |
| 702 | } |
| 703 | |
| 704 | fn finish(zds: ZcuDataStarts, wasm: *Wasm, pt: Zcu.PerThread) !void { |
| 705 | const comp = wasm.base.comp; |
| 706 | const is_obj = comp.config.output_mode == .Obj; |
| 707 | return if (is_obj) finishObj(zds, wasm, pt) else finishExe(zds, wasm, pt); |
| 708 | } |
| 709 | |
| 710 | fn finishObj(zds: ZcuDataStarts, wasm: *Wasm, pt: Zcu.PerThread) !void { |
| 711 | const zcu = wasm.base.comp.zcu.?; |
| 712 | const ip = &zcu.intern_pool; |
| 713 | var uavs_i = zds.uavs_i; |
| 714 | var navs_i = zds.navs_i; |
| 715 | while (true) { |
| 716 | while (navs_i < wasm.navs_obj.entries.len) : (navs_i += 1) { |
| 717 | const elem_nav = ip.getNav(wasm.navs_obj.keys()[navs_i]); |
| 718 | const elem_nav_init = switch (ip.indexToKey(elem_nav.status.resolved.val)) { |
| 719 | .variable => |variable| variable.init, |
| 720 | else => elem_nav.status.resolved.val, |
| 721 | }; |
| 722 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 723 | wasm.navs_obj.values()[navs_i] = try lowerZcuData(wasm, pt, elem_nav_init); |
| 724 | } |
| 725 | while (uavs_i < wasm.uavs_obj.entries.len) : (uavs_i += 1) { |
| 726 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 727 | wasm.uavs_obj.values()[uavs_i] = try lowerZcuData(wasm, pt, wasm.uavs_obj.keys()[uavs_i]); |
| 728 | } |
| 729 | if (navs_i >= wasm.navs_obj.entries.len) break; |
| 730 | } |
| 731 | } |
| 732 | |
| 733 | fn finishExe(zds: ZcuDataStarts, wasm: *Wasm, pt: Zcu.PerThread) !void { |
| 734 | const zcu = wasm.base.comp.zcu.?; |
| 735 | const ip = &zcu.intern_pool; |
| 736 | var uavs_i = zds.uavs_i; |
| 737 | var navs_i = zds.navs_i; |
| 738 | while (true) { |
| 739 | while (navs_i < wasm.navs_exe.entries.len) : (navs_i += 1) { |
| 740 | const elem_nav = ip.getNav(wasm.navs_exe.keys()[navs_i]); |
| 741 | const elem_nav_init = switch (ip.indexToKey(elem_nav.status.resolved.val)) { |
| 742 | .variable => |variable| variable.init, |
| 743 | else => elem_nav.status.resolved.val, |
| 744 | }; |
| 745 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 746 | const zcu_data = try lowerZcuData(wasm, pt, elem_nav_init); |
| 747 | assert(zcu_data.relocs.len == 0); |
| 748 | wasm.navs_exe.values()[navs_i].code = zcu_data.code; |
| 749 | } |
| 750 | while (uavs_i < wasm.uavs_exe.entries.len) : (uavs_i += 1) { |
| 751 | // Call to `lowerZcuData` here possibly creates more entries in these tables. |
| 752 | const zcu_data = try lowerZcuData(wasm, pt, wasm.uavs_exe.keys()[uavs_i]); |
| 753 | wasm.uavs_exe.values()[uavs_i].code = zcu_data.code; |
| 754 | } |
| 755 | if (navs_i >= wasm.navs_exe.entries.len) break; |
| 756 | } |
| 757 | } |
| 758 | }; |
| 759 | |
| 678 | 760 | pub const ZcuFunc = extern struct { |
| 679 | 761 | function: CodeGen.Function, |
| 680 | 762 | |
| ... | ... | @@ -2306,6 +2388,8 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, |
| 2306 | 2388 | try wasm.functions.ensureUnusedCapacity(gpa, 1); |
| 2307 | 2389 | try wasm.zcu_funcs.ensureUnusedCapacity(gpa, 1); |
| 2308 | 2390 | |
| 2391 | const zds: ZcuDataStarts = .init(wasm); |
| 2392 | |
| 2309 | 2393 | // This converts AIR to MIR but does not yet lower to wasm code. |
| 2310 | 2394 | // That lowering happens during `flush`, after garbage collection, which |
| 2311 | 2395 | // can affect function and global indexes, which affects the LEB integer |
| ... | ... | @@ -2314,6 +2398,8 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, |
| 2314 | 2398 | .function = try CodeGen.function(wasm, pt, func_index, air, liveness), |
| 2315 | 2399 | }); |
| 2316 | 2400 | wasm.functions.putAssumeCapacity(.pack(wasm, .{ .zcu_func = @enumFromInt(wasm.zcu_funcs.entries.len - 1) }), {}); |
| 2401 | |
| 2402 | try zds.finish(wasm, pt); |
| 2317 | 2403 | } |
| 2318 | 2404 | |
| 2319 | 2405 | // Generate code for the "Nav", storing it in memory to be later written to |
| ... | ... | @@ -2365,48 +2451,13 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 2365 | 2451 | } |
| 2366 | 2452 | |
| 2367 | 2453 | if (is_obj) { |
| 2368 | | var uavs_i = wasm.uavs_obj.entries.len; |
| 2369 | | var navs_i = wasm.navs_obj.entries.len; |
| 2454 | const zcu_data_starts: ZcuDataStarts = .initObj(wasm); |
| 2370 | 2455 | _ = 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 | | } |
| 2456 | try zcu_data_starts.finishObj(wasm, pt); |
| 2387 | 2457 | } else { |
| 2388 | | var uavs_i = wasm.uavs_exe.entries.len; |
| 2389 | | var navs_i = wasm.navs_exe.entries.len; |
| 2458 | const zcu_data_starts: ZcuDataStarts = .initExe(wasm); |
| 2390 | 2459 | _ = 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 | | } |
| 2460 | try zcu_data_starts.finishExe(wasm, pt); |
| 2410 | 2461 | } |
| 2411 | 2462 | } |
| 2412 | 2463 | |