Commit 1f64432196

Techatrix <19954306+Techatrix@users.noreply.github.com>
2023-01-31 00:59:18
wasm: correctly handle optional slices
1 parent 885d696
Changed files (1)
src
arch
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,17 @@ 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()) {
+        // move the ptr on top of the stack
+        _ = try func.load(operand, Type.usize, 0);
     }
 
     // Compare the null value with '0'