@Override public void generateMethods(Object classVisitor) { assert classVisitor instanceof ClassVisitor; ClassVisitor cv = (ClassVisitor) classVisitor; // generated by compiling the class: // class foo { public ClassLoader getFrameworkClassLoader() { return // getClass().getClassLoader(); } } // and then running ASMifier on it: // java -classpath asm-debug-all-5.0.2.jar:. org.objectweb.asm.util.ASMifier foo MethodVisitor mv = cv.visitMethod( ACC_PUBLIC, "getFrameworkClassLoader", "()Ljava/lang/ClassLoader;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/Class", "getClassLoader", "()Ljava/lang/ClassLoader;", false); mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); // generated code ends. }
@Test public void testInstrumentationModernClassFile() throws Exception { ClassVisitor classVisitor = TypeConstantAdjustment.INSTANCE.wrap( mock(TypeDescription.class), this.classVisitor, mock(Implementation.Context.class), mock(TypePool.class), new FieldList.Empty<FieldDescription.InDefinedShape>(), new MethodList.Empty<MethodDescription>(), IGNORED, IGNORED); classVisitor.visit( ClassFileVersion.JAVA_V5.getMinorMajorVersion(), FOOBAR, FOO, BAR, QUX, new String[] {BAZ}); assertThat( classVisitor.visitMethod(FOOBAR, FOO, BAR, QUX, new String[] {BAZ}), is(methodVisitor)); verify(this.classVisitor) .visit( ClassFileVersion.JAVA_V5.getMinorMajorVersion(), FOOBAR, FOO, BAR, QUX, new String[] {BAZ}); verify(this.classVisitor).visitMethod(FOOBAR, FOO, BAR, QUX, new String[] {BAZ}); verifyNoMoreInteractions(this.classVisitor); verifyZeroInteractions(methodVisitor); }
T createRootGenerator(AstNode node, String name, Generator.Block block) throws Exception { ClassVisitor type_builder = defineClass(Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC, name, Computation.class); type_builder.visitSource(node.getFileName(), null); RootGenerator generator = new RootGenerator(node, this, type_builder, name); block.invoke(generator); generator.generateSwitchBlock(true); return doMagic(name); }
@Override public void visitEnd() { // add fields for (ThreadLocalVar tlv : threadLocalVars) { super.visitField(Opcodes.ACC_PUBLIC, tlv.getName(), tlv.getTypeAsDesc(), null, null); } super.visitEnd(); }
public String getNewStaticConstant(String type, String name_prefix) { ClassVisitor cv = getClassVisitor(); String realName; synchronized (this) { realName = "__" + constants++; } // declare the field cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, realName, type, null, null).visitEnd(); return realName; }
private FunctionGenerator createFunctionGenerator( AstNode node, String name, boolean has_original, String root_prefix, Set<String> owner_externals) throws NoSuchMethodException, NoSuchFieldException, SecurityException { ClassVisitor type_builder = defineClass(Opcodes.ACC_FINAL, name, Computation.class); type_builder.visitSource(node.getFileName(), null); return new FunctionGenerator( node, this, type_builder, has_original, name, root_prefix, owner_externals); }
public String getNewField(String type, String name, Object init) { ClassVisitor cv = getClassVisitor(); // declare the field cv.visitField(ACC_PRIVATE, name, type, null, null).visitEnd(); if (init != null) { initMethod.aload(THIS); initMethod.ldc(init); initMethod.putfield(getClassname(), name, type); } return name; }
T createReplGenerator(AstNode node, String name, ReplGenerator.Block block) throws Exception { ClassVisitor type_builder = defineClass(Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC, name, Computation.class); type_builder.visitSource(node.getFileName(), null); ReplGenerator generator = new ReplGenerator(node, this, type_builder, name); block.invoke( generator, generator.getRootFrame(), generator.getCurrentFrame(), generator.getUpdateCurrent(), generator.getEscapeValue(), generator.getPrintValue()); generator.generateSwitchBlock(true); return doMagic(name); }
@Override public void visitInnerClass(String name, String outerName, String innerName, int access) { // logger.debug(String.format("[Inner Class] Name: %s, outerName: %s, innerName: %s, // templateName: %s, newName: %s.", // name, outerName, innerName, templateName, newName)); if (name.startsWith(set.precompiled.slash)) { // outerName = outerName.replace(precompiled.slash, generated.slash); name = name.replace(set.precompiled.slash, set.generated.slash); int i = name.lastIndexOf('$'); outerName = name.substring(0, i); super.visitInnerClass(name, outerName, innerName, access); } else { super.visitInnerClass(name, outerName, innerName, access); } }
@Override @SuppressWarnings("CallToThreadDumpStack") public void visitEnd() { classEntry.setRequiresInstrumentation(false); db.recordSuspendableMethods(className, classEntry); if (methods != null && !methods.isEmpty()) { if (alreadyInstrumented && !forceInstrumentation) { for (MethodNode mn : methods) mn.accept(makeOutMV(mn)); } else { if (!alreadyInstrumented) { super.visitAnnotation(ALREADY_INSTRUMENTED_NAME, true); classEntry.setInstrumented(true); } for (MethodNode mn : methods) { final MethodVisitor outMV = makeOutMV(mn); try { InstrumentMethod im = new InstrumentMethod(db, className, mn); if (db.isDebug()) db.log( LogLevel.INFO, "About to instrument method %s#%s%s", className, mn.name, mn.desc); if (im.collectCodeBlocks()) { if (mn.name.charAt(0) == '<') throw new UnableToInstrumentException( "special method", className, mn.name, mn.desc); im.accept(outMV, hasAnnotation(mn)); } else mn.accept(outMV); } catch (AnalyzerException ex) { ex.printStackTrace(); throw new InternalError(ex.getMessage()); } } } } else { // if we don't have any suspendable methods, but our superclass is instrumented, we mark this // class as instrumented, too. if (!alreadyInstrumented && classEntry.getSuperName() != null) { ClassEntry superClass = db.getClassEntry(classEntry.getSuperName()); if (superClass != null && superClass.isInstrumented()) { super.visitAnnotation(ALREADY_INSTRUMENTED_NAME, true); classEntry.setInstrumented(true); } } } super.visitEnd(); }
@Override public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { this.className = name; this.classEntry = db.getOrCreateClassEntry(className, superName); classEntry.setInterfaces(interfaces); forceInstrumentation |= classEntry.requiresInstrumentation(); // need atleast 1.5 for annotations to work if (version < Opcodes.V1_5) version = Opcodes.V1_5; // When Java allows adding interfaces in retransformation, we can mark the class with an // interface, which makes checking whether it's instrumented faster (with instanceof) // if(classEntry.requiresInstrumentation() && !contains(interfaces, SUSPENDABLE_NAME)) { // System.out.println("XX: Marking " + className + " as " + SUSPENDABLE_NAME); // interfaces = add(interfaces, SUSPENDABLE_NAME); // } super.visit(version, access, name, signature, superName, interfaces); }
@SuppressWarnings("unchecked") public void visitEnd() { // add all the fields of the class we're going to merge. for (Iterator<?> it = classToMerge.fields.iterator(); it.hasNext(); ) { ((FieldNode) it.next()).accept(this); } // add all the methods that we to include. for (Iterator<?> it = classToMerge.methods.iterator(); it.hasNext(); ) { MethodNode mn = (MethodNode) it.next(); // skip the init. 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); 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 RemappingMethodAdapter( mn.access, mn.desc, mv, new SimpleRemapper(top.precompiled.slash, top.generated.slash))); } super.visitEnd(); }
@Override public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { if (superName != null) { this.nameOfSuper = superName.replaceAll("/", "."); try { reader = new ClassReader(superName); ClassVisitor visitor = new MethodGetterVisitor(Opcodes.ASM5, superMethods); reader.accept(visitor, ClassReader.EXPAND_FRAMES); } catch (IOException e) { } } if (null != interfaces && interfaces.length == 1) { this.interfaces = interfaces; try { reader = new ClassReader(interfaces[0]); ClassVisitor visitor = new MethodGetterVisitor(Opcodes.ASM5, interfaceMethods); reader.accept(visitor, ClassReader.EXPAND_FRAMES); } catch (IOException e) { } } super.visit(version, access, name, signature, superName, interfaces); }
@Override public void visitInnerClass(String name, String outerName, String innerName, int access) { // TODO should innerName be changed? super.visitInnerClass(remapper.mapType(name), outerName == null ? null : remapper.mapType(outerName), innerName, access); }
public String getNewConstant(String type, String name_prefix, Object init) { ClassVisitor cv = getClassVisitor(); String realName = getNewConstantName(); // declare the field cv.visitField(ACC_PRIVATE, realName, type, null, null).visitEnd(); if (init != null) { initMethod.aload(THIS); initMethod.ldc(init); initMethod.putfield(getClassname(), realName, type); } return realName; }
@Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { this.className = name; super.visit(version, access, remapper.mapType(name), remapper .mapSignature(signature, false), remapper.mapType(superName), interfaces == null ? null : remapper.mapTypes(interfaces)); }
private FieldVisitor declareStaticField(ClassVisitor visitor, String name, Class<?> fieldClass) { return visitor.visitField( ACC_PRIVATE | ACC_FINAL | ACC_STATIC | ACC_SYNTHETIC, name, Type.getDescriptor(fieldClass), null, null); }
@Override public void visitEnd() { for (Map.Entry<Handle, Handle> entry : lambdaAccessToImplMethods.entrySet()) { Handle accessMethod = entry.getKey(); Handle implMethod = entry.getValue(); Bytecode.generateDelegateMethod(cv, ACC_STATIC | ACC_SYNTHETIC, accessMethod, implMethod); } super.visitEnd(); }
@Override public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, FOO, superName, interfaces); }
public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { className = name; super.visit(version, access, name, signature, superName, interfaces); }
public void visitField(FieldNode fieldNode) { cv.visitField( fieldNode.getModifiers(), fieldNode.getName(), BytecodeHelper.getTypeDescription(fieldNode.getType()), null, // fieldValue, //br all the sudden that one cannot init the field here. init is done // in static initializer and instance initializer. null); }
@Override public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { originClassName = name; super.visit(version, access, shadowClassName, signature, superName, interfaces); }
@Override public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, signature, superName, interfaces); this.classname = name; }
@Override public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { System.out.println(name + " extends " + superName + " {"); super.visit(version, access, name, signature, superName, interfaces); }
private MethodVisitor declareMethod( ClassVisitor visitor, String methodName, String methodDescriptor, String methodSignature, int access) { MethodVisitor methodVisitor = visitor.visitMethod(access, methodName, methodDescriptor, methodSignature, NO_EXCEPTIONS); methodVisitor.visitCode(); return methodVisitor; }
// GroovyClassVisitor interface // ------------------------------------------------------------------------- public void visitClass(ClassNode classNode) { try { this.classNode = classNode; this.internalClassName = BytecodeHelper.getClassInternalName(classNode); // System.out.println("Generating class: " + classNode.getName()); this.internalBaseClassName = BytecodeHelper.getClassInternalName(classNode.getSuperClass()); cv.visit( Opcodes.V1_3, classNode.getModifiers(), internalClassName, (String) null, internalBaseClassName, BytecodeHelper.getClassInternalNames(classNode.getInterfaces())); classNode.visitContents(this); for (Iterator iter = innerClasses.iterator(); iter.hasNext(); ) { ClassNode innerClass = (ClassNode) iter.next(); ClassNode innerClassType = innerClass; String innerClassInternalName = BytecodeHelper.getClassInternalName(innerClassType); String outerClassName = internalClassName; // default for inner classes MethodNode enclosingMethod = innerClass.getEnclosingMethod(); if (enclosingMethod != null) { // local inner classes do not specify the outer class name outerClassName = null; } cv.visitInnerClass( innerClassInternalName, outerClassName, innerClassType.getName(), innerClass.getModifiers()); } cv.visitEnd(); } catch (GroovyRuntimeException e) { e.setModule(classNode.getModule()); throw e; } }
/** {@inheritDoc} */ @Override public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { // Retrieve the class name className = name; super.visit(version, access, name, signature, superName, interfaces); }
@Override public void visit( int version, int access, String name, String signature, String superName, String[] interfaces) { this.ownClassSpec = name; this.classFileFormatVersion = version; super.visit(version, access, name, signature, superName, interfaces); }
public SkinnyMethodAdapter( ClassVisitor cv, int flags, String name, String signature, String something, String[] exceptions) { super(flags); setMethodVisitor(cv.visitMethod(flags, name, signature, something, exceptions)); this.cv = cv; this.name = name; }
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)); }