C: fix bugs in exception handling lowerer

This commit is contained in:
Alexey Andreev 2019-07-09 17:57:28 +03:00
parent 94996a5e00
commit f264865cc1
3 changed files with 30 additions and 22 deletions

View File

@ -141,7 +141,6 @@ public class ExceptionHandlingShadowStackContributor {
IntObjectMap<int[]> jointReceiverMaps = new IntObjectHashMap<>();
Arrays.fill(currentJointSources, -1);
IntSet outgoingVariablesToRemove = new IntHashSet();
IntSet variablesDefinedHere = new IntHashSet();
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
@ -175,6 +174,17 @@ public class ExceptionHandlingShadowStackContributor {
jointReceiverMaps.put(tryCatch.getHandler().getIndex(), jointReceiverMap);
}
for (Phi phi : block.getPhis()) {
Variable definedVar = phi.getReceiver();
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
int jointReceiver = jointReceiverMaps.get(tryCatch.getHandler().getIndex())[definedVar.getIndex()];
if (jointReceiver >= 0) {
currentJointSources[jointReceiver] = definedVar.getIndex();
}
}
variablesDefinedHere.add(definedVar.getIndex());
}
DefinitionExtractor defExtractor = new DefinitionExtractor();
List<BasicBlock> blocksToClearHandlers = new ArrayList<>();
blocksToClearHandlers.add(block);
@ -228,7 +238,7 @@ public class ExceptionHandlingShadowStackContributor {
callSites.add(callSite);
List<Instruction> pre = setLocation(getInstructionsBeforeCallSite(callSite), insn.getLocation());
List<Instruction> post = getInstructionsAfterCallSite(initialBlock, block, next, callSite,
currentJointSources, outgoingVariablesToRemove, variablesDefinedHere);
currentJointSources, variablesDefinedHere);
post = setLocation(post, insn.getLocation());
block.getLastInstruction().insertPreviousAll(pre);
block.addAll(post);
@ -238,7 +248,6 @@ public class ExceptionHandlingShadowStackContributor {
break;
}
block = next;
outgoingVariablesToRemove.clear();
variablesDefinedHere.clear();
}
@ -247,12 +256,6 @@ public class ExceptionHandlingShadowStackContributor {
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
int jointReceiver = jointReceiverMaps.get(tryCatch.getHandler().getIndex())[definedVar.getIndex()];
if (jointReceiver >= 0) {
int formerVar = currentJointSources[jointReceiver];
if (formerVar >= 0) {
if (variableDefinitionPlaces[formerVar] == initialBlock) {
outgoingVariablesToRemove.add(formerVar);
}
}
currentJointSources[jointReceiver] = definedVar.getIndex();
}
}
@ -260,7 +263,7 @@ public class ExceptionHandlingShadowStackContributor {
}
}
fixOutgoingPhis(initialBlock, block, currentJointSources, outgoingVariablesToRemove, variablesDefinedHere);
fixOutgoingPhis(initialBlock, block, currentJointSources, variablesDefinedHere);
for (BasicBlock blockToClear : blocksToClearHandlers) {
blockToClear.getTryCatchBlocks().clear();
}
@ -321,8 +324,7 @@ public class ExceptionHandlingShadowStackContributor {
}
private List<Instruction> getInstructionsAfterCallSite(BasicBlock initialBlock, BasicBlock block, BasicBlock next,
CallSiteDescriptor callSite, int[] currentJointSources, IntSet outgoingVariablesToRemove,
IntSet variablesDefinedHere) {
CallSiteDescriptor callSite, int[] currentJointSources, IntSet variablesDefinedHere) {
Program program = block.getProgram();
List<Instruction> instructions = new ArrayList<>();
@ -360,7 +362,7 @@ public class ExceptionHandlingShadowStackContributor {
switchInsn.getEntries().add(catchEntry);
}
}
fixOutgoingPhis(initialBlock, block, currentJointSources, outgoingVariablesToRemove, variablesDefinedHere);
fixOutgoingPhis(initialBlock, block, currentJointSources, variablesDefinedHere);
if (!defaultExists) {
switchInsn.setDefaultTarget(getDefaultExceptionHandler());
@ -393,7 +395,7 @@ public class ExceptionHandlingShadowStackContributor {
}
private void fixOutgoingPhis(BasicBlock block, BasicBlock newBlock, int[] currentJointSources,
IntSet outgoingVariablesToRemove, IntSet variablesDefinedHere) {
IntSet variablesDefinedHere) {
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
for (Phi phi : tryCatch.getHandler().getPhis()) {
int value = currentJointSources[phi.getReceiver().getIndex()];
@ -403,13 +405,10 @@ public class ExceptionHandlingShadowStackContributor {
List<Incoming> additionalIncomings = new ArrayList<>();
for (int i = 0; i < phi.getIncomings().size(); i++) {
Incoming incoming = phi.getIncomings().get(i);
if (incoming.getSource() != block) {
if (incoming.getSource() != block || incoming.getSource() == newBlock) {
continue;
}
if (outgoingVariablesToRemove.contains(incoming.getValue().getIndex())) {
phi.getIncomings().remove(i--);
break;
} else if (incoming.getValue().getIndex() == value && incoming.getSource() != newBlock) {
if (incoming.getValue().getIndex() == value) {
if (variablesDefinedHere.contains(value)) {
incoming.setSource(newBlock);
} else {
@ -418,7 +417,8 @@ public class ExceptionHandlingShadowStackContributor {
incomingCopy.setValue(incoming.getValue());
additionalIncomings.add(incomingCopy);
}
break;
} else {
phi.getIncomings().remove(i--);
}
}

View File

@ -62,6 +62,13 @@ class ListingLexer {
case -1:
token = ListingToken.EOF;
break;
case '\r':
token = ListingToken.EOL;
nextChar();
if (c == '\n') {
nextChar();
}
break;
case '\n':
token = ListingToken.EOL;
nextChar();

View File

@ -18,6 +18,7 @@ package org.teavm.model;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import org.junit.Assert;
import org.teavm.model.text.ListingParseException;
import org.teavm.model.text.ListingParser;
@ -29,7 +30,7 @@ public final class ListingParseUtils {
public static Program parseFromResource(String resourceName) {
ClassLoader classLoader = ListingParseUtils.class.getClassLoader();
try (InputStream input = classLoader.getResourceAsStream(resourceName);
InputStreamReader reader = new InputStreamReader(input, "UTF-8")) {
InputStreamReader reader = new InputStreamReader(input, StandardCharsets.UTF_8)) {
return new ListingParser().parse(reader);
} catch (IOException e) {
throw new RuntimeException(e);
@ -49,7 +50,7 @@ public final class ListingParseUtils {
private static Location offsetToLocation(int offset, InputStream input) throws IOException {
int row = 0;
int column = 0;
try (InputStreamReader reader = new InputStreamReader(input, "UTF-8")) {
try (InputStreamReader reader = new InputStreamReader(input, StandardCharsets.UTF_8)) {
for (int i = 0; i < offset; ++i) {
int c = reader.read();
if (c == '\n') {