Java Code Examples for org.objectweb.asm.MethodVisitor#visitInsn()

The following examples show how to use org.objectweb.asm.MethodVisitor#visitInsn() . These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: yql-plus   File: ExpressionHandler.java    License: Apache License 2.0 6 votes vote down vote up
@Override
public BytecodeExpression in(Location loc, final BytecodeExpression left, final BytecodeExpression right) {
    return new BaseTypeExpression(BaseTypeAdapter.BOOLEAN) {
        @Override
        public void generate(CodeEmitter code) {
            Label done = new Label();
            Label anyIsNull = new Label();
            CodeEmitter.BinaryCoercion coerce = code.binaryCoercion(right, Collection.class, left, Object.class, anyIsNull, anyIsNull, anyIsNull);
            MethodVisitor mv = code.getMethodVisitor();
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Collection.class), "contains",
                    Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Object.class)), true);
            if (coerce.leftNullable || coerce.rightNullable) {
                mv.visitJumpInsn(Opcodes.GOTO, done);
                mv.visitLabel(anyIsNull);
                mv.visitInsn(Opcodes.ICONST_0);
                mv.visitLabel(done);
            }
        }
    };
}
 
Example 2
Source Project: DataLoader   File: DataLoaderTransform.java    License: Apache License 2.0 6 votes vote down vote up
private void testModifyClass(TransformInvocation transformInvocation) {
    try {
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
        cw.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC,
                "com.jeremyliao.dataloader.core.utils.GenericsUtils".replace('.', '/'),
                null, "java/lang/Object", null);
        {
            MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,
                    Const.INIT_METHOD, "()Ljava/lang/String;", null, null);
            mv.visitCode();
            mv.visitInsn(Opcodes.ARETURN);
            mv.visitMaxs(1, 0);
            mv.visitEnd();
        }
        cw.visitEnd();
        System.out.println(TAG + "code");
        System.out.println(TAG + "code: " + new String(cw.toByteArray()));
    } catch (Exception e) {

    }
}
 
Example 3
Source Project: yql-plus   File: ExpressionHandler.java    License: Apache License 2.0 6 votes vote down vote up
@Override
public BytecodeExpression matches(Location loc, final BytecodeExpression left, final BytecodeExpression right) {
    return new BaseTypeExpression(BaseTypeAdapter.BOOLEAN) {
        @Override
        public void generate(CodeEmitter code) {
            Label done = new Label();
            Label anyIsNull = new Label();
            CodeEmitter.BinaryCoercion coerce = code.binaryCoercion(right, Pattern.class, left, CharSequence.class, anyIsNull, anyIsNull, anyIsNull);
            MethodVisitor mv = code.getMethodVisitor();
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Pattern.class), "matcher",
                    Type.getMethodDescriptor(Type.getType(Matcher.class), Type.getType(CharSequence.class)), false);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Matcher.class), "matches",
                    Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            if (coerce.leftNullable || coerce.rightNullable) {
                mv.visitJumpInsn(Opcodes.GOTO, done);
                mv.visitLabel(anyIsNull);
                mv.visitInsn(Opcodes.ICONST_0);
                mv.visitLabel(done);
            }
        }
    };
}
 
Example 4
Source Project: AVM   File: CreateTest.java    License: MIT License 6 votes vote down vote up
private byte[] getByteCodeForClassWithoutSuperName() {
    ClassWriter classWriter = new ClassWriter(0);
    MethodVisitor methodVisitor;

    classWriter.visit(V10, ACC_PUBLIC | ACC_SUPER, "b/Main", null, null, null);

    classWriter.visitSource("Main.java", null);
    {
        methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        methodVisitor.visitCode();
        Label label0 = new Label();
        methodVisitor.visitLabel(label0);
        methodVisitor.visitLineNumber(3, label0);
        methodVisitor.visitVarInsn(ALOAD, 0);
        methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        methodVisitor.visitInsn(RETURN);
        methodVisitor.visitMaxs(1, 1);
        methodVisitor.visitEnd();
    }
    classWriter.visitEnd();

    return classWriter.toByteArray();
}
 
Example 5
Source Project: Despector   File: OperatorTests.java    License: MIT License 6 votes vote down vote up
@Test
public void testDiv() {
    TestMethodBuilder builder = new TestMethodBuilder("test_mth", "(III)V");
    MethodVisitor mv = builder.getGenerator();
    Label start = new Label();
    mv.visitLabel(start);
    Label end = new Label();
    mv.visitIntInsn(ILOAD, 1);
    mv.visitIntInsn(ILOAD, 2);
    mv.visitInsn(IDIV);
    mv.visitIntInsn(ISTORE, 0);
    mv.visitLabel(end);
    mv.visitInsn(RETURN);
    mv.visitLocalVariable("i", "I", null, start, end, 0);
    mv.visitLocalVariable("a", "I", null, start, end, 1);
    mv.visitLocalVariable("b", "I", null, start, end, 2);

    String insn = TestHelper.getAsString(builder.finish(), "test_mth");
    String good = "i = a / b;";
    Assert.assertEquals(good, insn);
}
 
Example 6
private static void generateArrayInitialization(MethodVisitor mv, String className, String fieldName, List<Integer> values) {
    if (values.isEmpty()) {
        return;
    }
    pushIntValue(mv, values.size());
    mv.visitIntInsn(NEWARRAY, T_INT);
    int idx = 0;
    for (Integer value : values) {
        mv.visitInsn(DUP);
        pushIntValue(mv, idx);
        mv.visitLdcInsn(value);
        mv.visitInsn(IASTORE);
        idx++;
    }
    mv.visitFieldInsn(PUTSTATIC, className, fieldName, "[I");
}
 
Example 7
Source Project: pitest   File: PrimitiveReturnsMutator.java    License: Apache License 2.0 6 votes vote down vote up
private static ZeroOperandMutation freturnMutation() {
  return new ZeroOperandMutation() {

    @Override
    public void apply(final int opcode, final MethodVisitor mv) {
      mv.visitInsn(Opcodes.POP);
      mv.visitInsn(Opcodes.FCONST_0);
      mv.visitInsn(Opcodes.FRETURN);
    }

    @Override
    public String describe(final int opCode, final MethodInfo methodInfo) {
      return "replaced float return with 0.0f for " + methodInfo.getDescription();
    }

  };
}
 
Example 8
Source Project: groovy   File: DgmConverter.java    License: Apache License 2.0 5 votes vote down vote up
private static void createConstructor(ClassWriter cw) {
    MethodVisitor mv;
    mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;Lorg/codehaus/groovy/reflection/CachedClass;Ljava/lang/Class;[Ljava/lang/Class;)V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitVarInsn(ALOAD, 3);
    mv.visitVarInsn(ALOAD, 4);
    mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/reflection/GeneratedMetaMethod", "<init>", "(Ljava/lang/String;Lorg/codehaus/groovy/reflection/CachedClass;Ljava/lang/Class;[Ljava/lang/Class;)V", false);
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
 
Example 9
Source Project: maple-ir   File: CastExpr.java    License: GNU General Public License v3.0 5 votes vote down vote up
@Override
public void toCode(MethodVisitor visitor, BytecodeFrontend assembler) {
	expression.toCode(visitor, assembler);
	if (TypeUtils.isObjectRef(getType())) {
		visitor.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName());
	} else {
		int[] instructions = TypeUtils.getPrimitiveCastOpcodes(expression.getType(), type);
		for (int i = 0; i < instructions.length; i++) {
			visitor.visitInsn(instructions[i]);
		}
	}
}
 
Example 10
Source Project: AVM   File: StubGenerator.java    License: MIT License 5 votes vote down vote up
/**
 * Generates and returns the bytecode for a "legacy-style" exception class.  That is, the kind which have their own getCause and getException implementations.
 * In our implementation, we will strictly wrap the super-class, and append a getException method.
 * 
 * @param name The name of the class to generate.
 * @param superName The name of the superclass.
 * @return The bytecode for the new class.
 */
public static byte[] generateLegacyExceptionClass(String name, String superName) {
    ClassWriter out = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    
    // This class only exists to be a type - the superclasses always do everything.
    // (common access for all classes we generate - public and "super", meaning post-1.1 invokestatic).
    int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER;
    // We ignore generics, so null signature.
    String signature = null;
    // We implement no interfaces.
    String[] interfaces = new String[0];
    out.visit(CLASS_VERSION, access, name, signature, superName, interfaces);
    
    // Generate the constructors.
    populateExceptionConstructors(out, superName);
    
    // Generate the getException method.
    {
        // NOTE:  These methods need to exist with the UserClassMappingVisitor.mapMethodName("" prefixes, since the shadow library is post-shadow.
        String returnThrowable = "()L" + PackageConstants.kShadowSlashPrefix + "java/lang/Throwable;";
        // This method does not require a charge energy call since it's calling avm_getCause and the billing is done there
        MethodVisitor methodVisitor = out.visitMethod(Opcodes.ACC_PUBLIC, NamespaceMapper.mapMethodName("getException"), returnThrowable, null, null);
        methodVisitor.visitCode();
        methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, name, NamespaceMapper.mapMethodName("getCause"), returnThrowable, false);
        methodVisitor.visitInsn(Opcodes.ARETURN);
        methodVisitor.visitMaxs(1, 1);
        methodVisitor.visitEnd();
    }
    
    // Finish this and dump the bytes.
    out.visitEnd();
    return out.toByteArray();
}
 
Example 11
Source Project: Despector   File: WhileTests.java    License: MIT License 5 votes vote down vote up
@Test
public void testIfThenWhileInverse() {
    // the target of an if preceeding a while which has been made in the
    // inverse manner will be optimized to point to the condition of the
    // while loop rather than the start of the while loop
    TestMethodBuilder builder = new TestMethodBuilder("test_mth", "(IZ)V");
    MethodVisitor mv = builder.getGenerator();
    Label start = new Label();
    mv.visitLabel(start);
    Label end = new Label();
    Label l1 = new Label();
    Label l2 = new Label();
    mv.visitVarInsn(ILOAD, 1);
    mv.visitJumpInsn(IFEQ, l2);
    mv.visitInsn(RETURN);
    mv.visitLabel(l1);
    mv.visitMethodInsn(INVOKESTATIC, THIS_TYPE.getInternalName(), "body", "()V", false);
    mv.visitLabel(l2);
    mv.visitVarInsn(ILOAD, 0);
    mv.visitInsn(ICONST_5);
    mv.visitJumpInsn(IF_ICMPLT, l1);
    mv.visitLabel(end);
    mv.visitInsn(RETURN);
    mv.visitLocalVariable("i", "I", null, start, end, 0);
    mv.visitLocalVariable("a", "Z", null, start, end, 1);

    String insn = TestHelper.getAsString(builder.finish(), "test_mth");
    String good = "if (a) {\n"
            + "    return;\n"
            + "}\n\n"
            + "while (i < 5) {\n"
            + "    org.spongepowered.test.decompile.WhileTests.body();\n"
            + "}";
    Assert.assertEquals(good, insn);
}
 
Example 12
Source Project: shrinker   File: ShrinkRClassVisitor.java    License: Apache License 2.0 5 votes vote down vote up
private static void pushInt(MethodVisitor mv, int i) {
    if (0 <= i && i <= 5) {
        mv.visitInsn(Opcodes.ICONST_0 + i); //  ICONST_0 ~ ICONST_5
    } else if (i <= Byte.MAX_VALUE) {
        mv.visitIntInsn(Opcodes.BIPUSH, i);
    } else if (i <= Short.MAX_VALUE) {
        mv.visitIntInsn(Opcodes.SIPUSH, i);
    } else {
        mv.visitLdcInsn(i);
    }
}
 
Example 13
Source Project: yql-plus   File: ExpressionHandler.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public BytecodeExpression list(Location loc, final List<BytecodeExpression> args) {
    List<TypeWidget> types = Lists.newArrayList();
    for (BytecodeExpression e : args) {
        types.add(e.getType());
    }
    final TypeWidget unified = unify(types).boxed();
    final ListTypeWidget out = new ListTypeWidget(NotNullableTypeWidget.create(unified));
    return new BaseTypeExpression(out) {
        @Override
        public void generate(CodeEmitter code) {
            MethodVisitor mv = code.getMethodVisitor();
            code.exec(out.construct(constant(args.size())));
            for (BytecodeExpression expr : args) {
                Label skip = new Label();
                mv.visitInsn(Opcodes.DUP);
                code.exec(expr);
                final TypeWidget type = expr.getType();
                boolean nullable = code.cast(unified, type, skip);
                mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Collection.class), "add", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Object.class)), true);
                if (nullable) {
                    // we're either going to POP the DUPed List OR the result of add
                    mv.visitLabel(skip);
                }
                mv.visitInsn(Opcodes.POP);
            }
        }
    };
}
 
Example 14
Source Project: bazel   File: GenZipWithEntries.java    License: Apache License 2.0 5 votes vote down vote up
public static byte[] dump(String name) {
  ClassWriter cw = new ClassWriter(0);
  cw.visit(52, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, name, null, "java/lang/Object", null);
  {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
    mv.visitInsn(Opcodes.RETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
  }
  cw.visitEnd();
  return cw.toByteArray();
}
 
Example 15
Source Project: groovy   File: OperandStack.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * swap two top level operands
 */
public void swap() {
    MethodVisitor mv = controller.getMethodVisitor();
    int size = stack.size();
    ClassNode b = stack.get(size-1);
    ClassNode a = stack.get(size-2);
    //        dup_x1:     --- 
    //        dup_x2:     aab  -> baab
    //        dup2_x1:    abb  -> bbabb
    //        dup2_x2:    aabb -> bbaabb
    //        b = top element, a = element under b
    //        top element at right
    if (isTwoSlotType(a)) { // aa
        if (isTwoSlotType(b)) { // aabb
            // aabb -> bbaa
            mv.visitInsn(DUP2_X2);   // bbaabb
            mv.visitInsn(POP2);      // bbaa
        } else {
            // aab -> baa
            mv.visitInsn(DUP_X2);   // baab
            mv.visitInsn(POP);      // baa
        }
    } else { // a
        if (isTwoSlotType(b)) { //abb
            // abb -> bba
            mv.visitInsn(DUP2_X1);   // bbabb
            mv.visitInsn(POP2);      // bba
        } else {
            // ab -> ba
            mv.visitInsn(SWAP);
        }
    }
    stack.set(size-1,a);
    stack.set(size-2,b);
}
 
Example 16
Source Project: AVM   File: InterfaceFieldClassGeneratorTest.java    License: MIT License 5 votes vote down vote up
public static byte[] getNestedInterfaceCalledFIELDSLevelTwo() {

        ClassWriter classWriter = new ClassWriter(0);
        FieldVisitor fieldVisitor;
        MethodVisitor methodVisitor;

        classWriter.visit(V10, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, "NestedInterfaces$FIELDS$FIELDS", null, "java/lang/Object", null);

        classWriter.visitSource("NestedInterfaces.java", null);

        classWriter.visitInnerClass("NestedInterfaces$FIELDS", "NestedInterfaces", "FIELDS", ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);

        classWriter.visitInnerClass("NestedInterfaces$FIELDS$FIELDS", "NestedInterfaces$FIELDS", "FIELDS", ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE);

        {
            fieldVisitor = classWriter.visitField(ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "b", "I", null, null);
            fieldVisitor.visitEnd();
        }
        {
            methodVisitor = classWriter.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
            methodVisitor.visitCode();
            Label label0 = new Label();
            methodVisitor.visitLabel(label0);
            methodVisitor.visitLineNumber(7, label0);
            methodVisitor.visitTypeInsn(NEW, "java/lang/Object");
            methodVisitor.visitInsn(DUP);
            methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
            methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false);
            methodVisitor.visitFieldInsn(PUTSTATIC, "NestedInterfaces$FIELDS$FIELDS", "b", "I");
            methodVisitor.visitInsn(RETURN);
            methodVisitor.visitMaxs(2, 0);
            methodVisitor.visitEnd();
        }
        classWriter.visitEnd();

        return classWriter.toByteArray();
    }
 
Example 17
Source Project: yql-plus   File: ArrayIndexAdapter.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public BytecodeSequence iterate(final BytecodeExpression target, final AssignableValue item, final IterateLoop loop) {
    return new BytecodeSequence() {
        @Override
        public void generate(CodeEmitter start) {
            CodeEmitter code = start.createScope();
            final AssignableValue count = code.allocate(BaseTypeAdapter.INT32);
            final AssignableValue idx = code.allocate(BaseTypeAdapter.INT32);
            Label done = new Label();
            Label next = new Label();
            MethodVisitor mv = code.getMethodVisitor();
            BytecodeExpression tgt = code.evaluateOnce(target);
            code.exec(tgt);
            code.nullTest(tgt.getType(), done);
            mv.visitInsn(Opcodes.ARRAYLENGTH);
            code.exec(count.write(BaseTypeAdapter.INT32));
            code.emitIntConstant(0);
            code.exec(idx.write(BaseTypeAdapter.INT32));
            mv.visitLabel(next);
            code.exec(count.read());
            mv.visitJumpInsn(Opcodes.IFEQ, done);
            code.inc(count, -1);
            code.exec(tgt);
            code.exec(idx.read());
            code.getMethodVisitor().visitInsn(ownerType.getJVMType().getOpcode(Opcodes.IALOAD));
            code.inc(idx, 1);
            code.nullTest(valueType, next);
            code.exec(item.write(item.getType()));
            loop.item(code, item.read(), done, next);
            mv.visitJumpInsn(Opcodes.GOTO, next);
            mv.visitLabel(done);
            code.endScope();
        }
    };
}
 
Example 18
Source Project: atlas   File: AsmExample.java    License: Apache License 2.0 4 votes vote down vote up
public static void main(String[] args) throws IOException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException {

        ClassReader cr = new ClassReader(Foo.class.getName());
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
        ClassVisitor cv = new MethodChangeClassAdapter(cw);
        cr.accept(cv, Opcodes.ASM4);

        //Add a new method  
        MethodVisitor mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
                                          "add",
                                          "([Ljava/lang/String;)V",
                                          null,
                                          null);
        // pushes the 'out' field (of type PrintStream) of the System class  
        mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        // pushes the "Hello World!" String constant  
        mw.visitLdcInsn("this is add method print!");
        // invokes the 'println' method (defined in the PrintStream class)  
        mw.visitMethodInsn(INVOKEVIRTUAL,
                           "java/io/PrintStream",
                           "println",
                           "(Ljava/lang/String;)V");
        mw.visitInsn(RETURN);
        // this code uses a maximum of two stack elements and two local  
        // variables  
        mw.visitMaxs(0, 0);
        mw.visitEnd();

        // gets the bytecode of the Example class, and loads it dynamically  
        byte[] code = cw.toByteArray();

        AsmExample loader = new AsmExample();
        Class<?> exampleClass = loader.defineClass(Foo.class.getName(), code, 0, code.length);

        for (Method method : exampleClass.getMethods()) {
            System.out.println(method);
        }

        System.out.println("*************");

        // uses the dynamically generated class to print 'Helloworld'  
        exampleClass.getMethods()[0].invoke(null);  //Change the method content by calling the changeMethodContent

        System.out.println("*************");

        exampleClass.getMethods()[1].invoke(null); //Call execute to modify the method name

        // gets the bytecode of the Example class, and loads it dynamically  

        FileOutputStream fos = new FileOutputStream("e:\\logs\\Example.class");
        fos.write(code);
        fos.close();
    }
 
Example 19
private <T extends Script> Class<? extends T> generateEmptyScriptClass(Class<T> type) {
    ClassWriter visitor = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    String typeName = type.getName() + "_Decorated";
    Type generatedType = Type.getType("L" + typeName.replaceAll("\\.", "/") + ";");
    Type superclassType = Type.getType(type);
    visitor.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, generatedType.getInternalName(), null,
            superclassType.getInternalName(), new String[0]);

    // Constructor

    String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[0]);
    MethodVisitor methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructorDescriptor, null,
            new String[0]);
    methodVisitor.visitCode();

    // super()
    methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
    methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>",
            constructorDescriptor);

    methodVisitor.visitInsn(Opcodes.RETURN);
    methodVisitor.visitMaxs(0, 0);
    methodVisitor.visitEnd();

    // run() method

    String runDesciptor = Type.getMethodDescriptor(Type.getType(Object.class), new Type[0]);
    methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "run", runDesciptor, null, new String[0]);
    methodVisitor.visitCode();

    // return null
    methodVisitor.visitInsn(Opcodes.ACONST_NULL);

    methodVisitor.visitInsn(Opcodes.ARETURN);
    methodVisitor.visitMaxs(0, 0);
    methodVisitor.visitEnd();

    visitor.visitEnd();

    byte[] bytecode = visitor.toByteArray();
    JavaMethod<ClassLoader, Class> method = JavaReflectionUtil.method(ClassLoader.class, Class.class, "defineClass", String.class, byte[].class, int.class, int.class);
    @SuppressWarnings("unchecked")
    Class<T> clazz = method.invoke(type.getClassLoader(), typeName, bytecode, 0, bytecode.length);
    return clazz;
}
 
Example 20
Source Project: groovy   File: ClosureWriter.java    License: Apache License 2.0 4 votes vote down vote up
public void writeClosure(final ClosureExpression expression) {
    CompileStack compileStack = controller.getCompileStack();
    MethodVisitor mv = controller.getMethodVisitor();
    ClassNode classNode = controller.getClassNode();
    AsmClassGenerator acg = controller.getAcg();

    // generate closure as public class to make sure it can be properly invoked by classes of the
    // Groovy runtime without circumventing JVM access checks (see CachedMethod for example).
    int mods = ACC_PUBLIC | ACC_FINAL;
    if (classNode.isInterface()) {
        mods |= ACC_STATIC;
    }
    ClassNode closureClass = getOrAddClosureClass(expression, mods);
    String closureClassinternalName = BytecodeHelper.getClassInternalName(closureClass);
    List<ConstructorNode> constructors = closureClass.getDeclaredConstructors();
    ConstructorNode node = constructors.get(0);

    Parameter[] localVariableParams = node.getParameters();

    mv.visitTypeInsn(NEW, closureClassinternalName);
    mv.visitInsn(DUP);
    if (controller.isStaticMethod() || compileStack.isInSpecialConstructorCall()) {
        (new ClassExpression(classNode)).visit(acg);
        (new ClassExpression(controller.getOutermostClass())).visit(acg);
    } else {
        mv.visitVarInsn(ALOAD, 0);
        controller.getOperandStack().push(ClassHelper.OBJECT_TYPE);
        loadThis();
    }

    // now let's load the various parameters we're passing
    // we start at index 2 because the first variable we pass
    // is the owner instance and at this point it is already
    // on the stack
    for (int i = 2; i < localVariableParams.length; i++) {
        Parameter param = localVariableParams[i];
        String name = param.getName();
        loadReference(name, controller);
        if (param.getNodeMetaData(ClosureWriter.UseExistingReference.class)==null) {
            param.setNodeMetaData(ClosureWriter.UseExistingReference.class,Boolean.TRUE);
        }
    }

    // we may need to pass in some other constructors
    //cv.visitMethodInsn(INVOKESPECIAL, innerClassinternalName, "<init>", prototype + ")V");
    mv.visitMethodInsn(INVOKESPECIAL, closureClassinternalName, "<init>", BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, localVariableParams), false);
    controller.getOperandStack().replace(ClassHelper.CLOSURE_TYPE, localVariableParams.length);
}