use of org.objectweb.asm.tree.analysis.BasicValue in project quasar by puniverse.
the class InstrumentMethod method emitStoreState.
private void emitStoreState(MethodVisitor mv, int idx, FrameInfo fi, int numArgsToPreserve) {
if (idx > Stack.MAX_ENTRY)
throw new IllegalArgumentException("Entry index (PC) " + idx + " greater than maximum of " + Stack.MAX_ENTRY + " in " + className + "." + mn.name + mn.desc);
if (fi.numSlots > Stack.MAX_SLOTS)
throw new IllegalArgumentException("Number of slots required " + fi.numSlots + " greater than maximum of " + Stack.MAX_SLOTS + " in " + className + "." + mn.name + mn.desc);
Frame f = frames[fi.endInstruction];
if (fi.lBefore != null)
fi.lBefore.accept(mv);
mv.visitVarInsn(Opcodes.ALOAD, lvarStack);
emitConst(mv, idx);
emitConst(mv, fi.numSlots);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, STACK_NAME, "pushMethod", "(II)V", false);
// store operand stack
for (int i = f.getStackSize(); i-- > 0; ) {
BasicValue v = (BasicValue) f.getStack(i);
if (!isOmitted(v)) {
if (!isNullType(v)) {
int slotIdx = fi.stackSlotIndices[i];
assert slotIdx >= 0 && slotIdx < fi.numSlots;
emitStoreValue(mv, v, lvarStack, slotIdx, -1);
} else {
db.log(LogLevel.DEBUG, "NULL stack entry: type=%s size=%d", v.getType(), v.getSize());
mv.visitInsn(Opcodes.POP);
}
}
}
// store local vars
for (int i = firstLocal; i < f.getLocals(); i++) {
BasicValue v = (BasicValue) f.getLocal(i);
if (!isNullType(v)) {
mv.visitVarInsn(v.getType().getOpcode(Opcodes.ILOAD), i);
int slotIdx = fi.localSlotIndices[i];
assert slotIdx >= 0 && slotIdx < fi.numSlots;
emitStoreValue(mv, v, lvarStack, slotIdx, i);
}
}
// restore last numArgsToPreserve operands
for (int i = f.getStackSize() - numArgsToPreserve; i < f.getStackSize(); i++) {
BasicValue v = (BasicValue) f.getStack(i);
if (!isOmitted(v)) {
if (!isNullType(v)) {
int slotIdx = fi.stackSlotIndices[i];
assert slotIdx >= 0 && slotIdx < fi.numSlots;
emitRestoreValue(mv, v, lvarStack, slotIdx, -1);
} else
mv.visitInsn(Opcodes.ACONST_NULL);
}
}
}
use of org.objectweb.asm.tree.analysis.BasicValue in project quasar by puniverse.
the class InstrumentMethod method emitNewAndDup.
/*
private static void emitConst(MethodVisitor mv, String value) {
mv.visitLdcInsn(value);
}
*/
private void emitNewAndDup(MethodVisitor mv, Frame frame, int stackIndex, MethodInsnNode min) {
/*
* This method, and the entire NewValue business has to do with dealing with the following case:
*
* new Foo(suspendableCall())
*
* I.e. when the suspendable call is passed as an argument to the constructor. The emitted code may be:
*
* NEW Foo
* DUP
* INVOKEVIRTUAL suspendableCall
* INVOKESPECIAL Foo.<init>
*
* Which means that the suspension points is after NEW, leaving the object in an uninitialized state which the verifier rejects.
* This method rewrites it to be:
*
* INVOKEVIRTUAL suspendableCall
* ASTORE X
* NEW Foo
* DUP
* ALOAD X
* INVOKESPECIAL Foo.<init>
*
*/
int arguments = frame.getStackSize() - stackIndex - 1;
int neededLocals = 0;
for (int i = arguments; i >= 1; i--) {
BasicValue v = (BasicValue) frame.getStack(stackIndex + i);
mv.visitVarInsn(v.getType().getOpcode(Opcodes.ISTORE), lvarStack + NUM_LOCALS + neededLocals);
neededLocals += v.getSize();
}
if (additionalLocals < neededLocals)
additionalLocals = neededLocals;
db.log(LogLevel.DEBUG, "Inserting NEW & DUP for constructor call %s%s with %d arguments (%d locals)", min.owner, min.desc, arguments, neededLocals);
((NewValue) frame.getStack(stackIndex - 1)).insn.accept(mv);
((NewValue) frame.getStack(stackIndex)).insn.accept(mv);
for (int i = 1; i <= arguments; i++) {
BasicValue v = (BasicValue) frame.getStack(stackIndex + i);
neededLocals -= v.getSize();
mv.visitVarInsn(v.getType().getOpcode(Opcodes.ILOAD), lvarStack + NUM_LOCALS + neededLocals);
}
}
use of org.objectweb.asm.tree.analysis.BasicValue in project flink by apache.
the class NestedMethodAnalyzer method invokeNestedMethod.
@SuppressWarnings("unchecked")
private TaggedValue invokeNestedMethod(List<? extends BasicValue> values, final MethodInsnNode methodInsn) throws AnalyzerException {
final Object[] mn = findMethodNode(methodInsn.owner, methodInsn.name, methodInsn.desc);
MethodNode methodNode = (MethodNode) mn[0];
// recursion
if (methodNode.name.equals(this.methodNode.name) && methodNode.desc.equals(this.methodNode.desc)) {
// return the values that are present so far
return mergeReturnValues(returnValues);
}
final NestedMethodAnalyzer nma = new NestedMethodAnalyzer(analyzer, (String) mn[1], (MethodNode) mn[0], (List<BasicValue>) values, remainingNesting - 1, topLevelMethod && isBridgeMethod());
return nma.analyze();
}
use of org.objectweb.asm.tree.analysis.BasicValue in project bytecode-viewer by Konloch.
the class CheckClassAdapter method verify.
/**
* Checks a given class.
*
* @param cr
* a <code>ClassReader</code> that contains bytecode for the
* analysis.
* @param loader
* a <code>ClassLoader</code> which will be used to load
* referenced classes. This is useful if you are verifiying
* multiple interdependent classes.
* @param dump
* true if bytecode should be printed out not only when errors
* are found.
* @param pw
* write where results going to be printed
*/
public static void verify(final ClassReader cr, final ClassLoader loader, final boolean dump, final PrintWriter pw) {
ClassNode cn = new ClassNode();
cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG);
Type syperType = cn.superName == null ? null : Type.getObjectType(cn.superName);
List<MethodNode> methods = cn.methods;
List<Type> interfaces = new ArrayList<Type>();
for (Iterator<String> i = cn.interfaces.iterator(); i.hasNext(); ) {
interfaces.add(Type.getObjectType(i.next()));
}
for (int i = 0; i < methods.size(); ++i) {
MethodNode method = methods.get(i);
SimpleVerifier verifier = new SimpleVerifier(Type.getObjectType(cn.name), syperType, interfaces, (cn.access & Opcodes.ACC_INTERFACE) != 0);
Analyzer<BasicValue> a = new Analyzer<BasicValue>(verifier);
if (loader != null) {
verifier.setClassLoader(loader);
}
try {
a.analyze(cn.name, method);
if (!dump) {
continue;
}
} catch (Exception e) {
e.printStackTrace(pw);
}
printAnalyzerResult(method, a, pw);
}
pw.flush();
}
use of org.objectweb.asm.tree.analysis.BasicValue in project drill by apache.
the class ReplacingInterpreter method unaryOperation.
@Override
public BasicValue unaryOperation(final AbstractInsnNode insn, final BasicValue value) throws AnalyzerException {
/*
* We're looking for the assignment of an operator member variable that's a holder to a local
* objectref. If we spot that, we can't replace the local objectref (at least not
* until we do the work to replace member variable holders).
*
* Note that a GETFIELD does not call newValue(), as would happen for a local variable, so we're
* emulating that here.
*/
if ((insn.getOpcode() == Opcodes.GETFIELD) && (value instanceof ReplacingBasicValue)) {
final ReplacingBasicValue possibleThis = (ReplacingBasicValue) value;
if (possibleThis.isThis()) {
final FieldInsnNode fieldInsn = (FieldInsnNode) insn;
if (HOLDERS.get(fieldInsn.desc) != null) {
final BasicValue fetchedField = super.unaryOperation(insn, value);
final ReplacingBasicValue replacingValue = ReplacingBasicValue.create(fetchedField.getType(), null, -1, valueList);
replacingValue.setAssignedToMember();
return replacingValue;
}
}
}
return super.unaryOperation(insn, value);
}
Aggregations