Skip to content

Commit ef39e83

Browse files
fix: support more types in switch statements
1 parent f16b08f commit ef39e83

File tree

4 files changed

+5508
-112
lines changed

4 files changed

+5508
-112
lines changed

src/compiler.ts

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2806,19 +2806,48 @@ export class Compiler extends DiagnosticEmitter {
28062806
let numCases = cases.length;
28072807

28082808
// Compile the condition (always executes)
2809-
let condExpr = this.compileExpression(statement.condition, Type.u32,
2810-
Constraints.ConvImplicit
2811-
);
2809+
let condExpr = this.compileExpression(statement.condition, Type.auto);
2810+
2811+
// Get the type set from compiling the condition expression
2812+
let currentType = this.currentType;
2813+
2814+
// Determine the binary operation to use for comparison
2815+
let binaryOp: BinaryOp;
2816+
switch (currentType.toRef()) {
2817+
case TypeRef.I32: {
2818+
binaryOp = BinaryOp.EqI32;
2819+
break;
2820+
}
2821+
case TypeRef.I64: {
2822+
binaryOp = BinaryOp.EqI64;
2823+
break;
2824+
}
2825+
case TypeRef.F32: {
2826+
binaryOp = BinaryOp.EqF32;
2827+
break;
2828+
}
2829+
case TypeRef.F64: {
2830+
binaryOp = BinaryOp.EqF64;
2831+
break;
2832+
}
2833+
default: {
2834+
this.error(
2835+
DiagnosticCode.Not_implemented_0,
2836+
statement.range, `Switch condition of type ${currentType}`
2837+
);
2838+
return module.unreachable();
2839+
}
2840+
}
28122841

28132842
// Shortcut if there are no cases
28142843
if (!numCases) return module.drop(condExpr);
28152844

28162845
// Assign the condition to a temporary local as we compare it multiple times
28172846
let outerFlow = this.currentFlow;
2818-
let tempLocal = outerFlow.getTempLocal(Type.u32);
2847+
let tempLocal = outerFlow.getTempLocal(currentType);
28192848
let tempLocalIndex = tempLocal.index;
28202849
let breaks = new Array<ExpressionRef>(1 + numCases);
2821-
breaks[0] = module.local_set(tempLocalIndex, condExpr, false); // u32
2850+
breaks[0] = module.local_set(tempLocalIndex, condExpr, currentType.isManaged);
28222851

28232852
// Make one br_if per labeled case and leave it to Binaryen to optimize the
28242853
// sequence of br_ifs to a br_table according to optimization levels
@@ -2832,9 +2861,9 @@ export class Compiler extends DiagnosticEmitter {
28322861
continue;
28332862
}
28342863
breaks[breakIndex++] = module.br(`case${i}|${label}`,
2835-
module.binary(BinaryOp.EqI32,
2836-
module.local_get(tempLocalIndex, TypeRef.I32),
2837-
this.compileExpression(assert(case_.label), Type.u32,
2864+
module.binary(binaryOp,
2865+
module.local_get(tempLocalIndex, currentType.toRef()),
2866+
this.compileExpression(assert(case_.label), currentType,
28382867
Constraints.ConvImplicit
28392868
)
28402869
)

0 commit comments

Comments
 (0)