use of org.objectweb.asm.tree.LocalVariableNode in project cassandra by apache.
the class MonitorMethodTransformer method loadParamsAndReturnInvokeCode.
// TODO (cleanup): this _should_ be possible to determine purely from the method signature
int loadParamsAndReturnInvokeCode() {
if (isInstanceMethod)
instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
ListIterator<LocalVariableNode> it = localVariables.listIterator();
while (it.hasNext()) {
LocalVariableNode cur = it.next();
if (cur.index < maxLocalParams) {
if (!isInstanceMethod || cur.index > 0) {
int opcode;
switch(cur.desc.charAt(0)) {
case 'L':
case '[':
opcode = Opcodes.ALOAD;
break;
case 'J':
opcode = Opcodes.LLOAD;
break;
case 'D':
opcode = Opcodes.DLOAD;
break;
case 'F':
opcode = Opcodes.FLOAD;
break;
default:
opcode = Opcodes.ILOAD;
break;
}
instructions.add(new IntInsnNode(opcode, cur.index));
}
}
}
int invokeCode;
if (isInstanceMethod && (access & Opcodes.ACC_PRIVATE) != 0)
invokeCode = Opcodes.INVOKESPECIAL;
else if (isInstanceMethod)
invokeCode = Opcodes.INVOKEVIRTUAL;
else
invokeCode = Opcodes.INVOKESTATIC;
return invokeCode;
}
use of org.objectweb.asm.tree.LocalVariableNode in project dex2jar by pxb1988.
the class InvocationWeaver method wrapper.
public ClassVisitor wrapper(final ClassVisitor cv) {
return new RemappingClassAdapter(cv, remapper) {
Map<MtdInfo, MtdInfo> toCreate = new HashMap<MtdInfo, MtdInfo>();
String clzName;
private MtdInfo newMethodA(int opcode, MtdInfo t, MtdInfo mapTo) {
MtdInfo n = toCreate.get(t);
if (n != null) {
return n;
}
n = new MtdInfo();
n.owner = t.owner;
n.name = buildMethodAName(t.name);
boolean hasThis = opcode != INVOKESTATIC;
if (hasThis) {
Type[] args = Type.getArgumentTypes(t.desc);
Type ret = Type.getReturnType(t.desc);
List<Type> ts = new ArrayList<>(args.length + 1);
ts.add(Type.getType(t.owner));
ts.addAll(Arrays.asList(args));
n.desc = Type.getMethodDescriptor(ret, ts.toArray(new Type[ts.size()]));
} else {
n.desc = t.desc;
}
toCreate.put(t, n);
MethodVisitor mv = cv.visitMethod(ACC_SYNTHETIC | ACC_PRIVATE | ACC_STATIC, n.name, n.desc, null, null);
mv.visitCode();
genMethodACode(opcode, t, mapTo, mv, t);
return n;
}
private void genMethodACode(int opcode, MtdInfo t, MtdInfo mapTo, MethodVisitor mv, MtdInfo src) {
boolean hasThis = opcode != INVOKESTATIC;
Type[] args = Type.getArgumentTypes(t.desc);
Type ret = Type.getReturnType(t.desc);
final int start;
mv.visitTypeInsn(NEW, getCurrentInvocationName());
mv.visitInsn(DUP);
if (hasThis) {
mv.visitVarInsn(ALOAD, 0);
start = 1;
} else {
mv.visitInsn(ACONST_NULL);
start = 0;
}
if (args.length == 0) {
mv.visitInsn(ACONST_NULL);
} else {
mv.visitLdcInsn(args.length);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
for (int i = 0; i < args.length; i++) {
mv.visitInsn(DUP);
mv.visitLdcInsn(i);
mv.visitVarInsn(args[i].getOpcode(ILOAD), i + start);
box(args[i], mv);
mv.visitInsn(AASTORE);
}
}
int nextIdx = callbacks.size();
mv.visitLdcInsn(nextIdx);
mv.visitMethodInsn(INVOKESPECIAL, getCurrentInvocationName(), "<init>", "(Ljava/lang/Object;[Ljava/lang/Object;I)V");
mv.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);
unBox(ret, Type.getReturnType(mapTo.desc), mv);
mv.visitInsn(ret.getOpcode(IRETURN));
mv.visitMaxs(-1, -1);
mv.visitEnd();
Callback cb = new Callback();
cb.idx = nextIdx;
cb.callback = newMethodCallback(opcode, t);
cb.target = src;
cb.isSpecial = opcode == INVOKESPECIAL;
cb.isStatic = opcode == INVOKESTATIC;
callbacks.add(cb);
}
private MtdInfo newMethodCallback(int opcode, MtdInfo t) {
MtdInfo n = new MtdInfo();
n.owner = "L" + className + ";";
n.name = buildCallbackMethodName(t.name);
if (opcode == INVOKESPECIAL || opcode == INVOKESTATIC) {
n.desc = "([Ljava/lang/Object;)Ljava/lang/Object;";
} else {
n.desc = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;";
}
MethodVisitor mv = cv.visitMethod(opcode == INVOKESPECIAL ? ACC_PUBLIC : ACC_PUBLIC | ACC_STATIC, n.name, n.desc, null, null);
mv.visitCode();
int start;
if (opcode != INVOKESTATIC) {
mv.visitVarInsn(ALOAD, 0);
if (opcode != INVOKESPECIAL) {
mv.visitTypeInsn(CHECKCAST, toInternal(t.owner));
}
start = 1;
} else {
start = 0;
}
Type[] args = Type.getArgumentTypes(t.desc);
for (int i = 0; i < args.length; i++) {
mv.visitVarInsn(ALOAD, start);
mv.visitLdcInsn(i);
mv.visitInsn(AALOAD);
unBox(args[i], OBJECT_TYPE, mv);
}
mv.visitMethodInsn(opcode, toInternal(t.owner), t.name, t.desc);
Type ret = Type.getReturnType(t.desc);
box(ret, mv);
mv.visitInsn(ARETURN);
mv.visitMaxs(-1, -1);
mv.visitEnd();
return n;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
clzName = name;
}
public MethodVisitor visitMethod(int access, final String name, String desc, String signature, String[] exceptions) {
final MethodVisitor superMv = superMethodVisitor(access, name, desc, signature, exceptions);
final MtdInfo mapTo = findDefinedTargetMethod("L" + clzName + ";", name, desc);
if (mapTo != null) {
final MtdInfo t1 = new MtdInfo();
t1.owner = "L" + clzName + ";";
t1.name = buildMethodAName(name);
t1.desc = desc;
final MtdInfo t = t1;
final MtdInfo src = new MtdInfo();
src.owner = t.owner;
src.name = name;
src.desc = desc;
return new MethodNode(Opcodes.ASM4, access, name, desc, signature, exceptions) {
@Override
public void visitEnd() {
InsnList instructions = this.instructions;
List<TryCatchBlockNode> tryCatchBlocks = this.tryCatchBlocks;
List<LocalVariableNode> localVariables = this.localVariables;
this.instructions = new InsnList();
this.tryCatchBlocks = new ArrayList<>();
this.localVariables = new ArrayList<>();
this.maxLocals = -1;
this.maxStack = -1;
accept(superMv);
int opcode;
if (Modifier.isStatic(access)) {
opcode = Opcodes.INVOKESTATIC;
} else {
opcode = Opcodes.INVOKEVIRTUAL;
}
genMethodACode(opcode, t, mapTo, superMv, src);
// make sure public
int newAccess = (access & ~(ACC_PRIVATE | ACC_PROTECTED)) | ACC_PUBLIC;
MethodVisitor rmv = wrap(superMethodVisitor(newAccess, t.name, desc, null, null));
if (rmv != null) {
rmv.visitCode();
int n, i;
n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
for (i = 0; i < n; ++i) {
tryCatchBlocks.get(i).accept(rmv);
}
instructions.accept(rmv);
n = localVariables == null ? 0 : localVariables.size();
for (i = 0; i < n; ++i) {
localVariables.get(i).accept(rmv);
}
rmv.visitMaxs(-1, -1);
rmv.visitEnd();
}
}
};
} else {
return wrap(superMv);
}
}
private MethodVisitor superMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) {
return super.visitMethod(access, name, desc, signature, exceptions);
}
MethodVisitor wrap(MethodVisitor mv) {
return mv == null ? null : new ReplaceMethodVisitor(mv);
}
class ReplaceMethodVisitor extends MethodVisitor {
public ReplaceMethodVisitor(MethodVisitor mv) {
super(Opcodes.ASM4, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
MtdInfo mapTo = findTargetMethod("L" + owner + ";", name, desc);
if (mapTo != null) {
boolean isStatic = opcode == INVOKESTATIC;
Type orgRet = Type.getReturnType(desc);
Type[] orgArgs = Type.getArgumentTypes(desc);
Type nRet = Type.getReturnType(mapTo.desc);
Type[] nArgs = Type.getArgumentTypes(mapTo.desc);
if (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {
throw new RuntimeException("can't cast " + nRet + " to " + orgRet);
}
if (nArgs.length == 1 && nArgs[0].getDescriptor().equals(invocationInterfaceDesc)) {
MtdInfo t = new MtdInfo();
t.owner = "L" + owner + ";";
t.name = name;
t.desc = desc;
MtdInfo n = newMethodA(opcode, t, mapTo);
super.visitMethodInsn(INVOKESTATIC, clzName, n.name, n.desc);
} else {
// checking for invalid replace
if (isStatic) {
if (!Arrays.deepEquals(orgArgs, nArgs)) {
throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
}
} else {
if (nArgs.length != orgArgs.length + 1) {
throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
}
if (orgArgs.length > 0) {
for (int i = 0; i < orgArgs.length; i++) {
if (!orgArgs[i].equals(nArgs[i + 1])) {
throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
}
}
}
}
// replace it!
super.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);
unBox(orgRet, nRet, this.mv);
}
} else {
super.visitMethodInsn(opcode, owner, name, desc);
}
}
}
};
}
use of org.objectweb.asm.tree.LocalVariableNode in project spring-loaded by spring-projects.
the class SpringLoadedTests method checkLocalVariables.
@SuppressWarnings("unchecked")
protected void checkLocalVariables(byte[] bytes, String methodNameAndDescriptor, String... expected) {
ClassNode cn = new ClassNode();
ClassReader cr = new ClassReader(bytes);
cr.accept(cn, 0);
boolean checked = false;
List<MethodNode> methods = cn.methods;
for (MethodNode mn : methods) {
if (methodNameAndDescriptor.equals(mn.name + mn.desc)) {
List<LocalVariableNode> localVariables = mn.localVariables;
Assert.assertEquals(expected.length, localVariables.size());
for (int i = 0; i < expected.length; i++) {
StringTokenizer tokenizer = new StringTokenizer(expected[i], ":");
String expectedName = tokenizer.nextToken();
String expectedDesc = tokenizer.nextToken();
LocalVariableNode localVariable = localVariables.get(i);
Assert.assertEquals(i, localVariable.index);
Assert.assertEquals(expectedName, localVariable.name);
Assert.assertEquals(expectedDesc, localVariable.desc);
}
checked = true;
}
}
if (!checked) {
for (MethodNode mn : methods) {
System.out.println(mn.name + mn.desc);
}
Assert.fail("Unable to find method " + methodNameAndDescriptor);
}
}
use of org.objectweb.asm.tree.LocalVariableNode in project enumerable by hraberg.
the class LambdaExpressionTrees method parseExpressionFromMethod.
public static Expression parseExpressionFromMethod(Method method, String... parameters) {
try {
MethodNode mn = findMethodNode(method);
LocalVariableNode[] parameterLocals = new LocalVariableNode[parameters.length];
Type[] argumentTypes = getArgumentTypes(mn.desc);
int realIndex = 1;
for (int i = 0; i < parameters.length; i++) {
parameterLocals[i] = new LocalVariableNode(parameters[i], argumentTypes[i].getDescriptor(), null, null, null, realIndex);
realIndex += argumentTypes[i].getSize();
}
final ExpressionInterpreter interpreter = new ExpressionInterpreter(mn, parameterLocals);
Analyzer analyzer = new Analyzer(interpreter) {
protected Frame newFrame(Frame src) {
Frame frame = super.newFrame(src);
interpreter.setCurrentFrame(frame);
return frame;
}
protected void newControlFlowEdge(int insn, int successor) {
interpreter.newControlFlowEdge(insn, successor);
}
};
interpreter.analyzer = analyzer;
analyzer.analyze(getInternalName(method.getDeclaringClass()), mn);
return interpreter.expression;
} catch (Exception e) {
throw uncheck(e);
}
}
use of org.objectweb.asm.tree.LocalVariableNode in project felix by apache.
the class InnerClassAdapter method generateMethodWrapper.
/**
* Generate the method header of a POJO method.
* This method header encapsulate the POJO method call to
* signal entry exit and error to the container.
*
* The instance manager and flag are accessed using method calls.
* @param access : access flag.
* @param name : method name.
* @param desc : method descriptor.
* @param signature : method signature.
* @param exceptions : declared exceptions.
* @param localVariables : the local variable nodes.
* @param annotations : the annotations to move to this method.
* @param paramAnnotations : the parameter annotations to move to this method.
*/
private void generateMethodWrapper(int access, String name, String desc, String signature, String[] exceptions, List<LocalVariableNode> localVariables, List<ClassChecker.AnnotationDescriptor> annotations, Map<Integer, List<ClassChecker.AnnotationDescriptor>> paramAnnotations) {
GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc);
// If we have variables, we wraps the code within labels. The `lifetime` of the variables are bound to those
// two variables.
boolean hasArgumentLabels = localVariables != null && !localVariables.isEmpty();
Label start = null;
if (hasArgumentLabels) {
start = new Label();
mv.visitLabel(start);
}
mv.visitCode();
Type returnType = Type.getReturnType(desc);
// Compute result and exception stack location
int result = -1;
int exception;
if (returnType.getSort() != Type.VOID) {
// The method returns something
result = mv.newLocal(returnType);
exception = mv.newLocal(Type.getType(Throwable.class));
} else {
exception = mv.newLocal(Type.getType(Throwable.class));
}
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable");
// Access the flag from the outer class
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, m_name, "this$0", "L" + m_outer + ";");
mv.visitFieldInsn(GETFIELD, m_outer, getMethodFlagName(name, desc), "Z");
mv.visitJumpInsn(IFNE, l0);
mv.visitVarInsn(ALOAD, 0);
mv.loadArgs();
mv.visitMethodInsn(INVOKESPECIAL, m_name, ClassManipulator.PREFIX + name, desc, false);
mv.visitInsn(returnType.getOpcode(IRETURN));
// end of the non intercepted method invocation.
mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, m_name, "this$0", "L" + m_outer + ";");
mv.visitFieldInsn(GETFIELD, m_outer, ClassManipulator.IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(getMethodId(name, desc));
mv.loadArgArray();
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ClassManipulator.ENTRY, "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V", false);
mv.visitVarInsn(ALOAD, 0);
// Do not allow argument modification : just reload arguments.
mv.loadArgs();
mv.visitMethodInsn(INVOKESPECIAL, m_name, ClassManipulator.PREFIX + name, desc, false);
if (returnType.getSort() != Type.VOID) {
mv.visitVarInsn(returnType.getOpcode(ISTORE), result);
}
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, m_name, "this$0", "L" + m_outer + ";");
mv.visitFieldInsn(GETFIELD, m_outer, ClassManipulator.IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(getMethodId(name, desc));
if (returnType.getSort() != Type.VOID) {
mv.visitVarInsn(returnType.getOpcode(ILOAD), result);
mv.box(returnType);
} else {
mv.visitInsn(ACONST_NULL);
}
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ClassManipulator.EXIT, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V", false);
mv.visitLabel(l1);
Label l7 = new Label();
mv.visitJumpInsn(GOTO, l7);
mv.visitLabel(l2);
mv.visitVarInsn(ASTORE, exception);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, m_name, "this$0", "L" + m_outer + ";");
mv.visitFieldInsn(GETFIELD, m_outer, ClassManipulator.IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(getMethodId(name, desc));
mv.visitVarInsn(ALOAD, exception);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ClassManipulator.ERROR, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Throwable;)V", false);
mv.visitVarInsn(ALOAD, exception);
mv.visitInsn(ATHROW);
mv.visitLabel(l7);
if (returnType.getSort() != Type.VOID) {
mv.visitVarInsn(returnType.getOpcode(ILOAD), result);
}
mv.visitInsn(returnType.getOpcode(IRETURN));
// If we had arguments, we mark the end of the lifetime.
Label end = null;
if (hasArgumentLabels) {
end = new Label();
mv.visitLabel(end);
}
// Move annotations
if (annotations != null) {
for (ClassChecker.AnnotationDescriptor ad : annotations) {
ad.visitAnnotation(mv);
}
}
// Move parameter annotations
if (paramAnnotations != null && !paramAnnotations.isEmpty()) {
for (Integer id : paramAnnotations.keySet()) {
List<ClassChecker.AnnotationDescriptor> ads = paramAnnotations.get(id);
for (ClassChecker.AnnotationDescriptor ad : ads) {
ad.visitParameterAnnotation(id, mv);
}
}
}
// Write the arguments name.
if (hasArgumentLabels) {
for (LocalVariableNode var : localVariables) {
mv.visitLocalVariable(var.name, var.desc, var.signature, start, end, var.index);
}
}
mv.visitMaxs(0, 0);
mv.visitEnd();
}
Aggregations