use of org.objectweb.asm.tree.MethodNode in project SpecialSource by md-5.
the class JarComparer method getDeclarer.
public String getDeclarer(String currentParent, Ownable node) {
String newParent = null;
ClassNode n = jarRepo.findClass(currentParent);
if (n == null) {
return newParent;
}
switch(node.type) {
case FIELD:
for (FieldNode field : n.fields) {
if (field.name.equals(node.name) && field.desc.equals(node.descriptor)) {
newParent = currentParent;
fields.remove(new Ownable(NodeType.FIELD, currentParent, node.name, node.descriptor, node.access));
break;
}
}
break;
case METHOD:
for (MethodNode method : n.methods) {
if (method.name.equals(node.name) && method.desc.equals(node.descriptor) && (method.access == -1 || (!Modifier.isPrivate(method.access) && !Modifier.isStatic(method.access)))) {
newParent = currentParent;
methods.remove(new Ownable(NodeType.METHOD, currentParent, node.name, node.descriptor, node.access));
methods.remove(node);
break;
}
}
break;
}
if ((node.owner.equals(newParent) || newParent == null) && (node.access == -1 || (!Modifier.isPrivate(node.access) && !Modifier.isStatic(node.access)))) {
Collection<String> parents = inheritance.getParents(currentParent);
if (parents != null) {
// climb the inheritance tree
for (String parent : parents) {
newParent = getDeclarer(parent, node);
if (newParent != null) {
return newParent;
}
}
}
}
return newParent;
}
use of org.objectweb.asm.tree.MethodNode in project drill by apache.
the class MergeAdapter method visitEnd.
@Override
public void visitEnd() {
// add all the fields of the class we're going to merge.
// Special handling for nested classes. Drill uses non-static nested
// "inner" classes in some templates. Prior versions of Drill would
// create the generated nested classes as static, then this line
// would copy the "this$0" field to convert the static nested class
// into a non-static inner class. However, that approach is not
// compatible with plain-old Java compilation. Now, Drill generates
// the nested classes as non-static inner classes. As a result, we
// do not want to copy the hidden fields; we'll end up with two if
// we do.
classToMerge.fields.stream().filter(field -> !field.name.startsWith("this$")).forEach(field -> field.accept(this));
// add all the methods that we to include.
for (MethodNode mn : classToMerge.methods) {
if (mn.name.equals("<init>")) {
continue;
}
String[] exceptions = new String[mn.exceptions.size()];
mn.exceptions.toArray(exceptions);
MethodVisitor mv = cv.visitMethod(mn.access | Modifier.FINAL, mn.name, mn.desc, mn.signature, exceptions);
if (verifyBytecode) {
mv = new CheckMethodVisitorFsm(api, mv);
}
mn.instructions.resetLabels();
// mn.accept(new RemappingMethodAdapter(mn.access, mn.desc, mv, new
// SimpleRemapper("org.apache.drill.exec.compile.ExampleTemplate", "Bunky")));
ClassSet top = set;
while (top.parent != null) {
top = top.parent;
}
mn.accept(new MethodRemapper(mv, new SimpleRemapper(top.precompiled.slash, top.generated.slash)));
}
super.visitEnd();
}
use of org.objectweb.asm.tree.MethodNode in project LogisticsPipes by RS485.
the class ParamProfiler method handleClass.
public static byte[] handleClass(byte[] bytes) {
if (!isActive)
return bytes;
final ClassReader reader = new ClassReader(bytes);
final ClassNode node = new ClassNode();
reader.accept(node, 0);
final String className = node.name;
for (final MethodNode m : node.methods) {
final String methodName = m.name;
final String methodDesc = m.desc;
final boolean isConst = methodName.contains("<") || methodName.contains(">");
if (isConst)
continue;
final long methodId = minMethodId++;
final List<String> varList = new ArrayList<>();
if (!methodDesc.startsWith("("))
throw new UnsupportedOperationException(methodDesc);
outer: for (int i = 1; i < methodDesc.length(); i++) {
switch(methodDesc.charAt(i)) {
case ')':
break outer;
case 'L':
int startA = i;
while (methodDesc.charAt(i) != ';') i++;
varList.add(methodDesc.substring(startA, i + 1));
break;
case '[':
int startB = i;
while (methodDesc.charAt(i) == '[') i++;
if (methodDesc.charAt(i) == 'L') {
while (methodDesc.charAt(i) != ';') i++;
}
varList.add(methodDesc.substring(startB, i + 1));
break;
default:
varList.add(String.valueOf(methodDesc.charAt(i)));
}
}
final List<Label> catchStatement = new ArrayList<>();
MethodNode mv = new MethodNode(Opcodes.ASM4, m.access, m.name, m.desc, m.signature, m.exceptions.toArray(new String[0])) {
@Override
public void visitCode() {
super.visitCode();
Label l0 = new Label();
visitLabel(l0);
visitLdcInsn(new Long(methodId));
visitLdcInsn(className + "+" + methodName + "+" + methodDesc);
if ((m.access & Opcodes.ACC_STATIC) != 0) {
visitInsn(Opcodes.ACONST_NULL);
} else {
visitVarInsn(Opcodes.ALOAD, 0);
}
visitIntInsn(Opcodes.BIPUSH, varList.size());
visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
int count = 0;
int pos = 0;
if ((m.access & Opcodes.ACC_STATIC) == 0) {
pos = 1;
}
for (String varNode : varList) {
visitInsn(Opcodes.DUP);
visitIntInsn(Opcodes.BIPUSH, count++);
if (!varNode.startsWith("L") && !varNode.startsWith("[")) {
switch(varNode.charAt(0)) {
case 'I':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
break;
case 'J':
visitVarInsn(Opcodes.LLOAD, pos);
pos += 2;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
break;
case 'Z':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
break;
case 'B':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
break;
case 'C':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
break;
case 'S':
visitVarInsn(Opcodes.ILOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
break;
case 'F':
visitVarInsn(Opcodes.FLOAD, pos);
pos += 1;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
break;
case 'D':
visitVarInsn(Opcodes.DLOAD, pos);
pos += 2;
visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
break;
default:
throw new UnsupportedOperationException("'" + varNode + "'");
}
} else {
visitVarInsn(Opcodes.ALOAD, pos);
pos += 1;
}
visitInsn(Opcodes.AASTORE);
}
visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/ParamProfiler", "methodStart", "(JLjava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)V", false);
}
@Override
public void visitInsn(int opcode) {
if (opcode == Opcodes.RETURN || opcode == Opcodes.IRETURN || opcode == Opcodes.LRETURN || opcode == Opcodes.FRETURN || opcode == Opcodes.DRETURN || opcode == Opcodes.ARETURN) {
visitLdcInsn(new Long(methodId));
visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/ParamProfiler", "methodEnd", "(J)V", false);
}
super.visitInsn(opcode);
}
@Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
catchStatement.add(handler);
super.visitTryCatchBlock(start, end, handler, type);
}
boolean watchForHandling = false;
@Override
public void visitLabel(Label label) {
watchForHandling = false;
super.visitLabel(label);
if (catchStatement.contains(label)) {
watchForHandling = true;
}
}
@Override
public void visitVarInsn(int opcode, int var) {
super.visitVarInsn(opcode, var);
if (watchForHandling) {
watchForHandling = false;
Label l = new Label();
visitLabel(l);
visitVarInsn(Opcodes.ALOAD, var);
visitMethodInsn(Opcodes.INVOKESTATIC, "logisticspipes/asm/ParamProfiler", "handleException", "(Ljava/lang/Throwable;)V", false);
}
}
};
m.accept(mv);
node.methods.set(node.methods.indexOf(m), mv);
}
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
node.accept(writer);
return writer.toByteArray();
}
use of org.objectweb.asm.tree.MethodNode 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.MethodNode in project dex2jar by pxb1988.
the class ExDex2Asm method convertCode.
@Override
public void convertCode(DexMethodNode methodNode, MethodVisitor mv, ClzCtx clzCtx) {
MethodVisitor mw = AsmBridge.searchMethodWriter(mv);
MethodNode mn = new MethodNode(Opcodes.ASM5, methodNode.access, methodNode.method.getName(), methodNode.method.getDesc(), null, null);
try {
super.convertCode(methodNode, mn, clzCtx);
} catch (Exception ex) {
if (exceptionHandler == null) {
throw new DexException(ex, "Failed to convert code for %s", methodNode.method);
} else {
mn.instructions.clear();
mn.tryCatchBlocks.clear();
exceptionHandler.handleMethodTranslateException(methodNode.method, methodNode, mn, ex);
}
}
// code convert ok, copy to MethodWriter and check for Size
mn.accept(mv);
if (mw != null) {
try {
AsmBridge.sizeOfMethodWriter(mw);
} catch (Exception ex) {
mn.instructions.clear();
mn.tryCatchBlocks.clear();
exceptionHandler.handleMethodTranslateException(methodNode.method, methodNode, mn, ex);
AsmBridge.replaceMethodWriter(mw, mn);
}
}
}
Aggregations