mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-31 12:24:10 -08:00
Adds method to copy program
This commit is contained in:
parent
a5ff1cf5a8
commit
559cf989ba
|
@ -17,9 +17,8 @@ package org.teavm.model.util;
|
||||||
|
|
||||||
import org.teavm.common.Graph;
|
import org.teavm.common.Graph;
|
||||||
import org.teavm.common.GraphBuilder;
|
import org.teavm.common.GraphBuilder;
|
||||||
import org.teavm.model.BasicBlock;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.Instruction;
|
import org.teavm.model.instructions.*;
|
||||||
import org.teavm.model.Program;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -43,4 +42,331 @@ public class ProgramUtils {
|
||||||
}
|
}
|
||||||
return graphBuilder.build();
|
return graphBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Program copy(Program program) {
|
||||||
|
Program copy = new Program();
|
||||||
|
CopyVisitor insnCopier = new CopyVisitor();
|
||||||
|
insnCopier.programCopy = copy;
|
||||||
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
|
program.createVariable();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
program.createBasicBlock();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
BasicBlock blockCopy = copy.basicBlockAt(i);
|
||||||
|
for (Instruction insn : block.getInstructions()) {
|
||||||
|
insn.acceptVisitor(insnCopier);
|
||||||
|
blockCopy.getInstructions().add(insnCopier.copy);
|
||||||
|
}
|
||||||
|
for (Phi phi : block.getPhis()) {
|
||||||
|
Phi phiCopy = new Phi();
|
||||||
|
phiCopy.setReceiver(copy.variableAt(phi.getReceiver().getIndex()));
|
||||||
|
for (Incoming incoming : phi.getIncomings()) {
|
||||||
|
Incoming incomingCopy = new Incoming();
|
||||||
|
incomingCopy.setSource(copy.basicBlockAt(incoming.getSource().getIndex()));
|
||||||
|
incomingCopy.setValue(copy.variableAt(incoming.getValue().getIndex()));
|
||||||
|
phiCopy.getIncomings().add(incomingCopy);
|
||||||
|
}
|
||||||
|
blockCopy.getPhis().add(phiCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CopyVisitor implements InstructionVisitor {
|
||||||
|
Instruction copy;
|
||||||
|
Program programCopy;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(EmptyInstruction insn) {
|
||||||
|
copy = new EmptyInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Variable copyVar(Variable var) {
|
||||||
|
return programCopy.variableAt(var.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
private BasicBlock copyBlock(BasicBlock block) {
|
||||||
|
return programCopy.basicBlockAt(block.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ClassConstantInstruction insn) {
|
||||||
|
ClassConstantInstruction insnCopy = new ClassConstantInstruction();
|
||||||
|
insnCopy.setConstant(insn.getConstant());
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(NullConstantInstruction insn) {
|
||||||
|
NullConstantInstruction insnCopy = new NullConstantInstruction();
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(IntegerConstantInstruction insn) {
|
||||||
|
IntegerConstantInstruction insnCopy = new IntegerConstantInstruction();
|
||||||
|
insnCopy.setConstant(insn.getConstant());
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LongConstantInstruction insn) {
|
||||||
|
LongConstantInstruction insnCopy = new LongConstantInstruction();
|
||||||
|
insnCopy.setConstant(insn.getConstant());
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(FloatConstantInstruction insn) {
|
||||||
|
FloatConstantInstruction insnCopy = new FloatConstantInstruction();
|
||||||
|
insnCopy.setConstant(insn.getConstant());
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(DoubleConstantInstruction insn) {
|
||||||
|
DoubleConstantInstruction insnCopy = new DoubleConstantInstruction();
|
||||||
|
insnCopy.setConstant(insn.getConstant());
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(StringConstantInstruction insn) {
|
||||||
|
StringConstantInstruction insnCopy = new StringConstantInstruction();
|
||||||
|
insnCopy.setConstant(insn.getConstant());
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BinaryInstruction insn) {
|
||||||
|
BinaryInstruction insnCopy = new BinaryInstruction(insn.getOperation(), insn.getOperandType());
|
||||||
|
insnCopy.setFirstOperand(copyVar(insn.getFirstOperand()));
|
||||||
|
insnCopy.setSecondOperand(copyVar(insn.getSecondOperand()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(NegateInstruction insn) {
|
||||||
|
NegateInstruction insnCopy = new NegateInstruction(insn.getOperandType());
|
||||||
|
insnCopy.setOperand(copyVar(insn.getOperand()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(AssignInstruction insn) {
|
||||||
|
AssignInstruction insnCopy = new AssignInstruction();
|
||||||
|
insnCopy.setAssignee(copyVar(insn.getAssignee()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CastInstruction insn) {
|
||||||
|
CastInstruction insnCopy = new CastInstruction();
|
||||||
|
insnCopy.setValue(copyVar(insn.getValue()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
insnCopy.setTargetType(insn.getTargetType());
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CastNumberInstruction insn) {
|
||||||
|
CastNumberInstruction insnCopy = new CastNumberInstruction(insn.getSourceType(), insn.getTargetType());
|
||||||
|
insnCopy.setValue(copyVar(insn.getValue()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CastIntegerInstruction insn) {
|
||||||
|
CastIntegerInstruction insnCopy = new CastIntegerInstruction(insn.getTargetType(), insn.getDirection());
|
||||||
|
insnCopy.setValue(copyVar(insn.getValue()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BranchingInstruction insn) {
|
||||||
|
BranchingInstruction insnCopy = new BranchingInstruction(insn.getCondition());
|
||||||
|
insnCopy.setOperand(copyVar(insn.getOperand()));
|
||||||
|
insnCopy.setConsequent(copyBlock(insn.getConsequent()));
|
||||||
|
insnCopy.setAlternative(copyBlock(insn.getAlternative()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(BinaryBranchingInstruction insn) {
|
||||||
|
BinaryBranchingInstruction insnCopy = new BinaryBranchingInstruction(insn.getCondition());
|
||||||
|
insnCopy.setFirstOperand(copyVar(insn.getFirstOperand()));
|
||||||
|
insnCopy.setSecondOperand(copyVar(insn.getSecondOperand()));
|
||||||
|
insnCopy.setConsequent(copyBlock(insn.getConsequent()));
|
||||||
|
insnCopy.setAlternative(copyBlock(insn.getAlternative()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(JumpInstruction insn) {
|
||||||
|
JumpInstruction insnCopy = new JumpInstruction();
|
||||||
|
insnCopy.setTarget(copyBlock(insn.getTarget()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(SwitchInstruction insn) {
|
||||||
|
SwitchInstruction insnCopy = new SwitchInstruction();
|
||||||
|
insnCopy.setCondition(copyVar(insn.getCondition()));
|
||||||
|
insnCopy.setDefaultTarget(copyBlock(insn.getDefaultTarget()));
|
||||||
|
for (SwitchTableEntry entry : insn.getEntries()) {
|
||||||
|
SwitchTableEntry entryCopy = new SwitchTableEntry();
|
||||||
|
entryCopy.setCondition(entry.getCondition());
|
||||||
|
entryCopy.setTarget(copyBlock(entry.getTarget()));
|
||||||
|
insnCopy.getEntries().add(entryCopy);
|
||||||
|
}
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ExitInstruction insn) {
|
||||||
|
ExitInstruction insnCopy = new ExitInstruction();
|
||||||
|
insnCopy.setValueToReturn(insn.getValueToReturn() != null ? copyVar(insn.getValueToReturn()) : null);
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RaiseInstruction insn) {
|
||||||
|
RaiseInstruction insnCopy = new RaiseInstruction();
|
||||||
|
insnCopy.setException(copyVar(insn.getException()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ConstructArrayInstruction insn) {
|
||||||
|
ConstructArrayInstruction insnCopy = new ConstructArrayInstruction();
|
||||||
|
insnCopy.setItemType(insn.getItemType());
|
||||||
|
insnCopy.setSize(copyVar(insn.getSize()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ConstructInstruction insn) {
|
||||||
|
ConstructInstruction insnCopy = new ConstructInstruction();
|
||||||
|
insnCopy.setType(insn.getType());
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ConstructMultiArrayInstruction insn) {
|
||||||
|
ConstructMultiArrayInstruction insnCopy = new ConstructMultiArrayInstruction();
|
||||||
|
insnCopy.setItemType(insn.getItemType());
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
for (Variable dim : insn.getDimensions()) {
|
||||||
|
insnCopy.getDimensions().add(copyVar(dim));
|
||||||
|
}
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(GetFieldInstruction insn) {
|
||||||
|
GetFieldInstruction insnCopy = new GetFieldInstruction();
|
||||||
|
insnCopy.setField(insn.getField());
|
||||||
|
insnCopy.setFieldType(insn.getFieldType());
|
||||||
|
insnCopy.setInstance(insn.getInstance() != null ? copyVar(insn.getInstance()) : null);
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PutFieldInstruction insn) {
|
||||||
|
PutFieldInstruction insnCopy = new PutFieldInstruction();
|
||||||
|
insnCopy.setField(insn.getField());
|
||||||
|
insnCopy.setInstance(insn.getInstance() != null ? copyVar(insn.getInstance()) : null);
|
||||||
|
insnCopy.setValue(copyVar(insn.getValue()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ArrayLengthInstruction insn) {
|
||||||
|
ArrayLengthInstruction insnCopy = new ArrayLengthInstruction();
|
||||||
|
insnCopy.setArray(copyVar(insn.getArray()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(CloneArrayInstruction insn) {
|
||||||
|
CloneArrayInstruction insnCopy = new CloneArrayInstruction();
|
||||||
|
insnCopy.setArray(copyVar(insn.getArray()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(UnwrapArrayInstruction insn) {
|
||||||
|
UnwrapArrayInstruction insnCopy = new UnwrapArrayInstruction(insn.getElementType());
|
||||||
|
insnCopy.setArray(copyVar(insn.getArray()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(GetElementInstruction insn) {
|
||||||
|
GetElementInstruction insnCopy = new GetElementInstruction();
|
||||||
|
insnCopy.setArray(copyVar(insn.getArray()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
insnCopy.setIndex(copyVar(insn.getIndex()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PutElementInstruction insn) {
|
||||||
|
PutElementInstruction insnCopy = new PutElementInstruction();
|
||||||
|
insnCopy.setArray(copyVar(insn.getArray()));
|
||||||
|
insnCopy.setValue(copyVar(insn.getValue()));
|
||||||
|
insnCopy.setIndex(copyVar(insn.getIndex()));
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(InvokeInstruction insn) {
|
||||||
|
InvokeInstruction insnCopy = new InvokeInstruction();
|
||||||
|
insnCopy.setMethod(insn.getMethod());
|
||||||
|
insnCopy.setType(insn.getType());
|
||||||
|
insnCopy.setInstance(insn.getInstance() != null ? copyVar(insn.getInstance()) : null);
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
for (Variable arg : insn.getArguments()) {
|
||||||
|
insnCopy.getArguments().add(copyVar(arg));
|
||||||
|
}
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(IsInstanceInstruction insn) {
|
||||||
|
IsInstanceInstruction insnCopy = new IsInstanceInstruction();
|
||||||
|
insnCopy.setValue(copyVar(insn.getValue()));
|
||||||
|
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
||||||
|
insnCopy.setType(insn.getType());
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(InitClassInstruction insn) {
|
||||||
|
InitClassInstruction insnCopy = new InitClassInstruction();
|
||||||
|
insnCopy.setClassName(insn.getClassName());
|
||||||
|
copy = insnCopy;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user