| ... | @@ -675,6 +675,88 @@ pub const ZcuDataExe = extern struct { | ... | @@ -675,6 +675,88 @@ pub const ZcuDataExe = extern struct { |
| 675 | count: u32, | 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 | pub const ZcuFunc = extern struct { | 760 | pub const ZcuFunc = extern struct { |
| 679 | function: CodeGen.Function, | 761 | function: CodeGen.Function, |
| 680 | | 762 | |
| ... | @@ -2306,6 +2388,8 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, | ... | @@ -2306,6 +2388,8 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, |
| 2306 | try wasm.functions.ensureUnusedCapacity(gpa, 1); | 2388 | try wasm.functions.ensureUnusedCapacity(gpa, 1); |
| 2307 | try wasm.zcu_funcs.ensureUnusedCapacity(gpa, 1); | 2389 | try wasm.zcu_funcs.ensureUnusedCapacity(gpa, 1); |
| 2308 | | 2390 | |
| | 2391 | const zds: ZcuDataStarts = .init(wasm); |
| | 2392 | |
| 2309 | // This converts AIR to MIR but does not yet lower to wasm code. | 2393 | // This converts AIR to MIR but does not yet lower to wasm code. |
| 2310 | // That lowering happens during `flush`, after garbage collection, which | 2394 | // That lowering happens during `flush`, after garbage collection, which |
| 2311 | // can affect function and global indexes, which affects the LEB integer | 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,6 +2398,8 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, |
| 2314 | .function = try CodeGen.function(wasm, pt, func_index, air, liveness), | 2398 | .function = try CodeGen.function(wasm, pt, func_index, air, liveness), |
| 2315 | }); | 2399 | }); |
| 2316 | wasm.functions.putAssumeCapacity(.pack(wasm, .{ .zcu_func = @enumFromInt(wasm.zcu_funcs.entries.len - 1) }), {}); | 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 | // Generate code for the "Nav", storing it in memory to be later written to | 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,48 +2451,13 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 2365 | } | 2451 | } |
| 2366 | | 2452 | |
| 2367 | if (is_obj) { | 2453 | if (is_obj) { |
| 2368 | var uavs_i = wasm.uavs_obj.entries.len; | 2454 | const zcu_data_starts: ZcuDataStarts = .initObj(wasm); |
| 2369 | var navs_i = wasm.navs_obj.entries.len; | | |
| 2370 | _ = try refNavObj(wasm, nav_index); // Possibly creates an entry in `Wasm.navs_obj`. | 2455 | _ = try refNavObj(wasm, nav_index); // Possibly creates an entry in `Wasm.navs_obj`. |
| 2371 | while (true) { | 2456 | try zcu_data_starts.finishObj(wasm, pt); |
| 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 { | 2457 | } else { |
| 2388 | var uavs_i = wasm.uavs_exe.entries.len; | 2458 | const zcu_data_starts: ZcuDataStarts = .initExe(wasm); |
| 2389 | var navs_i = wasm.navs_exe.entries.len; | | |
| 2390 | _ = try refNavExe(wasm, nav_index); // Possibly creates an entry in `Wasm.navs_exe`. | 2459 | _ = try refNavExe(wasm, nav_index); // Possibly creates an entry in `Wasm.navs_exe`. |
| 2391 | while (true) { | 2460 | try zcu_data_starts.finishExe(wasm, pt); |
| 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 | } | | |
| 2410 | } | 2461 | } |
| 2411 | } | 2462 | } |
| 2412 | | 2463 | |