List of usage examples for org.objectweb.asm.tree MethodNode accept
public void accept(final MethodVisitor methodVisitor)
From source file:com.android.build.gradle.internal.incremental.InstantRunMethodVerifier.java
License:Apache License
/** * Verifies a method implementation against the blacklisted list of APIs. * @param method the method to verify/*from w w w. ja v a 2 s. c om*/ * @return a {@link InstantRunVerifierStatus} instance or null if the method is not making any * blacklisted calls. */ @NonNull public static InstantRunVerifierStatus verifyMethod(MethodNode method) { VerifierMethodVisitor mv = new VerifierMethodVisitor(method); method.accept(mv); return mv.incompatibleChange.or(InstantRunVerifierStatus.COMPATIBLE); }
From source file:com.android.build.gradle.internal2.incremental.IncrementalSupportVisitor.java
License:Apache License
/** * Insert Constructor specific logic({@link ConstructorRedirection} and * {@link ConstructorBuilder}) for constructor redirecting or * normal method redirecting ({@link MethodRedirection}) for other methods. *///from w w w . ja va2 s .co m @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { access = transformAccessForInstantRun(access); MethodVisitor defaultVisitor = super.visitMethod(access, name, desc, signature, exceptions); MethodNode method = getMethodByNameInClass(name, desc, classNode); // does the method use blacklisted APIs. boolean hasIncompatibleChange = InstantRunMethodVerifier .verifyMethod(method) != InstantRunVerifierStatus.COMPATIBLE; if (hasIncompatibleChange || disableRedirectionForClass || !isAccessCompatibleWithInstantRun(access) || name.equals(ByteCodeUtils.CLASS_INITIALIZER)) { return defaultVisitor; } else { ArrayList<Type> args = new ArrayList<Type>(Arrays.asList(Type.getArgumentTypes(desc))); boolean isStatic = (access & Opcodes.ACC_STATIC) != 0; if (!isStatic) { args.add(0, Type.getType(Object.class)); } ISMethodVisitor mv = new ISMethodVisitor(defaultVisitor, access, name, desc); if (name.equals(ByteCodeUtils.CONSTRUCTOR)) { Constructor constructor = ConstructorBuilder.build(visitedClassName, method); LabelNode start = new LabelNode(); method.instructions.insert(constructor.loadThis, start); if (constructor.lineForLoad != -1) { // Record the line number from the start of LOAD_0 for uninitialized 'this'. // This allows a breakpoint to be set at the line with this(...) or super(...) // call in the constructor. method.instructions.insert(constructor.loadThis, new LineNumberNode(constructor.lineForLoad, start)); } mv.addRedirection(new ConstructorRedirection(start, constructor, args)); } else { mv.addRedirection(new MethodRedirection(new LabelNode(mv.getStartLabel()), name + "." + desc, args, Type.getReturnType(desc))); } method.accept(mv); return null; } }
From source file:com.android.builder.shrinker.Shrinker.java
License:Apache License
@NonNull private Set<Dependency<T>> getDependencies(MethodNode methodNode) { final Set<Dependency<T>> deps = Sets.newHashSet(); methodNode.accept(new DependencyFinderVisitor<T>(mGraph, null, null, null, null) { @Override/*w w w. j av a 2 s . c o m*/ protected void handleDependency(T source, T target, DependencyType type) { deps.add(new Dependency<T>(target, type)); } }); return deps; }
From source file:com.codename1.tools.ikvm.Parser.java
/** * Parses an InputStream containing a class. * @param input The input stream with a class. * @return If a transformation occurred, the bytes for the changed class will be returned. Otherwise null will be returned. * @throws Exception //from w ww. j av a 2 s. com */ public static byte[] parse(InputStream input, ClassLoader classLoader) throws Exception { ClassReader r = new ClassReader(input); Parser p = new Parser(); //ClassWriter w = new ClassWriter(r, 0); ClassNode classNode = new ClassNode(); //p.classNode = classNode; r.accept(classNode, 0); //r.accept(p, ClassReader.EXPAND_FRAMES) List<MethodNode> methodsToAdd = new ArrayList<MethodNode>(); int methodNum = 0; for (Object o : classNode.methods) { methodNum++; MethodNode methodNode = (MethodNode) o; boolean synchronizedMethod = (methodNode.access & Opcodes.ACC_SYNCHRONIZED) == Opcodes.ACC_SYNCHRONIZED; if (synchronizedMethod) { // Check for a try statement final boolean[] tryCatchFound = new boolean[1]; //System.out.println("Found sync method "+methodNode.name+". Checking for try blocks"); methodNode.accept(new MethodVisitor(Opcodes.ASM5) { @Override public void visitTryCatchBlock(Label label, Label label1, Label label2, String string) { tryCatchFound[0] = true; } }); if (!tryCatchFound[0]) { continue; } //System.out.println("Instructions: "+Arrays.toString(methodNode.instructions.toArray())); System.out.println("Transforming method " + methodNode.name + " of class " + classNode.name); MethodDescriptor md = new MethodDescriptor(methodNode.access, methodNode.name, methodNode.desc); //methodNode.access = methodNode.access & ~Opcodes.ACC_SYNCHRONIZED; String privateMethodName = (md.constructor ? "___cn1init__" : methodNode.name) + "___cn1sync" + (methodNum); MethodNode syncMethod = new MethodNode(methodNode.access, methodNode.name, methodNode.desc, methodNode.signature, (String[]) methodNode.exceptions.toArray(new String[methodNode.exceptions.size()])); methodNode.name = privateMethodName; methodNode.access = (methodNode.access | Opcodes.ACC_PRIVATE) & ~Opcodes.ACC_PUBLIC & ~Opcodes.ACC_PROTECTED & ~Opcodes.ACC_SYNCHRONIZED; LabelNode startLabel = new LabelNode(); syncMethod.instructions.add(startLabel); LabelNode endLabel = new LabelNode(); int argIndex = 0; if (!md.staticMethod) { //System.out.println(methodNode.name + " is not static"); syncMethod.localVariables.add(new LocalVariableNode("arg" + (argIndex), "L" + classNode.name + ";", null, startLabel, endLabel, argIndex)); syncMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, argIndex++)); } for (ByteCodeMethodArg arg : md.arguments) { char typeChar = arg.type; if (arg.dim > 0) { typeChar = 'L'; } if (arg.desc == null || arg.desc.isEmpty()) { throw new RuntimeException( "Invalid arg description for arg " + argIndex + " of method " + methodNode.name); } syncMethod.localVariables.add(new LocalVariableNode("arg" + (argIndex), arg.desc, arg.desc, startLabel, endLabel, argIndex)); switch (typeChar) { case 'L': syncMethod.instructions.add(new VarInsnNode(Opcodes.ALOAD, argIndex++)); //syncMethod.localVariables.add(new LocalVariableNode("arg"+(argIndex-1), arg.desc, null, startLabel, endLabel, argIndex-1)); break; case 'S': case 'I': case 'B': case 'Z': case 'C': syncMethod.instructions.add(new VarInsnNode(Opcodes.ILOAD, argIndex++)); break; case 'J': syncMethod.instructions.add(new VarInsnNode(Opcodes.LLOAD, argIndex++)); argIndex++; // arg index increments 2 for double size args break; case 'F': syncMethod.instructions.add(new VarInsnNode(Opcodes.FLOAD, argIndex++)); break; case 'D': syncMethod.instructions.add(new VarInsnNode(Opcodes.DLOAD, argIndex++)); argIndex++;// arg index increments 2 for double size args break; default: throw new IllegalArgumentException("Unsupported argument type " + arg.type); } } if (md.staticMethod) { syncMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name, privateMethodName, methodNode.desc)); } else { syncMethod.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.name, privateMethodName, methodNode.desc)); } if (md.returnType != null) { char typeChar = md.returnType.type; if (md.returnType.dim > 0) { typeChar = 'L'; } switch (typeChar) { case 'L': syncMethod.instructions.add(new InsnNode(Opcodes.ARETURN)); break; case 'S': case 'I': case 'B': case 'Z': case 'C': syncMethod.instructions.add(new InsnNode(Opcodes.IRETURN)); break; case 'J': syncMethod.instructions.add(new InsnNode(Opcodes.LRETURN)); break; case 'F': syncMethod.instructions.add(new InsnNode(Opcodes.FRETURN)); break; case 'D': syncMethod.instructions.add(new InsnNode(Opcodes.DRETURN)); break; case 'V': syncMethod.instructions.add(new InsnNode(Opcodes.RETURN)); break; default: throw new IllegalArgumentException("Unsupported argument type " + md.returnType.type); } } else { syncMethod.instructions.add(new InsnNode(Opcodes.DRETURN)); } syncMethod.instructions.add(endLabel); methodsToAdd.add(syncMethod); } } if (!methodsToAdd.isEmpty()) { changed = true; System.out .println("Transforming " + methodsToAdd.size() + " synchronized methods in " + classNode.name); classNode.methods.addAll(methodsToAdd); ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(w); byte[] out = w.toByteArray(); if (verify) { verify(out, classLoader); } return out; } else { ClassWriter w = new ClassWriter(0); classNode.accept(w); byte[] out = w.toByteArray(); return out; } }
From source file:com.github.antag99.retinazer.weaver.SystemProcessor.java
License:Open Source License
@Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { if ((access & ACC_STATIC) != 0 || (access & ACC_ABSTRACT) != 0) return super.visitMethod(access, name, desc, signature, exceptions); final MethodNode methodNode = new MethodNode(access, name, desc, signature, exceptions); return new MethodVisitor(ASM5, methodNode) { @Override/*from w ww . ja va2 s . c o m*/ public void visitEnd() { super.visitEnd(); processMethod(methodNode); if (name.equals("setup") && desc.equals("()V")) setupMethod = methodNode; else methodNode.accept(SystemProcessor.super.visitMethod(access, name, desc, signature, exceptions)); } }; }
From source file:com.github.fge.grappa.transform.AsmTestUtils.java
License:Apache License
public static String getMethodInstructionList(MethodNode methodNode) { Preconditions.checkNotNull(methodNode, "methodNode"); Printer printer = new NonMaxTextifier(); TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer); methodNode.accept(traceMethodVisitor); StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); printer.print(printWriter);//from w ww . ja va2 s. co m printWriter.flush(); String[] lines = PATTERN.split(stringWriter.toString()); int lineNr = 0; for (int i = 0; i < lines.length; i++) { if (!lines[i].startsWith(" @")) { lines[i] = String.format("%2d %s", lineNr++, lines[i]); } } return "Method '" + methodNode.name + "':\n" + NEWLINE.join(lines) + '\n'; }
From source file:com.github.fge.grappa.transform.AsmTestUtils.java
License:Apache License
public static void assertTraceDumpEquality(MethodNode method, String traceDump) throws Exception { Preconditions.checkNotNull(method, "method"); Printer printer = new NonMaxTextifier(); TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer); // MethodAdapter checkMethodAdapter = new MethodAdapter(traceMethodVisitor); MethodVisitor checkMethodAdapter = new CheckMethodAdapter(traceMethodVisitor); method.accept(checkMethodAdapter); StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); printer.print(printWriter);/*from w ww . jav a 2s. com*/ printWriter.flush(); assertEquals(stringWriter.toString(), traceDump); }
From source file:com.github.veithen.cosmos.osgi.runtime.MemberInjector.java
License:Apache License
@Override public void visitEnd() { for (MethodNode method : classNode.methods) { method.accept(new RelocatingClassVisitor(cv, classNode.name, name)); }/*from w w w. java 2s . c om*/ super.visitEnd(); }
From source file:com.google.java.contract.core.agent.SpecificationClassAdapter.java
License:Open Source License
@Override public void visitEnd() { if (contracts != null) { List<ClassContractHandle> synths = new ArrayList<ClassContractHandle>(); synths.addAll(contracts.getClassHandles(ContractKind.ACCESS)); synths.addAll(contracts.getClassHandles(ContractKind.LAMBDA)); for (ClassContractHandle h : synths) { h.getContractMethod().accept(cv); }/*from w ww .ja va 2s .c o m*/ List<ClassContractHandle> helpers = contracts.getClassHandles(ContractKind.HELPER); for (ClassContractHandle h : helpers) { MethodNode methodNode = h.getContractMethod(); DebugUtils.info("instrument", "helper method " + className + "." + methodNode.name + methodNode.desc); ClassVisitor visitor = cv; List<Long> lineNumbers = h.getLineNumbers(); if (lineNumbers != null) { visitor = new LineNumberingClassAdapter(visitor, lineNumbers); } methodNode.accept(new ContractFixingClassAdapter(visitor)); h.setInjected(true); } } super.visitEnd(); }
From source file:com.google.java.contract.core.agent.SpecificationMethodAdapter.java
License:Open Source License
/** * Injects the specified contract method code into the current * class, and returns a new Method object representing the injected * method. This is done by bypassing the SpecificationClassAdapter * and talking directly to its parent (usually, a class writer). * * @param handle the handle from the code pool that holds code and * meta-information about the contract method * @return the method node to invoke/*ww w . j av a 2 s . c om*/ */ @Requires("handle != null") @Ensures("result != null") protected MethodNode injectContractMethod(ContractHandle handle) { MethodNode methodNode = handle.getContractMethod(); if (!handle.isInjected()) { DebugUtils.info("instrument", "contract method " + className + "." + methodNode.name + methodNode.desc); ClassVisitor cv = classAdapter.getParent(); List<Long> lineNumbers = handle.getLineNumbers(); if (lineNumbers != null) { cv = new LineNumberingClassAdapter(cv, lineNumbers); } methodNode.accept(new ContractFixingClassAdapter(cv)); handle.setInjected(true); } return methodNode; }