mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -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);
|
TryCatchBlock tryCatch = tryCatchBlocks.remove(index);
|
||||||
tryCatch.protectedBlocks.remove(BasicBlock.this);
|
tryCatch.protectedBlocks.remove(BasicBlock.this);
|
||||||
return tryCatch;
|
return tryCatch;
|
||||||
};
|
}
|
||||||
@Override public TryCatchBlock set(int index, TryCatchBlock element) {
|
@Override public TryCatchBlock set(int index, TryCatchBlock element) {
|
||||||
TryCatchBlock oldTryCatch = tryCatchBlocks.get(index);
|
TryCatchBlock oldTryCatch = tryCatchBlocks.get(index);
|
||||||
if (oldTryCatch == element) {
|
if (oldTryCatch == element) {
|
||||||
|
@ -220,13 +220,13 @@ public class BasicBlock implements BasicBlockReader {
|
||||||
element.protectedBlocks.add(BasicBlock.this);
|
element.protectedBlocks.add(BasicBlock.this);
|
||||||
tryCatchBlocks.set(index, element);
|
tryCatchBlocks.set(index, element);
|
||||||
return oldTryCatch;
|
return oldTryCatch;
|
||||||
};
|
}
|
||||||
@Override public void clear() {
|
@Override public void clear() {
|
||||||
for (TryCatchBlock tryCatch : tryCatchBlocks) {
|
for (TryCatchBlock tryCatch : tryCatchBlocks) {
|
||||||
tryCatch.protectedBlocks.remove(BasicBlock.this);
|
tryCatch.protectedBlocks.remove(BasicBlock.this);
|
||||||
}
|
}
|
||||||
tryCatchBlocks.clear();
|
tryCatchBlocks.clear();
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public List<TryCatchBlock> getTryCatchBlocks() {
|
public List<TryCatchBlock> getTryCatchBlocks() {
|
||||||
|
|
|
@ -48,6 +48,11 @@ public class ListingBuilder {
|
||||||
block.readInstruction(j, stringifier);
|
block.readInstruction(j, stringifier);
|
||||||
sb.append("\n");
|
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();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model.util;
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import org.teavm.common.Graph;
|
import org.teavm.common.Graph;
|
||||||
import org.teavm.common.GraphBuilder;
|
import org.teavm.common.GraphBuilder;
|
||||||
import org.teavm.model.*;
|
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();
|
return graphBuilder.build();
|
||||||
}
|
}
|
||||||
|
@ -53,6 +58,7 @@ public class ProgramUtils {
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
copy.createBasicBlock();
|
copy.createBasicBlock();
|
||||||
}
|
}
|
||||||
|
Map<TryCatchBlock, TryCatchBlock> tryCatchCopies = new HashMap<>();
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
BasicBlock blockCopy = copy.basicBlockAt(i);
|
BasicBlock blockCopy = copy.basicBlockAt(i);
|
||||||
|
@ -71,6 +77,16 @@ public class ProgramUtils {
|
||||||
}
|
}
|
||||||
blockCopy.getPhis().add(phiCopy);
|
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;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.optimization;
|
||||||
|
|
||||||
import org.teavm.model.BasicBlock;
|
import org.teavm.model.BasicBlock;
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
|
import org.teavm.model.TryCatchBlock;
|
||||||
import org.teavm.model.util.InstructionTransitionExtractor;
|
import org.teavm.model.util.InstructionTransitionExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +45,9 @@ public class UnreachableBasicBlockEliminator {
|
||||||
for (BasicBlock successor : transitionExtractor.getTargets()) {
|
for (BasicBlock successor : transitionExtractor.getTargets()) {
|
||||||
stack[top++] = successor.getIndex();
|
stack[top++] = successor.getIndex();
|
||||||
}
|
}
|
||||||
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
|
stack[top++] = tryCatch.getHandler().getIndex();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < reachable.length; ++i) {
|
for (int i = 0; i < reachable.length; ++i) {
|
||||||
if (!reachable[i]) {
|
if (!reachable[i]) {
|
||||||
|
|
|
@ -17,10 +17,7 @@ package org.teavm.parsing;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
import org.objectweb.asm.tree.*;
|
||||||
import org.objectweb.asm.tree.InsnList;
|
|
||||||
import org.objectweb.asm.tree.LabelNode;
|
|
||||||
import org.objectweb.asm.tree.MethodNode;
|
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.instructions.*;
|
import org.teavm.model.instructions.*;
|
||||||
import org.teavm.model.util.InstructionTransitionExtractor;
|
import org.teavm.model.util.InstructionTransitionExtractor;
|
||||||
|
@ -170,8 +167,7 @@ public class ProgramParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetInstructions = new ArrayList<>(instructions.size());
|
targetInstructions = new ArrayList<>(instructions.size());
|
||||||
targetInstructions.addAll(Collections.<List<Instruction>>nCopies(
|
targetInstructions.addAll(Collections.<List<Instruction>>nCopies(instructions.size(), null));
|
||||||
instructions.size(), null));
|
|
||||||
basicBlocks.addAll(Collections.<BasicBlock>nCopies(instructions.size(), null));
|
basicBlocks.addAll(Collections.<BasicBlock>nCopies(instructions.size(), null));
|
||||||
stackBefore = new StackFrame[instructions.size()];
|
stackBefore = new StackFrame[instructions.size()];
|
||||||
stackAfter = new StackFrame[instructions.size()];
|
stackAfter = new StackFrame[instructions.size()];
|
||||||
|
@ -180,6 +176,10 @@ public class ProgramParser {
|
||||||
private void doAnalyze(MethodNode method) {
|
private void doAnalyze(MethodNode method) {
|
||||||
InsnList instructions = method.instructions;
|
InsnList instructions = method.instructions;
|
||||||
Deque<Step> workStack = new ArrayDeque<>();
|
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));
|
workStack.push(new Step(-1, 0));
|
||||||
while (!workStack.isEmpty()) {
|
while (!workStack.isEmpty()) {
|
||||||
Step step = workStack.pop();
|
Step step = workStack.pop();
|
||||||
|
@ -187,7 +187,18 @@ public class ProgramParser {
|
||||||
if (stackBefore[index] != null) {
|
if (stackBefore[index] != null) {
|
||||||
continue;
|
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;
|
stackBefore[index] = stack;
|
||||||
nextIndexes = new int[] { index + 1 };
|
nextIndexes = new int[] { index + 1 };
|
||||||
instructions.get(index).accept(methodVisitor);
|
instructions.get(index).accept(methodVisitor);
|
||||||
|
@ -200,6 +211,23 @@ public class ProgramParser {
|
||||||
workStack.push(new Step(index, next));
|
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() {
|
private void assemble() {
|
||||||
|
|
|
@ -131,6 +131,9 @@ public class SSATransformer {
|
||||||
for (Instruction insn : currentBlock.getInstructions()) {
|
for (Instruction insn : currentBlock.getInstructions()) {
|
||||||
insn.acceptVisitor(consumer);
|
insn.acceptVisitor(consumer);
|
||||||
}
|
}
|
||||||
|
for (TryCatchBlock tryCatch : currentBlock.getTryCatchBlocks()) {
|
||||||
|
define(tryCatch.getExceptionVariable());
|
||||||
|
}
|
||||||
int[] successors = domGraph.outgoingEdges(currentBlock.getIndex());
|
int[] successors = domGraph.outgoingEdges(currentBlock.getIndex());
|
||||||
for (int i = 0; i < successors.length; ++i) {
|
for (int i = 0; i < successors.length; ++i) {
|
||||||
Task next = new Task();
|
Task next = new Task();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user