| ... | ... | @@ -29,6 +29,9 @@ const errUnionErrorOffset = codegen.errUnionErrorOffset; |
| 29 | 29 | |
| 30 | 30 | /// Wasm Value, created when generating an instruction |
| 31 | 31 | const WValue = union(enum) { |
| 32 | /// `WValue` which has been freed and may no longer hold |
| 33 | /// any references. |
| 34 | dead: void, |
| 32 | 35 | /// May be referenced but is unused |
| 33 | 36 | none: void, |
| 34 | 37 | /// The value lives on top of the stack |
| ... | ... | @@ -86,6 +89,7 @@ const WValue = union(enum) { |
| 86 | 89 | fn offset(value: WValue) u32 { |
| 87 | 90 | switch (value) { |
| 88 | 91 | .stack_offset => |stack_offset| return stack_offset.value, |
| 92 | .dead => unreachable, |
| 89 | 93 | else => return 0, |
| 90 | 94 | } |
| 91 | 95 | } |
| ... | ... | @@ -123,7 +127,7 @@ const WValue = union(enum) { |
| 123 | 127 | .f64 => gen.free_locals_f64.append(gen.gpa, local_value) catch return, |
| 124 | 128 | .v128 => gen.free_locals_v128.append(gen.gpa, local_value) catch return, |
| 125 | 129 | } |
| 126 | | value.* = undefined; |
| 130 | value.* = .dead; |
| 127 | 131 | } |
| 128 | 132 | }; |
| 129 | 133 | |
| ... | ... | @@ -832,6 +836,7 @@ const Branch = struct { |
| 832 | 836 | |
| 833 | 837 | fn deinit(branch: *Branch, gpa: Allocator) void { |
| 834 | 838 | branch.values.deinit(gpa); |
| 839 | branch.* = undefined; |
| 835 | 840 | } |
| 836 | 841 | }; |
| 837 | 842 | |
| ... | ... | @@ -884,7 +889,7 @@ fn processDeath(func: *CodeGen, ref: Air.Inst.Ref) void { |
| 884 | 889 | if (value.local.value < reserved_indexes) { |
| 885 | 890 | return; // function arguments can never be re-used |
| 886 | 891 | } |
| 887 | | log.debug("Decreasing reference for ref: %{?d}, using local '{d}'\n", .{ Air.refToIndex(ref), value.local.value }); |
| 892 | log.debug("Decreasing reference for ref: %{?d}, using local '{d}'", .{ Air.refToIndex(ref), value.local.value }); |
| 888 | 893 | value.local.references -= 1; // if this panics, a call to `reuseOperand` was forgotten by the developer |
| 889 | 894 | if (value.local.references == 0) { |
| 890 | 895 | value.free(func); |
| ... | ... | @@ -1030,6 +1035,7 @@ fn genBlockType(ty: Type, target: std.Target) u8 { |
| 1030 | 1035 | /// Writes the bytecode depending on the given `WValue` in `val` |
| 1031 | 1036 | fn emitWValue(func: *CodeGen, value: WValue) InnerError!void { |
| 1032 | 1037 | switch (value) { |
| 1038 | .dead => unreachable, // reference to free'd `WValue` (missing reuseOperand?) |
| 1033 | 1039 | .none, .stack => {}, // no-op |
| 1034 | 1040 | .local => |idx| try func.addLabel(.local_get, idx.value), |
| 1035 | 1041 | .imm32 => |val| try func.addImm32(@bitCast(i32, val)), |
| ... | ... | @@ -1226,6 +1232,7 @@ fn genFunc(func: *CodeGen) InnerError!void { |
| 1226 | 1232 | defer { |
| 1227 | 1233 | var outer_branch = func.branches.pop(); |
| 1228 | 1234 | outer_branch.deinit(func.gpa); |
| 1235 | assert(func.branches.items.len == 0); // missing branch merge |
| 1229 | 1236 | } |
| 1230 | 1237 | // Generate MIR for function body |
| 1231 | 1238 | try func.genBody(func.air.getMainBody()); |