use of org.objectweb.asm.tree.JumpInsnNode in project quasar by puniverse.
the class InstrumentMethod method isForwardingToSuspendable.
private boolean isForwardingToSuspendable(int[] susCallsBcis) {
if (susCallsBcis.length != 1)
// we allow exactly one suspendable call
return false;
final int susCallBci = susCallsBcis[0];
final AbstractInsnNode susCall = mn.instructions.get(susCallBci);
assert isSuspendableCall(db, susCall);
if (isYieldMethod(getMethodOwner(susCall), getMethodName(susCall)))
// yield calls require instrumentation (to skip the call when resuming)
return false;
if (isReflectInvocation(getMethodOwner(susCall), getMethodName(susCall)))
// Reflective calls require instrumentation to handle SuspendExecution wrapped in InvocationTargetException
return false;
if (hasSuspendableTryCatchBlocksAround(susCallBci))
// Catching `SuspendableExecution needs instrumentation in order to propagate it
return false;
// before suspendable call:
for (int i = 0; i < susCallBci; i++) {
final AbstractInsnNode ins = mn.instructions.get(i);
if (ins.getType() == AbstractInsnNode.METHOD_INSN || ins.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN)
// methods calls might have side effects
return false;
if (ins.getType() == AbstractInsnNode.FIELD_INSN)
// side effects
return false;
if (ins instanceof JumpInsnNode && mn.instructions.indexOf(((JumpInsnNode) ins).label) <= i)
// back branches may be costly, so we'd rather capture state
return false;
if (!db.isAllowMonitors() && (ins.getOpcode() == Opcodes.MONITORENTER || ins.getOpcode() == Opcodes.MONITOREXIT))
// we need collectCodeBlocks to warn about monitors
return false;
}
// after suspendable call
for (int i = susCallBci + 1; i <= mn.instructions.size() - 1; i++) {
final AbstractInsnNode ins = mn.instructions.get(i);
if (ins instanceof JumpInsnNode && mn.instructions.indexOf(((JumpInsnNode) ins).label) <= susCallBci)
// if we jump before the suspendable call we suspend more than once -- need instrumentation
return false;
if (!db.isAllowMonitors() && (ins.getOpcode() == Opcodes.MONITORENTER || ins.getOpcode() == Opcodes.MONITOREXIT))
// we need collectCodeBlocks to warn about monitors
return false;
if (!db.isAllowBlocking() && (ins instanceof MethodInsnNode && blockingCallIdx((MethodInsnNode) ins) != -1))
// we need collectCodeBlocks to warn about blocking calls
return false;
}
return true;
}
use of org.objectweb.asm.tree.JumpInsnNode in project maple-ir by LLVM-but-worse.
the class ReflectiveFunctorFactory method branch.
@Override
public EvaluationFunctor<Boolean> branch(Type lt, Type rt, ConditionalJumpStmt.ComparisonType type) {
Type opType = TypeUtils.resolveBinOpType(lt, rt);
String name = lt.getClassName() + type.name() + rt.getClassName() + "OPTYPE" + opType.getClassName() + "RETbool";
String desc = "(" + lt.getDescriptor() + rt.getDescriptor() + ")Z";
if (cache.containsKey(name)) {
return _get(name);
}
MethodNode m = makeBase(name, desc);
{
InsnList insns = new InsnList();
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(lt), 0));
cast(insns, lt, opType);
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(rt), lt.getSize()));
cast(insns, rt, opType);
LabelNode trueSuccessor = new LabelNode();
if (opType == Type.INT_TYPE) {
insns.add(new JumpInsnNode(Opcodes.IF_ICMPEQ + type.ordinal(), trueSuccessor));
} else if (opType == Type.LONG_TYPE) {
insns.add(new InsnNode(Opcodes.LCMP));
insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
} else if (opType == Type.FLOAT_TYPE) {
insns.add(new InsnNode((type == ConditionalJumpStmt.ComparisonType.LT || type == ConditionalJumpStmt.ComparisonType.LE) ? Opcodes.FCMPL : Opcodes.FCMPG));
insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
} else if (opType == Type.DOUBLE_TYPE) {
insns.add(new InsnNode((type == ConditionalJumpStmt.ComparisonType.LT || type == ConditionalJumpStmt.ComparisonType.LE) ? Opcodes.DCMPL : Opcodes.DCMPG));
insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
} else {
throw new IllegalArgumentException(opType.toString());
}
branchReturn(insns, trueSuccessor);
m.instructions = insns;
}
return buildBridge(m);
}
use of org.objectweb.asm.tree.JumpInsnNode in project flink by apache.
the class ModifiedASMAnalyzer method newControlFlowEdge.
@Override
protected void newControlFlowEdge(int insn, int successor) {
try {
if (jumpModificationState == PRE_STATE) {
jumpModificationState = MOD_STATE;
} else if (jumpModificationState == MOD_STATE) {
// for a later merge
if (jumpModification == IFEQ_MOD) {
final int top = accessField(Analyzer.class, "top").getInt(this);
final int[] queue = (int[]) accessField(Analyzer.class, "queue").get(this);
final int tmp = queue[top - 2];
queue[top - 2] = queue[top - 1];
queue[top - 1] = tmp;
eventInsn = queue[top - 2] - 1;
final InsnList insns = (InsnList) accessField(Analyzer.class, "insns").get(this);
// if yes this is loop structure
if (insns.get(eventInsn) instanceof JumpInsnNode) {
jumpModificationState = WAIT_FOR_INSN_STATE;
} else // no loop -> end of modification
{
jumpModificationState = DO_NOTHING;
}
} else // this modification changes the merge priority of certain frames (the expression part of the IF)
if (jumpModification == IFNE_MOD) {
final Frame[] frames = (Frame[]) accessField(Analyzer.class, "frames").get(this);
final Field indexField = accessField(AbstractInsnNode.class, "index");
final InsnList insns = (InsnList) accessField(Analyzer.class, "insns").get(this);
final AbstractInsnNode gotoInsnn = insns.get(successor - 1);
// check for a loop
if (gotoInsnn instanceof JumpInsnNode) {
jumpModificationState = WAIT_FOR_INSN_STATE;
// sets a merge priority for all instructions (the expression of the IF)
// from the label the goto instruction points to until the evaluation with IFEQ
final int idx = indexField.getInt(accessField(JumpInsnNode.class, "label").get(gotoInsnn));
for (int i = idx; i <= insn; i++) {
((ModifiedASMFrame) frames[i]).mergePriority = true;
}
eventInsn = idx - 2;
} else {
jumpModificationState = DO_NOTHING;
}
}
} else // wait for the goto instruction
if (jumpModificationState == WAIT_FOR_INSN_STATE && insn == eventInsn) {
jumpModificationState = DO_NOTHING;
final Frame[] frames = (Frame[]) accessField(Analyzer.class, "frames").get(this);
// this ensures that local variables are kept
if (jumpModification == IFEQ_MOD) {
interpreter.rightMergePriority = true;
final Field top = accessField(Frame.class, "top");
top.setInt(frames[eventInsn], top.getInt(frames[eventInsn + 1]));
frames[eventInsn + 1].merge(frames[eventInsn], interpreter);
} else // finally set a merge priority for the last instruction of the loop (before the IF expression)
if (jumpModification == IFNE_MOD) {
((ModifiedASMFrame) frames[eventInsn + 1]).mergePriority = true;
}
}
} catch (Exception e) {
throw new CodeAnalyzerException("Unable to do jump modifications.", e);
}
}
use of org.objectweb.asm.tree.JumpInsnNode in project Bookshelf by Darkhax-Minecraft.
the class TransformerEnchantmentHelper method transform.
public static byte[] transform(String name, String transformedName, byte[] classBytes) {
final ClassNode clazz = ASMUtils.createClassFromByteArray(classBytes);
final MethodNode method = METHOD_GET_ENCH_LEVEL.getMethodNode(clazz);
final InsnList n1 = new InsnList();
final LabelNode start = new LabelNode();
n1.add(start);
n1.add(new TypeInsnNode(Opcodes.NEW, "net/darkhax/bookshelf/events/EnchantmentModifierEvent"));
n1.add(new InsnNode(Opcodes.DUP));
n1.add(new VarInsnNode(Opcodes.ALOAD, 0));
n1.add(new VarInsnNode(Opcodes.ALOAD, 1));
n1.add(METHOD_INIT_EVENT.getMethodInsn(Opcodes.INVOKESPECIAL, false));
n1.add(new VarInsnNode(Opcodes.ASTORE, 2));
final LabelNode l1 = new LabelNode();
n1.add(l1);
n1.add(FIELD_EVENT_BUS.getFieldNode(Opcodes.GETSTATIC));
n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
n1.add(METHOD_POST.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
n1.add(new InsnNode(Opcodes.POP));
final LabelNode l2 = new LabelNode();
n1.add(l2);
n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
n1.add(METHOD_CANCELED.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
final LabelNode vanillaLogic = new LabelNode();
n1.add(new JumpInsnNode(Opcodes.IFEQ, vanillaLogic));
final LabelNode l4 = new LabelNode();
n1.add(l4);
n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
n1.add(METHOD_GET_LEVELS.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
n1.add(new InsnNode(Opcodes.IRETURN));
n1.add(vanillaLogic);
method.instructions.insertBefore(method.instructions.getFirst(), n1);
return ASMUtils.createByteArrayFromClass(clazz, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
}
use of org.objectweb.asm.tree.JumpInsnNode in project bytecode-viewer by Konloch.
the class Subroutine method merge.
public boolean merge(final Subroutine subroutine) throws AnalyzerException {
boolean changes = false;
for (int i = 0; i < access.length; ++i) {
if (subroutine.access[i] && !access[i]) {
access[i] = true;
changes = true;
}
}
if (subroutine.start == start) {
for (int i = 0; i < subroutine.callers.size(); ++i) {
JumpInsnNode caller = subroutine.callers.get(i);
if (!callers.contains(caller)) {
callers.add(caller);
changes = true;
}
}
}
return changes;
}
Aggregations