| author | |
| committer | |
| log | 46af37a1ad8bcff989ae18624b02760ab7a5bfa5 |
| tree | d3cf92e07a8595883e86f00c9de099127338e775 |
| parent | 23541774d6b01b1b614cc5aa3514295ce88917a5 |
2 files changed, 59 insertions(+), 0 deletions(-)
src/link/Wasm/Flush.zig+9| ... | ... | @@ -249,6 +249,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 249 | 249 | }; |
| 250 | 250 | const is_obj = comp.config.output_mode == .Obj; |
| 251 | 251 | const allow_undefined = is_obj or wasm.import_symbols; |
| 252 | const zcu_references = if (comp.zcu) |zcu| try zcu.resolveReferences() else null; | |
| 252 | 253 | |
| 253 | 254 | const entry_name = if (wasm.entry_resolution.isNavOrUnresolved(wasm)) wasm.entry_name else .none; |
| 254 | 255 | |
| ... | ... | @@ -1223,6 +1224,14 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 1223 | 1224 | try emitTagIndexFunction(wasm, binary_bytes, ip_index); |
| 1224 | 1225 | }, |
| 1225 | 1226 | else => { |
| 1227 | if (!zcu_references.?.contains(.wrap(.{ .func = ip_index }))) { | |
| 1228 | try binary_bytes.appendSlice(gpa, &.{ | |
| 1229 | 0, // no locals | |
| 1230 | @backingInt(std.wasm.Opcode.@"unreachable"), | |
| 1231 | @backingInt(std.wasm.Opcode.end), | |
| 1232 | }); | |
| 1233 | continue; | |
| 1234 | } | |
| 1226 | 1235 | const func = i.value(wasm).function; |
| 1227 | 1236 | const mir: Mir = .{ |
| 1228 | 1237 | .instructions = wasm.mir_instructions.slice().subslice(func.instructions_off, func.instructions_len), |
test/incremental/remove_function_with_changed_callee created+50| ... | ... | @@ -0,0 +1,50 @@ |
| 1 | #update=initial version | |
| 2 | #file=main.zig | |
| 3 | const std = @import("std"); | |
| 4 | const io = std.Io.Threaded.global_single_threaded.io(); | |
| 5 | ||
| 6 | const A = enum(u32) { | |
| 7 | zero, | |
| 8 | one, | |
| 9 | }; | |
| 10 | ||
| 11 | fn foo() !void { | |
| 12 | try bar(.zero); | |
| 13 | } | |
| 14 | ||
| 15 | fn bar(a: A) !void { | |
| 16 | const msg = switch (a) { | |
| 17 | .zero => "0", | |
| 18 | .one => "1", | |
| 19 | }; | |
| 20 | try std.Io.File.stdout().writeStreamingAll(io, msg); | |
| 21 | } | |
| 22 | ||
| 23 | pub fn main() !void { | |
| 24 | try foo(); | |
| 25 | } | |
| 26 | #expect_stdout="0" | |
| 27 | #update=remove foo and change bar wasm function type | |
| 28 | #file=main.zig | |
| 29 | //! This update must preserve `bar` `InternPool.Index` value, while changing its wasm function type. | |
| 30 | //! If `foo` code is preserved in the binary without any changes, wasm type checking will fail. | |
| 31 | const std = @import("std"); | |
| 32 | const io = std.Io.Threaded.global_single_threaded.io(); | |
| 33 | ||
| 34 | const A = enum(u64) { | |
| 35 | zero, | |
| 36 | one, | |
| 37 | }; | |
| 38 | ||
| 39 | fn bar(a: A) !void { | |
| 40 | const msg = switch (a) { | |
| 41 | .zero => "0", | |
| 42 | .one => "1", | |
| 43 | }; | |
| 44 | try std.Io.File.stdout().writeStreamingAll(io, msg); | |
| 45 | } | |
| 46 | ||
| 47 | pub fn main() !void { | |
| 48 | try bar(.one); | |
| 49 | } | |
| 50 | #expect_stdout="1" |