private void writeConstructor(ClassVisitor visitor, Type generatedType, Type superclassType, StructSchema<?> delegateSchema, Type backingStateType) { String constructorDescriptor; Type delegateType; if (delegateSchema == null) { delegateType = null; constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, backingStateType, TYPE_CONVERTER_TYPE); } else { delegateType = Type.getType(delegateSchema.getType().getConcreteClass()); constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, backingStateType, TYPE_CONVERTER_TYPE, delegateType); } MethodVisitor constructorVisitor = declareMethod(visitor, CONSTRUCTOR_NAME, constructorDescriptor, CONCRETE_SIGNATURE); invokeSuperConstructor(constructorVisitor, superclassType); assignStateField(constructorVisitor, generatedType); assignTypeConverterField(constructorVisitor, generatedType); if (delegateType != null) { assignDelegateField(constructorVisitor, generatedType, delegateType); } setCanCallSettersField(constructorVisitor, generatedType, true); finishVisitingMethod(constructorVisitor); }
/** * See {@link org.objectweb.asm.util.CheckClassAdapter#CheckClassAdapter(ClassVisitor, boolean)}. * @param api the api version */ protected DrillCheckClassAdapter(final int api, final ClassVisitor cv, final boolean checkDataFlow) { super(api); /* * We set up a chain of class visitors: * this -> InnerAccessStripper -> CheckClassAdapter -> AccessRestorer -> cv * Note the AccessRestorer references accessStripper to get the original * access bits; the inner class could not be constructed before the call to * super(), hence the need to set the delegate after that. */ accessStripper = new InnerClassAccessStripper(api, new CheckClassAdapter( new AccessRestorer(api, cv), checkDataFlow)); setDelegate(accessStripper); }
private void writeViewPropertyDslMethods(ClassVisitor visitor, Type generatedType, Collection<ModelProperty<?>> viewProperties, Class<?> viewClass) { boolean writable = Iterables.any(viewProperties, new Predicate<ModelProperty<?>>() { @Override public boolean apply(ModelProperty<?> viewProperty) { return viewProperty.isWritable(); } }); // TODO:LPTR Instead of the first view property, we should figure out these parameters from the actual property ModelProperty<?> firstProperty = viewProperties.iterator().next(); writeConfigureMethod(visitor, generatedType, firstProperty, writable); writeSetMethod(visitor, generatedType, firstProperty); writeTypeConvertingSetter(visitor, generatedType, viewClass, firstProperty); // TODO - this should be applied to all methods, including delegating methods writeReadOnlySetter(visitor, viewClass, writable, firstProperty); }
@Override public void begin(final String name, final Attributes attrs) { String desc = attrs.getValue("desc"); boolean visible = Boolean.valueOf(attrs.getValue("visible")) .booleanValue(); int typeRef = Integer.parseInt(attrs.getValue("typeRef")); TypePath typePath = TypePath.fromString(attrs.getValue("typePath")); Object v = peek(); if (v instanceof ClassVisitor) { push(((ClassVisitor) v).visitTypeAnnotation(typeRef, typePath, desc, visible)); } else if (v instanceof FieldVisitor) { push(((FieldVisitor) v).visitTypeAnnotation(typeRef, typePath, desc, visible)); } else if (v instanceof MethodVisitor) { push(((MethodVisitor) v).visitTypeAnnotation(typeRef, typePath, desc, visible)); } }
private void writeSetter(ClassVisitor visitor, Type generatedType, String propertyName, Class<?> propertyClass, WeaklyTypeReferencingMethod<?, ?> weakSetter) { Type propertyType = Type.getType(propertyClass); Label calledOutsideOfConstructor = new Label(); Method setter = weakSetter.getMethod(); // the regular typed setter String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, propertyType); MethodVisitor methodVisitor = declareMethod(visitor, setter.getName(), methodDescriptor, AsmClassGeneratorUtils.signature(setter)); putCanCallSettersFieldValueOnStack(methodVisitor, generatedType); jumpToLabelIfStackEvaluatesToTrue(methodVisitor, calledOutsideOfConstructor); throwExceptionBecauseCalledOnItself(methodVisitor); methodVisitor.visitLabel(calledOutsideOfConstructor); putStateFieldValueOnStack(methodVisitor, generatedType); putConstantOnStack(methodVisitor, propertyName); putFirstMethodArgumentOnStack(methodVisitor, propertyType); if (propertyClass.isPrimitive()) { boxType(methodVisitor, propertyClass); } invokeStateSetMethod(methodVisitor); finishVisitingMethod(methodVisitor); }
private void generateTests() throws IOException { ClassReader cr = new ClassReader(new FileInputStream(classNamePath.toFile())); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); cr.accept( new ClassVisitor(Opcodes.ASM5, cw) { @Override public void visitEnd() { generateMethodTest1(cw); generateMethodTest2(cw); generateMethodTest3(cw); generateMethodTest4(cw); generateMethodTest5(cw); generateMethodTest6(cw); generateMethodTest7(cw); generateMethodTest8(cw); generateMethodTest9(cw); generateMethodTest10(cw); generateMethodTest11(cw); generateMethodTest12(cw); generateMethodTest13(cw); generateMethodMain(cw); super.visitEnd(); } }, 0); new FileOutputStream(classNamePath.toFile()).write(cw.toByteArray()); }
/** * Generate test with an invokedynamic, a static bootstrap method without extra args and * args to the target method. */ private void generateMethodTest2(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test2", "()V", null, null); MethodType mt = MethodType.methodType( CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmLookupStatic", mt.toMethodDescriptorString(), false); mv.visitLdcInsn(new Boolean(true)); mv.visitLdcInsn(new Byte((byte) 127)); mv.visitLdcInsn(new Character('c')); mv.visitLdcInsn(new Short((short) 1024)); mv.visitLdcInsn(new Integer(123456)); mv.visitLdcInsn(new Float(1.2f)); mv.visitLdcInsn(new Long(123456789)); mv.visitLdcInsn(new Double(3.5123456789)); mv.visitLdcInsn("String"); mv.visitInvokeDynamicInsn("targetMethodTest2", "(ZBCSIFJDLjava/lang/String;)V", bootstrap); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invokespecial. */ private void generateMethodTest4(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test4", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallSite", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest5", "(Linvokecustom/InvokeCustom;)V", bootstrap, new Handle( Opcodes.H_INVOKESPECIAL, Type.getInternalName(Super.class), "targetMethodTest5", "()V", false)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke interface. The target method is a default method into an interface * that is at the end of a chain of interfaces. */ private void generateMethodTest6(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test6", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest7", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest7", "(Linvokecustom/J;)V", bootstrap, new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), "targetMethodTest7", "()V", true)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke interface. The target method is a method into an interface * that is shadowed by another definition into a sub interfaces. */ private void generateMethodTest7(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test7", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest8", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest8", "(Linvokecustom/J;)V", bootstrap, new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), "targetMethodTest8", "()V", true)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke virtual. The target method is a method into a class implementing * an abstract method and that shadows a default method from an interface. */ private void generateMethodTest9(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test9", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest10", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest10", "(Linvokecustom/InvokeCustom;)V", bootstrap, new Handle(Opcodes.H_INVOKEVIRTUAL, Type.getInternalName(InvokeCustom.class), "targetMethodTest10", "()V", false)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind get static. The method handle read a static field from a class. */ private void generateMethodTest10(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test10", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethod", mt.toMethodDescriptorString(), false); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitInvokeDynamicInsn("staticField1", "()Ljava/lang/String;", bootstrap, new Handle(Opcodes.H_GETSTATIC, Type.getInternalName(InvokeCustom.class), "staticField1", "Ljava/lang/String;", false)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind get instance. The method handle read an instance field from a class. */ private void generateMethodTest12(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test12", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethod", mt.toMethodDescriptorString(), false); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("instanceField1", "(Linvokecustom/InvokeCustom;)Ljava/lang/String;", bootstrap, new Handle(Opcodes.H_GETFIELD, Type.getInternalName(InvokeCustom.class), "instanceField1", "Ljava/lang/String;", false)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
@Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if(className.startsWith(TransformConfig.getInstance().getPackageScan())) { logger.log(Level.INFO, "-------------------CLASS---------------------"); logger.log(Level.INFO, "className: " + className); ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassVisitor classVisitor = new HookClassAdapter(Opcodes.ASM5, cw); cr.accept(classVisitor, ClassReader.SKIP_FRAMES); // try { // FileOutputStream fos = new FileOutputStream(new File("classMod.class")); // fos.write(cw.toByteArray()); // fos.close(); // } catch (IOException e) { // e.printStackTrace(); // } return cw.toByteArray(); } return null; }
/** * Generate simple <pre>super()</pre> calling constructor * * @param classVisitor ClassVisitor instance * @param superClass Super class name (use {@link Object} for non-extending classes * (or explictly extending Object, which is redundant anyway) */ public static void generateSimpleSuperConstructor(@NotNull ClassVisitor classVisitor, @NotNull String superClass) { MethodVisitor mv = Ensure.notNull(classVisitor, "ClassWriter shouldn't be null!") .visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, unqualifyName(superClass), "<init>", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(1, 0); mv.visitEnd(); }
protected AllocateInstrument(ClassVisitor cv, TreeMap<String, Integer> methodToLargestLocal, Properties options, Properties state, String excludeList, boolean logPointerChange) { super(cv, methodToLargestLocal, options, state); this.logPointerChange = logPointerChange; // always add the instrument package to the exclude list excludePackages.add(INSTRUMENT_PACKAGE); if (excludeList != null) { String[] packageList = excludeList.split(";"); for (String p : packageList) { p = p.replace('.', '/'); if (!p.endsWith("/")) p += p + "/"; excludePackages.add(p); } } String path = options.getProperty(PROP_AGENT_DIRECTORY); if (path!=null) { File agentPath = new File(path); File log = new File(agentPath,ALLOCATE_BASE_LOG_FILE_NAME); if (agentPath.exists() && agentPath.canWrite()) { if (!log.exists() || (log.exists() && log.canWrite())) this.allocateLogBaseName = log.getAbsolutePath(); } } }
private void writeEqualsMethod(ClassVisitor cw, Type generatedType) { MethodVisitor methodVisitor = cw.visitMethod(Opcodes.ACC_PUBLIC, "equals", EQUALS_METHOD_DESCRIPTOR, null, null); methodVisitor.visitCode(); // if (arg == this) { return true; } methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitVarInsn(ALOAD, 1); Label notSameLabel = new Label(); methodVisitor.visitJumpInsn(IF_ACMPNE, notSameLabel); methodVisitor.visitInsn(ICONST_1); methodVisitor.visitInsn(IRETURN); // if (!(age instanceof GeneratedView)) { return false; } methodVisitor.visitLabel(notSameLabel); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitTypeInsn(INSTANCEOF, GENERATED_VIEW_TYPE.getInternalName()); Label generatedViewLabel = new Label(); methodVisitor.visitJumpInsn(IFNE, generatedViewLabel); methodVisitor.visitInsn(ICONST_0); methodVisitor.visitInsn(IRETURN); // return state.equals(((GeneratedView)arg).__view_state()); methodVisitor.visitLabel(generatedViewLabel); putStateFieldValueOnStack(methodVisitor, generatedType); methodVisitor.visitVarInsn(ALOAD, 1); methodVisitor.visitTypeInsn(CHECKCAST, GENERATED_VIEW_TYPE.getInternalName()); methodVisitor.visitMethodInsn(INVOKEINTERFACE, GENERATED_VIEW_TYPE.getInternalName(), "__view_state__", GET_VIEW_STATE_METHOD_DESCRIPTOR, true); methodVisitor.visitMethodInsn(INVOKEINTERFACE, GENERATED_VIEW_STATE_TYPE_NAME, "equals", EQUALS_METHOD_DESCRIPTOR, true); finishVisitingMethod(methodVisitor, Opcodes.IRETURN); }
private void writeGetter(ClassVisitor visitor, Type generatedType, String propertyName, Class<?> propertyClass, WeaklyTypeReferencingMethod<?, ?> weakGetter) { Method getter = weakGetter.getMethod(); Type propertyType = Type.getType(propertyClass); MethodVisitor methodVisitor = declareMethod( visitor, getter.getName(), Type.getMethodDescriptor(propertyType), AsmClassGeneratorUtils.signature(getter)); putStateFieldValueOnStack(methodVisitor, generatedType); putConstantOnStack(methodVisitor, propertyName); invokeStateGetMethod(methodVisitor); castFirstStackElement(methodVisitor, propertyClass); finishVisitingMethod(methodVisitor, returnCode(propertyType)); }
private byte[] remapClass(String className, byte[] bytes) { ClassReader classReader = new ClassReader(bytes); ClassWriter classWriter = new ClassWriter(0); ClassVisitor remappingVisitor = new ShadingClassRemapper(classWriter, remapper); try { classReader.accept(remappingVisitor, ClassReader.EXPAND_FRAMES); } catch (Exception e) { throw new GradleException("Error in ASM processing class: " + className, e); } return classWriter.toByteArray(); }
@Override public byte[] apply(byte[] origin) { ClassReader reader = new ClassReader(origin); PredicateClassVisitor precondition = new PredicateClassVisitor(); reader.accept(precondition, SKIP_DEBUG | SKIP_FRAMES); if (!precondition.isAttemptToVisitR()) { return origin; } // don't pass reader to the writer. // or it will copy 'CONSTANT POOL' that contains no used entries to lead proguard running failed! ClassWriter writer = new ClassWriter(0); ClassVisitor visitor = new ShrinkRClassVisitor(writer, rSymbols); reader.accept(visitor, 0); return writer.toByteArray(); }
public Instrumenter(ClassVisitor arg0, TreeMap<String,Integer> methodToLargestLocal, Properties options, Properties state) { super(arg0); this.methodToLargestLocal = methodToLargestLocal; this.state = state; this.options = options; }
@Override public void begin(final String name, final Attributes attrs) { String desc = attrs.getValue("desc"); boolean visible = Boolean.valueOf(attrs.getValue("visible")) .booleanValue(); Object v = peek(); if (v instanceof ClassVisitor) { push(((ClassVisitor) v).visitAnnotation(desc, visible)); } else if (v instanceof FieldVisitor) { push(((FieldVisitor) v).visitAnnotation(desc, visible)); } else if (v instanceof MethodVisitor) { push(((MethodVisitor) v).visitAnnotation(desc, visible)); } }
/** * Generate test with an invokedynamic, a static bootstrap method without extra args and no arg * to the target method. */ private void generateMethodTest1(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test1", "()V", null, null); MethodType mt = MethodType.methodType( CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmLookupStatic", mt.toMethodDescriptorString(), false); mv.visitInvokeDynamicInsn("targetMethodTest1", "()V", bootstrap); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with extra args and no arg * to the target method. */ private void generateMethodTest3(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test3", "()V", null, null); MethodType mt = MethodType.methodType( CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class, long.class, float.class, double.class); Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmLookupStaticWithExtraArgs", mt.toMethodDescriptorString(), false); mv.visitInvokeDynamicInsn("targetMethodTest3", "()V", bootstrap, new Integer(1), new Long(123456789), new Float(123.456), new Double(123456.789123)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Get the raw bytes of instrumented class with name {@code className} * * @param classLoader * @param className * @param reader * @return */ public byte[] transformBytes(ClassLoader classLoader, ClassName className, ClassReader reader) { Objects.requireNonNull(classLoader); Objects.requireNonNull(className); Objects.requireNonNull(reader); if (!canInstrumentForCoverage(className)) { throw new IllegalArgumentException("Cannot instrument " + className); } int asmFlags = ClassWriter.COMPUTE_FRAMES; ClassWriter writer = new ComputeClassWriter(asmFlags); ClassVisitor cv = writer; //this is very we hook our instrumentation cv = new CoverageClassVisitor(cv, className); //avoid reading frames, as we re-compute them int readFlags = ClassReader.SKIP_FRAMES; /* This is using the "Visitor Pattern". In a nutshell, we scan the whole class definition, and at each element we "print" in the "writer" buffer. On such buffer we also add our instrumentation. Then, once we are done traversing the "reader", we convert the buffer in the "writer" into byte[] data */ reader.accept(cv, readFlags); return writer.toByteArray(); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind put static. The method handle write a static field in a class and then * print its value. */ private void generateMethodTest11(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test11", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethod", mt.toMethodDescriptorString(), false); mv.visitLdcInsn("Write static field"); mv.visitInvokeDynamicInsn("staticField1", "(Ljava/lang/String;)V", bootstrap, new Handle(Opcodes.H_PUTSTATIC, Type.getInternalName(InvokeCustom.class), "staticField1", "Ljava/lang/String;", false)); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(InvokeCustom.class), "staticField1", "Ljava/lang/String;"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Makes the given class visitor visit this method. * * @param cv * a class visitor. */ public void accept(final ClassVisitor cv) { String[] exceptions = new String[this.exceptions.size()]; this.exceptions.toArray(exceptions); MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); if (mv != null) { accept(mv); } }
public MethodWriter(int access, Method method, ClassVisitor cw, BitSet statements, CompilerSettings settings) { super(Opcodes.ASM5, cw.visitMethod(access, method.getName(), method.getDescriptor(), null, null), access, method.getName(), method.getDescriptor()); this.statements = statements; this.settings = settings; }
private HashSet<String> analyzeClass(String className) { HashSet<String> set = new HashSet<>(); Optional<InputStream> classFileInputStream = classFileFinder.apply(className); if (!classFileInputStream.isPresent()) { return set; } try(InputStream input = classFileInputStream.get()) { ClassReader reader = new ClassReader(input); reader.accept(new ClassVisitor(Opcodes.ASM6) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { return new MethodVisitor(Opcodes.ASM6) { @Override public AnnotationVisitor visitAnnotation(String annotationDesc, boolean visible) { if (annotationDesc.equals(OVERRIDE_ENTRY_POINT_NAME)) { set.add(name + desc); } return null; } }; } }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG); } catch (IOException e) { throw new UncheckedIOException(e); } return set; }
private static final void check(final byte[] b) { final ClassReader cr = new ClassReader(b); final ClassWriter cw = writer(); final ClassVisitor cv = new DrillCheckClassAdapter(cw); cr.accept(cv, 0); final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw); DrillCheckClassAdapter.verify(new ClassReader(cw.toByteArray()), false, pw); final String checkString = sw.toString(); if (!checkString.isEmpty()) { throw new IllegalStateException(checkString); } }
/** * Set the delegate for this ClassVisitor. Must be called before the visitor is * used (i.e., before any other methods are called), and only once. * @param cv the ClassVisitor to delegate calls to */ protected void setDelegate(final ClassVisitor cv) { if (started) { throw new IllegalStateException("can't change delegate after visitor has been used"); } // This member was only protected, so we can take advantage of that to set it here. this.cv = cv; }
public ClassVisitor rewrite(Class<?> clazz, ClassVisitor output) { Base base = null; Class<?> s = clazz.getSuperclass(); if (s != null) { base = _bases.get(s.getName()); if (base == null) { if (!_jar.hasClass(s.getName())) { for (s = s.getSuperclass(); s != null; s = s.getSuperclass()) { base = _bases.get(s.getName()); if (base != null) { break; } } } } } if (base == null) { return output; } Materialization materialization = null; for (Materialization m : base.materializations) { if (m.superName.equals(clazz.getSuperclass().getName())) { materialization = m; break; } } if (materialization == null) { materialization = new Materialization(base, base.materializations.size() + 1, _provider, _log); base.materializations.add(materialization); } return materialization.rewrite(clazz, output); }
public ClassVisitor rewrite(final Class<?> clazz, ClassVisitor output) { for (Mixin mixin : _mixins) { if (mixin.match(clazz)) { output = mixin.rewrite(clazz, output); } } return output; }
private void declareClass(ClassVisitor visitor, Collection<String> interfaceInternalNames, Type generatedType, Type superclassType) { visitor.visit(V1_6, ACC_PUBLIC, generatedType.getInternalName(), null, superclassType.getInternalName(), Iterables.toArray(interfaceInternalNames, String.class)); }
private void declareStateField(ClassVisitor visitor) { declareField(visitor, STATE_FIELD_NAME, GeneratedViewState.class); }
public static ClassVisitor make(ClassVisitor cv, TreeMap<String,Integer> methodToLargestLocal, Properties options, Properties state) { if (options.containsKey(CALL_CHAIN)) cv = new CallChainInstrument(cv, methodToLargestLocal, options, state); return cv; }