diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-01-31 23:11:58 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-31 23:11:58 +0100 |
| commit | 6f13a725a3249c7f0a0f5258ac00003cd132bf15 (patch) | |
| tree | b3d9b4b8592bf40572180e1d6a21a4093809607f /src | |
| parent | ef8f694d777029caaa48c50c28ff805c058ccccb (diff) | |
| parent | 47ff57ed7ddbf4c4a0f93208fc96851c9033b8b7 (diff) | |
| download | zig-6f13a725a3249c7f0a0f5258ac00003cd132bf15.tar.gz zig-6f13a725a3249c7f0a0f5258ac00003cd132bf15.zip | |
Merge pull request #14494 from Techatrix/wasm-optional-slice
wasm: correctly handle optional slices
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 342d6b70cc..c0d0c11b56 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1706,9 +1706,11 @@ fn isByRef(ty: Type, target: std.Target) bool { return true; }, .Optional => { - if (ty.optionalReprIsPayload()) return false; + if (ty.isPtrLikeOptional()) return false; var buf: Type.Payload.ElemType = undefined; - return ty.optionalChild(&buf).hasRuntimeBitsIgnoreComptime(); + const pl_type = ty.optionalChild(&buf); + if (pl_type.zigTypeTag() == .ErrorSet) return false; + return pl_type.hasRuntimeBitsIgnoreComptime(); }, .Pointer => { // Slices act like struct and will be passed by reference @@ -3869,14 +3871,20 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: /// NOTE: Leaves the result on the stack fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue { try func.emitWValue(operand); + var buf: Type.Payload.ElemType = undefined; + const payload_ty = optional_ty.optionalChild(&buf); if (!optional_ty.optionalReprIsPayload()) { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = optional_ty.optionalChild(&buf); // When payload is zero-bits, we can treat operand as a value, rather than // a pointer to the stack value if (payload_ty.hasRuntimeBitsIgnoreComptime()) { try func.addMemArg(.i32_load8_u, .{ .offset = operand.offset(), .alignment = 1 }); } + } else if (payload_ty.isSlice()) { + switch (func.arch()) { + .wasm32 => try func.addMemArg(.i32_load, .{ .offset = operand.offset(), .alignment = 4 }), + .wasm64 => try func.addMemArg(.i64_load, .{ .offset = operand.offset(), .alignment = 8 }), + else => unreachable, + } } // Compare the null value with '0' |
