use of com.android.dx.rop.code.ThrowingInsn in project J2ME-Loader by nikita36078.
the class Ropper method addSetupBlocks.
/**
* Constructs and adds the blocks that perform setup for the rest of
* the method. This includes a first block which merely contains
* assignments from parameters to the same-numbered registers and
* a possible second block which deals with synchronization.
*/
private void addSetupBlocks() {
LocalVariableList localVariables = method.getLocalVariables();
SourcePosition pos = method.makeSourcePosistion(0);
Prototype desc = method.getEffectiveDescriptor();
StdTypeList params = desc.getParameterTypes();
int sz = params.size();
InsnList insns = new InsnList(sz + 1);
int at = 0;
for (int i = 0; i < sz; i++) {
Type one = params.get(i);
LocalVariableList.Item local = localVariables.pcAndIndexToLocal(0, at);
RegisterSpec result = (local == null) ? RegisterSpec.make(at, one) : RegisterSpec.makeLocalOptional(at, one, local.getLocalItem());
Insn insn = new PlainCstInsn(Rops.opMoveParam(one), pos, result, RegisterSpecList.EMPTY, CstInteger.make(at));
insns.set(i, insn);
at += one.getCategory();
}
insns.set(sz, new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY));
insns.setImmutable();
boolean synch = isSynchronized();
int label = synch ? getSpecialLabel(SYNCH_SETUP_1) : 0;
BasicBlock bb = new BasicBlock(getSpecialLabel(PARAM_ASSIGNMENT), insns, IntList.makeImmutable(label), label);
addBlock(bb, IntList.EMPTY);
if (synch) {
RegisterSpec synchReg = getSynchReg();
Insn insn;
if (isStatic()) {
insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos, RegisterSpecList.EMPTY, StdTypeList.EMPTY, method.getDefiningClass());
insns = new InsnList(1);
insns.set(0, insn);
} else {
insns = new InsnList(2);
insn = new PlainCstInsn(Rops.MOVE_PARAM_OBJECT, pos, synchReg, RegisterSpecList.EMPTY, CstInteger.VALUE_0);
insns.set(0, insn);
insns.set(1, new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY));
}
int label2 = getSpecialLabel(SYNCH_SETUP_2);
insns.setImmutable();
bb = new BasicBlock(label, insns, IntList.makeImmutable(label2), label2);
addBlock(bb, IntList.EMPTY);
insns = new InsnList(isStatic() ? 2 : 1);
if (isStatic()) {
insns.set(0, new PlainInsn(Rops.opMoveResultPseudo(synchReg), pos, synchReg, RegisterSpecList.EMPTY));
}
insn = new ThrowingInsn(Rops.MONITOR_ENTER, pos, RegisterSpecList.make(synchReg), StdTypeList.EMPTY);
insns.set(isStatic() ? 1 : 0, insn);
insns.setImmutable();
bb = new BasicBlock(label2, insns, IntList.makeImmutable(0), 0);
addBlock(bb, IntList.EMPTY);
}
}
use of com.android.dx.rop.code.ThrowingInsn in project J2ME-Loader by nikita36078.
the class Ropper method addSynchExceptionHandlerBlock.
/**
* Constructs and adds, if necessary, the catch-all exception handler
* block to deal with unwinding the lock taken on entry to a synchronized
* method.
*/
private void addSynchExceptionHandlerBlock() {
if (!synchNeedsExceptionHandler) {
/*
* The method being converted either isn't synchronized or
* can't possibly throw exceptions in its main body, so
* there's no need for a synchronized method exception
* handler.
*/
return;
}
SourcePosition pos = method.makeSourcePosistion(0);
RegisterSpec exReg = RegisterSpec.make(0, Type.THROWABLE);
BasicBlock bb;
Insn insn;
InsnList insns = new InsnList(2);
insn = new PlainInsn(Rops.opMoveException(Type.THROWABLE), pos, exReg, RegisterSpecList.EMPTY);
insns.set(0, insn);
insn = new ThrowingInsn(Rops.MONITOR_EXIT, pos, RegisterSpecList.make(getSynchReg()), StdTypeList.EMPTY);
insns.set(1, insn);
insns.setImmutable();
int label2 = getSpecialLabel(SYNCH_CATCH_2);
bb = new BasicBlock(getSpecialLabel(SYNCH_CATCH_1), insns, IntList.makeImmutable(label2), label2);
addBlock(bb, IntList.EMPTY);
insns = new InsnList(1);
insn = new ThrowingInsn(Rops.THROW, pos, RegisterSpecList.make(exReg), StdTypeList.EMPTY);
insns.set(0, insn);
insns.setImmutable();
bb = new BasicBlock(label2, insns, IntList.EMPTY, -1);
addBlock(bb, IntList.EMPTY);
}
use of com.android.dx.rop.code.ThrowingInsn in project dexmaker by linkedin.
the class Code method op.
/**
* Executes {@code op} and sets {@code target} to the result. For most
* binary operations, the types of {@code a} and {@code b} must be the same.
* Shift operations (like {@link BinaryOp#SHIFT_LEFT}) require {@code b} to
* be an {@code int}, even when {@code a} is a {@code long}.
*/
public <T1, T2> void op(BinaryOp op, Local<T1> target, Local<T1> a, Local<T2> b) {
Rop rop = op.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
RegisterSpecList sources = RegisterSpecList.make(a.spec(), b.spec());
if (rop.getBranchingness() == BRANCH_NONE) {
addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), sources));
} else {
addInstruction(new ThrowingInsn(rop, sourcePosition, sources, catches));
moveResult(target, true);
}
}
use of com.android.dx.rop.code.ThrowingInsn in project dexmaker by linkedin.
the class Code method arrayLength.
// instructions: arrays
/**
* Sets {@code target} to the length of the array in {@code array}.
*/
public <T> void arrayLength(Local<Integer> target, Local<T> array) {
addInstruction(new ThrowingInsn(Rops.ARRAY_LENGTH, sourcePosition, RegisterSpecList.make(array.spec()), catches));
moveResult(target, true);
}
use of com.android.dx.rop.code.ThrowingInsn in project J2ME-Loader by nikita36078.
the class EscapeAnalysis method insertThrowingInsnBefore.
/**
* Inserts a new ThrowingInsn before the given instruction.
* TODO: move this somewhere more appropriate
*
* @param insn {@code non-null;} instruction to insert before
* @param newSources {@code non-null;} sources of new instruction
* @param newResult {@code non-null;} result of new instruction
* @param newOpcode opcode of new instruction
* @param cst {@code null-ok;} constant for new instruction, if any
*/
private void insertThrowingInsnBefore(SsaInsn insn, RegisterSpecList newSources, RegisterSpec newResult, int newOpcode, Constant cst) {
Insn origRopInsn = insn.getOriginalRopInsn();
Rop newRop = Rops.ropFor(newOpcode, newResult, newSources, cst);
Insn newRopInsn;
if (cst == null) {
newRopInsn = new ThrowingInsn(newRop, origRopInsn.getPosition(), newSources, StdTypeList.EMPTY);
} else {
newRopInsn = new ThrowingCstInsn(newRop, origRopInsn.getPosition(), newSources, StdTypeList.EMPTY, cst);
}
NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());
List<SsaInsn> insns = insn.getBlock().getInsns();
insns.add(insns.lastIndexOf(insn), newInsn);
ssaMeth.onInsnAdded(newInsn);
}
Aggregations