mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Fix switch generation for general case
This commit is contained in:
parent
850609bb72
commit
1aacbea4d0
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.teavm.wasm.generate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
@ -490,19 +491,36 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
|||
public void visit(SwitchStatement statement) {
|
||||
WasmBlock defaultBlock = new WasmBlock(false);
|
||||
|
||||
int min = statement.getClauses().stream()
|
||||
.flatMapToInt(clause -> Arrays.stream(clause.getConditions()))
|
||||
.min().orElse(0);
|
||||
int max = statement.getClauses().stream()
|
||||
.flatMapToInt(clause -> Arrays.stream(clause.getConditions()))
|
||||
.max().orElse(0);
|
||||
|
||||
breakTargets.put(statement, defaultBlock);
|
||||
IdentifiedStatement oldBreakTarget = currentBreakTarget;
|
||||
currentBreakTarget = statement;
|
||||
|
||||
WasmBlock wrapper = new WasmBlock(false);
|
||||
statement.getValue().acceptVisitor(this);
|
||||
if (min > 0) {
|
||||
result = new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.SUB, result,
|
||||
new WasmInt32Constant(min));
|
||||
}
|
||||
|
||||
WasmSwitch wasmSwitch = new WasmSwitch(result, wrapper);
|
||||
wrapper.getBody().add(wasmSwitch);
|
||||
WasmBlock[] targets = new WasmBlock[max - min + 1];
|
||||
|
||||
for (SwitchClause clause : statement.getClauses()) {
|
||||
WasmBlock caseBlock = new WasmBlock(false);
|
||||
caseBlock.getBody().add(wrapper);
|
||||
wasmSwitch.getTargets().add(wrapper);
|
||||
|
||||
for (int condition : clause.getConditions()) {
|
||||
targets[condition - min] = wrapper;
|
||||
}
|
||||
|
||||
for (Statement part : clause.getBody()) {
|
||||
part.acceptVisitor(this);
|
||||
if (result != null) {
|
||||
|
@ -522,6 +540,10 @@ class WasmGenerationVisitor implements StatementVisitor, ExprVisitor {
|
|||
wasmSwitch.setDefaultTarget(wrapper);
|
||||
wrapper = defaultBlock;
|
||||
|
||||
for (WasmBlock target : targets) {
|
||||
wasmSwitch.getTargets().add(target != null ? target : wasmSwitch.getDefaultTarget());
|
||||
}
|
||||
|
||||
breakTargets.remove(statement);
|
||||
currentBreakTarget = oldBreakTarget;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user