Commit 141a0cbb5a

Luuk de Gram <Luukdegram@users.noreply.github.com>
2021-05-15 17:32:38
Explicit return & more complex wasm enum test
- When returning within a block, we must use an explicit return opcode. For now always emit the opcode when calling return, rather than using implicit return statements. - Also added a more comprehensive test case to test for enum values using conditions
1 parent 9ddede2
Changed files (2)
src
codegen
test
stage2
src/codegen/wasm.zig
@@ -758,6 +758,7 @@ pub const Context = struct {
         // TODO: Implement tail calls
         const operand = self.resolveInst(inst.operand);
         try self.emitWValue(operand);
+        try self.code.append(wasm.opcode(.@"return"));
         return .none;
     }
 
@@ -903,6 +904,9 @@ pub const Context = struct {
                             if (enum_full.values.count() != 0) {
                                 const tag_val = enum_full.values.entries.items[field_index.data].key;
                                 try self.emitConstant(src, tag_val, enum_full.tag_ty);
+                            } else {
+                                try writer.writeByte(wasm.opcode(.i32_const));
+                                try leb.writeULEB128(writer, field_index.data);
                             }
                         },
                         else => unreachable,
test/stage2/wasm.zig
@@ -391,7 +391,7 @@ pub fn addCases(ctx: *TestContext) !void {
         case.addCompareOutput(
             \\const Number = enum { One, Two, Three };
             \\
-            \\export fn _start() i32 {
+            \\pub export fn _start() i32 {
             \\    var number1 = Number.One;
             \\    var number2: Number = .Two;
             \\    const number3 = @intToEnum(Number, 2);
@@ -399,5 +399,24 @@ pub fn addCases(ctx: *TestContext) !void {
             \\    return @enumToInt(number3);
             \\}
         , "2\n");
+
+        case.addCompareOutput(
+            \\const Number = enum { One, Two, Three };
+            \\
+            \\pub export fn _start() i32 {
+            \\    var number1 = Number.One;
+            \\    var number2: Number = .Two;
+            \\    const number3 = @intToEnum(Number, 2);
+            \\    if (number1 == number2) return 1;
+            \\    if (number2 == number3) return 1;
+            \\    if (@enumToInt(number1) != 0) return 1;
+            \\    if (@enumToInt(number2) != 1) return 1;
+            \\    if (@enumToInt(number3) != 2) return 1;
+            \\    var x: Number = .Two;
+            \\    if (number2 != x) return 1;
+            \\
+            \\    return @enumToInt(number3);
+            \\}
+        , "2\n");
     }
 }