mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Parser supports try/catch blocks
This commit is contained in:
parent
d5fac392d3
commit
de245613c4
|
@ -207,7 +207,7 @@ public class BasicBlock implements BasicBlockReader {
|
|||
TryCatchBlock tryCatch = tryCatchBlocks.remove(index);
|
||||
tryCatch.protectedBlocks.remove(BasicBlock.this);
|
||||
return tryCatch;
|
||||
};
|
||||
}
|
||||
@Override public TryCatchBlock set(int index, TryCatchBlock element) {
|
||||
TryCatchBlock oldTryCatch = tryCatchBlocks.get(index);
|
||||
if (oldTryCatch == element) {
|
||||
|
@ -220,13 +220,13 @@ public class BasicBlock implements BasicBlockReader {
|
|||
element.protectedBlocks.add(BasicBlock.this);
|
||||
tryCatchBlocks.set(index, element);
|
||||
return oldTryCatch;
|
||||
};
|
||||
}
|
||||
@Override public void clear() {
|
||||
for (TryCatchBlock tryCatch : tryCatchBlocks) {
|
||||
tryCatch.protectedBlocks.remove(BasicBlock.this);
|
||||
}
|
||||
tryCatchBlocks.clear();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
public List<TryCatchBlock> getTryCatchBlocks() {
|
||||
|
|
|
@ -48,6 +48,11 @@ public class ListingBuilder {
|
|||
block.readInstruction(j, stringifier);
|
||||
sb.append("\n");
|
||||
}
|
||||
for (TryCatchBlockReader tryCatch : block.readTryCatchBlocks()) {
|
||||
sb.append(prefix).append(" catch ").append(tryCatch.getExceptionType()).append(" @")
|
||||
.append(tryCatch.getExceptionVariable().getIndex())
|
||||
.append(" -> $").append(tryCatch.getHandler().getIndex()).append("\n");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*/
|
||||
package org.teavm.model.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.teavm.common.Graph;
|
||||
import org.teavm.common.GraphBuilder;
|
||||
import org.teavm.model.*;
|
||||
|
@ -39,6 +41,9 @@ public class ProgramUtils {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||
graphBuilder.addEdge(i, tryCatch.getHandler().getIndex());
|
||||
}
|
||||
}
|
||||
return graphBuilder.build();
|
||||
}
|
||||
|
@ -53,6 +58,7 @@ public class ProgramUtils {
|
|||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
copy.createBasicBlock();
|
||||
}
|
||||
Map<TryCatchBlock, TryCatchBlock> tryCatchCopies = new HashMap<>();
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
BasicBlock block = program.basicBlockAt(i);
|
||||
BasicBlock blockCopy = copy.basicBlockAt(i);
|
||||
|
@ -71,6 +77,16 @@ public class ProgramUtils {
|
|||
}
|
||||
blockCopy.getPhis().add(phiCopy);
|
||||
}
|
||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||
TryCatchBlock tryCatchCopy = tryCatchCopies.get(tryCatch);
|
||||
if (tryCatchCopy == null) {
|
||||
tryCatchCopy = new TryCatchBlock();
|
||||
tryCatchCopy.setExceptionType(tryCatchCopy.getExceptionType());
|
||||
tryCatchCopy.setHandler(copy.basicBlockAt(tryCatch.getHandler().getIndex()));
|
||||
tryCatchCopies.put(tryCatch, tryCatchCopy);
|
||||
}
|
||||
blockCopy.getTryCatchBlocks().add(tryCatchCopy);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.optimization;
|
|||
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.TryCatchBlock;
|
||||
import org.teavm.model.util.InstructionTransitionExtractor;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +45,9 @@ public class UnreachableBasicBlockEliminator {
|
|||
for (BasicBlock successor : transitionExtractor.getTargets()) {
|
||||
stack[top++] = successor.getIndex();
|
||||
}
|
||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||
stack[top++] = tryCatch.getHandler().getIndex();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < reachable.length; ++i) {
|
||||
if (!reachable[i]) {
|
||||
|
|
|
@ -17,10 +17,7 @@ package org.teavm.parsing;
|
|||
|
||||
import java.util.*;
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.LabelNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.model.instructions.*;
|
||||
import org.teavm.model.util.InstructionTransitionExtractor;
|
||||
|
@ -170,8 +167,7 @@ public class ProgramParser {
|
|||
}
|
||||
}
|
||||
targetInstructions = new ArrayList<>(instructions.size());
|
||||
targetInstructions.addAll(Collections.<List<Instruction>>nCopies(
|
||||
instructions.size(), null));
|
||||
targetInstructions.addAll(Collections.<List<Instruction>>nCopies(instructions.size(), null));
|
||||
basicBlocks.addAll(Collections.<BasicBlock>nCopies(instructions.size(), null));
|
||||
stackBefore = new StackFrame[instructions.size()];
|
||||
stackAfter = new StackFrame[instructions.size()];
|
||||
|
@ -180,6 +176,10 @@ public class ProgramParser {
|
|||
private void doAnalyze(MethodNode method) {
|
||||
InsnList instructions = method.instructions;
|
||||
Deque<Step> workStack = new ArrayDeque<>();
|
||||
for (Object obj : method.tryCatchBlocks) {
|
||||
TryCatchBlockNode tryCatchNode = (TryCatchBlockNode)obj;
|
||||
workStack.push(new Step(-2, labelIndexes.get(tryCatchNode.handler.getLabel())));
|
||||
}
|
||||
workStack.push(new Step(-1, 0));
|
||||
while (!workStack.isEmpty()) {
|
||||
Step step = workStack.pop();
|
||||
|
@ -187,7 +187,18 @@ public class ProgramParser {
|
|||
if (stackBefore[index] != null) {
|
||||
continue;
|
||||
}
|
||||
stack = step.source != -1 ? stackAfter[step.source] : new StackFrame(minLocal + method.maxLocals - 1);
|
||||
switch (step.source) {
|
||||
case -1:
|
||||
stack = new StackFrame(minLocal + method.maxLocals - 1);
|
||||
break;
|
||||
case -2:
|
||||
stack = new StackFrame(minLocal + method.maxLocals - 1);
|
||||
pushSingle();
|
||||
break;
|
||||
default:
|
||||
stack = stackAfter[step.source];
|
||||
break;
|
||||
}
|
||||
stackBefore[index] = stack;
|
||||
nextIndexes = new int[] { index + 1 };
|
||||
instructions.get(index).accept(methodVisitor);
|
||||
|
@ -200,6 +211,23 @@ public class ProgramParser {
|
|||
workStack.push(new Step(index, next));
|
||||
}
|
||||
}
|
||||
for (Object obj : method.tryCatchBlocks) {
|
||||
TryCatchBlockNode tryCatchNode = (TryCatchBlockNode)obj;
|
||||
TryCatchBlock tryCatch = new TryCatchBlock();
|
||||
tryCatch.setExceptionType(tryCatchNode.type.replace('/', '.'));
|
||||
tryCatch.setHandler(getBasicBlock(labelIndexes.get(tryCatchNode.handler.getLabel())));
|
||||
tryCatch.setExceptionVariable(getVariable(minLocal + method.maxLocals));
|
||||
int start = labelIndexes.get(tryCatchNode.start.getLabel());
|
||||
int end = labelIndexes.get(tryCatchNode.end.getLabel());
|
||||
getBasicBlock(start);
|
||||
getBasicBlock(end);
|
||||
for (int i = start; i < end; ++i) {
|
||||
BasicBlock block = basicBlocks.get(i);
|
||||
if (block != null) {
|
||||
block.getTryCatchBlocks().add(tryCatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void assemble() {
|
||||
|
|
|
@ -131,6 +131,9 @@ public class SSATransformer {
|
|||
for (Instruction insn : currentBlock.getInstructions()) {
|
||||
insn.acceptVisitor(consumer);
|
||||
}
|
||||
for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) {
|
||||
define(tryCatch.getExceptionVariable());
|
||||
}
|
||||
int[] successors = domGraph.outgoingEdges(currentBlock.getIndex());
|
||||
for (int i = 0; i < successors.length; ++i) {
|
||||
Task next = new Task();
|
||||
|
|
Loading…
Reference in New Issue
Block a user