WASM: fix exception handling. Use if instead of switch after call site when possible

This commit is contained in:
Alexey Andreev 2016-09-27 19:48:37 +03:00
parent 8a012178ed
commit cbd74d41f4
2 changed files with 24 additions and 1 deletions

View File

@ -216,6 +216,10 @@ public class WasmTarget implements TeaVMTarget {
int.class), null).use(); int.class), null).use();
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getStackRootPointer", Address.class, dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getStackRootPointer", Address.class,
Address.class), null).use(); Address.class), null).use();
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "setExceptionHandlerId", Address.class,
int.class, void.class), null).use();
dependencyChecker.linkMethod(new MethodReference(WasmRuntime.class, "getCallSiteId", Address.class,
int.class), null).use();
dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocate", dependencyChecker.linkMethod(new MethodReference(Allocator.class, "allocate",
RuntimeClass.class, Address.class), null).use(); RuntimeClass.class, Address.class), null).use();

View File

@ -32,6 +32,8 @@ import org.teavm.model.TryCatchBlock;
import org.teavm.model.TryCatchJoint; import org.teavm.model.TryCatchJoint;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
import org.teavm.model.Variable; import org.teavm.model.Variable;
import org.teavm.model.instructions.BinaryBranchingCondition;
import org.teavm.model.instructions.BinaryBranchingInstruction;
import org.teavm.model.instructions.CloneArrayInstruction; import org.teavm.model.instructions.CloneArrayInstruction;
import org.teavm.model.instructions.ConstructArrayInstruction; import org.teavm.model.instructions.ConstructArrayInstruction;
import org.teavm.model.instructions.ConstructInstruction; import org.teavm.model.instructions.ConstructInstruction;
@ -240,7 +242,6 @@ public class ExceptionHandlingShadowStackContributor {
SwitchInstruction switchInsn = new SwitchInstruction(); SwitchInstruction switchInsn = new SwitchInstruction();
switchInsn.setCondition(handlerIdVariable); switchInsn.setCondition(handlerIdVariable);
instructions.add(switchInsn);
if (next != null) { if (next != null) {
SwitchTableEntry continueExecutionEntry = new SwitchTableEntry(); SwitchTableEntry continueExecutionEntry = new SwitchTableEntry();
@ -280,6 +281,24 @@ public class ExceptionHandlingShadowStackContributor {
switchInsn.setDefaultTarget(getDefaultExceptionHandler()); switchInsn.setDefaultTarget(getDefaultExceptionHandler());
} }
if (switchInsn.getEntries().size() == 1) {
SwitchTableEntry entry = switchInsn.getEntries().get(0);
IntegerConstantInstruction singleTestConstant = new IntegerConstantInstruction();
singleTestConstant.setConstant(entry.getCondition());
singleTestConstant.setReceiver(program.createVariable());
instructions.add(singleTestConstant);
BinaryBranchingInstruction branching = new BinaryBranchingInstruction(BinaryBranchingCondition.EQUAL);
branching.setConsequent(entry.getTarget());
branching.setAlternative(switchInsn.getDefaultTarget());
branching.setFirstOperand(switchInsn.getCondition());
branching.setSecondOperand(singleTestConstant.getReceiver());
instructions.add(branching);
} else {
instructions.add(switchInsn);
}
return instructions; return instructions;
} }