Search in sources :

Example 16 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project eclipse.themes.darker by jinmingjian.

the class DarkerWeavingHook method transform.

public void transform(WovenClass wovenClass) {
    byte[] bytes = wovenClass.getBytes();
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    cr.accept(cw, 0);
    Method md = Method.getMethod("org.eclipse.swt.graphics.Color getForeground ()");
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, md.getName(), md.getDescriptor(), null, null);
    final GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, md, mv);
    final Label LABEL_SKIP_CALL_TO_SUPER = new Label();
    final Label LABEL_LOOP_CMP = new Label();
    final Label LABEL_LOOP_START = new Label();
    mg.newInstance(Type.getType(Exception.class));
    mg.dup();
    mg.invokeConstructor(Type.getType(Exception.class), Method.getMethod("void <init> ()"));
    mg.invokeVirtual(Type.getType(Exception.class), Method.getMethod("StackTraceElement[] getStackTrace ()"));
    mg.storeLocal(1, Type.getType(StackTraceElement[].class));
    mg.push(10);
    mg.storeLocal(2, Type.getType(int.class));
    mg.goTo(LABEL_LOOP_CMP);
    mg.mark(LABEL_LOOP_START);
    mg.loadLocal(1);
    mg.loadLocal(2);
    mg.arrayLoad(Type.getType(StackTraceElement.class));
    mg.invokeVirtual(Type.getType(StackTraceElement.class), Method.getMethod("String getClassName ()"));
    mg.push("Dialog");
    mg.invokeVirtual(Type.getType(String.class), Method.getMethod("int indexOf (String)"));
    mg.push(-1);
    mg.ifICmp(GeneratorAdapter.EQ, LABEL_SKIP_CALL_TO_SUPER);
    //    //XXX: DEBUG
    //    mg.getStatic(Type.getType(System.class), "out", Type.getType(java.io.PrintStream.class));
    //    mg.push("2");
    //    mg.invokeVirtual(Type.getType(java.io.PrintStream.class), Method.getMethod("void println (String)"));
    //    //XXX: DEBUG
    mg.loadThis();
    mg.invokeConstructor(Type.getType("Lorg/eclipse/swt/widgets/Control;"), Method.getMethod("org.eclipse.swt.graphics.Color getForeground ()"));
    mg.returnValue();
    mg.mark(LABEL_SKIP_CALL_TO_SUPER);
    mg.iinc(2, 1);
    mg.mark(LABEL_LOOP_CMP);
    mg.loadLocal(2);
    mg.loadLocal(1);
    mg.arrayLength();
    mg.ifICmp(GeneratorAdapter.LT, LABEL_LOOP_START);
    mg.loadThis();
    mg.invokeVirtual(Type.getType("Lorg/eclipse/swt/custom/CLabel;"), Method.getMethod("org.eclipse.swt.widgets.Display getDisplay ()"));
    mg.push(1);
    mg.invokeVirtual(Type.getType("Lorg/eclipse/swt/widgets/Display;"), Method.getMethod("org.eclipse.swt.graphics.Color getSystemColor (int)"));
    mg.returnValue();
    mg.endMethod();
    cw.visitEnd();
    wovenClass.setBytes(cw.toByteArray());
}
Also used : Label(org.objectweb.asm.Label) ClassReader(org.objectweb.asm.ClassReader) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method) ClassWriter(org.objectweb.asm.ClassWriter) IOException(java.io.IOException) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 17 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project MinecraftForge by MinecraftForge.

the class ASMTransformerWrapper method makeWrapper.

private static byte[] makeWrapper(String fileName) {
    if (!wrapperModMap.containsKey(fileName) || !wrapperParentMap.containsKey(fileName) || !fileName.endsWith(".class")) {
        throw new IllegalArgumentException("makeWrapper called with strange argument: " + fileName);
    }
    String name = fileName.substring(0, fileName.length() - ".class".length());
    try {
        Type wrapper = Type.getType(TransformerWrapper.class);
        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        writer.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, name, null, wrapper.getInternalName(), null);
        Method m = Method.getMethod("void <init> ()");
        GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, writer);
        mg.loadThis();
        mg.invokeConstructor(wrapper, m);
        mg.returnValue();
        mg.endMethod();
        m = Method.getMethod("java.lang.String getParentClass ()");
        mg = new GeneratorAdapter(Opcodes.ACC_PROTECTED, m, null, null, writer);
        mg.push(wrapperParentMap.get(fileName));
        mg.returnValue();
        mg.endMethod();
        m = Method.getMethod("java.lang.String getCoreMod ()");
        mg = new GeneratorAdapter(Opcodes.ACC_PROTECTED, m, null, null, writer);
        mg.push(wrapperModMap.get(fileName));
        mg.returnValue();
        mg.endMethod();
        writer.visitEnd();
        return writer.toByteArray();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : Type(org.objectweb.asm.Type) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method) ClassWriter(org.objectweb.asm.ClassWriter) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException)

Example 18 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project robolectric by robolectric.

the class ProxyMaker method createProxyFactory.

<T> Factory createProxyFactory(Class<T> targetClass) {
    Type targetType = Type.getType(targetClass);
    String targetName = targetType.getInternalName();
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    writer.visit(V1_7, ACC_PUBLIC | ACC_SUPER | ACC_FINAL, PROXY_NAME, null, targetName, null);
    writer.visitField(ACC_PUBLIC, TARGET_FIELD, targetType.getDescriptor(), null, null);
    for (java.lang.reflect.Method method : targetClass.getMethods()) {
        if (!shouldProxy(method))
            continue;
        Method proxyMethod = Method.getMethod(method);
        GeneratorAdapter m = new GeneratorAdapter(ACC_PUBLIC, Method.getMethod(method), null, null, writer);
        m.loadThis();
        m.getField(PROXY_TYPE, TARGET_FIELD, targetType);
        m.loadArgs();
        String targetMethod = methodMapper.getName(targetClass.getName(), method.getName());
        // In Java 8 we could use invokespecial here but not in 7, from jvm spec:
        // If an invokespecial instruction names a method which is not an instance
        // initialization method, then the type of the target reference on the operand
        // stack must be assignment compatible with the current class (JLS ยง5.2).
        m.visitMethodInsn(INVOKEVIRTUAL, targetName, targetMethod, proxyMethod.getDescriptor(), false);
        m.returnValue();
        m.endMethod();
    }
    writer.visitEnd();
    final Class<?> proxyClass = UNSAFE.defineAnonymousClass(targetClass, writer.toByteArray(), null);
    try {
        final MethodHandle setter = LOOKUP.findSetter(proxyClass, TARGET_FIELD, targetClass);
        return new Factory() {

            @Override
            public <E> E createProxy(Class<E> targetClass, E target) {
                try {
                    Object proxy = UNSAFE.allocateInstance(proxyClass);
                    setter.invoke(proxy, target);
                    return targetClass.cast(proxy);
                } catch (Throwable t) {
                    throw new AssertionError(t);
                }
            }
        };
    } catch (IllegalAccessException | NoSuchFieldException e) {
        throw new AssertionError(e);
    }
}
Also used : Method(org.objectweb.asm.commons.Method) ClassWriter(org.objectweb.asm.ClassWriter) Type(org.objectweb.asm.Type) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) MethodHandle(java.lang.invoke.MethodHandle)

Example 19 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project robovm by robovm.

the class LambdaClassGenerator method createForwardingMethod.

private void createForwardingMethod(SootClass caller, String lambdaClassName, ClassWriter cw, String name, List<Type> parameters, Type returnType, List<Type> invokedParameters, SootMethodType samMethodType, SootMethodHandle implMethod, SootMethodType instantiatedMethodType, boolean isBridgeMethod) {
    String descriptor = Types.getDescriptor(parameters, returnType);
    String implClassName = implMethod.getMethodRef().declaringClass().getName().replace('.', '/');
    int accessFlags = ACC_PUBLIC | (isBridgeMethod ? ACC_BRIDGE : 0);
    MethodVisitor mv = cw.visitMethod(accessFlags, name, descriptor, null, null);
    mv.visitCode();
    // figure out the invoke op code for the lambda implementation
    // as well as if it's an instance method.
    int invokeOpCode = INVOKESTATIC;
    boolean isInstanceMethod = false;
    switch(implMethod.getReferenceKind()) {
        case SootMethodHandle.REF_invokeInterface:
            invokeOpCode = INVOKEINTERFACE;
            isInstanceMethod = true;
            break;
        case SootMethodHandle.REF_invokeSpecial:
            invokeOpCode = INVOKESPECIAL;
            isInstanceMethod = true;
            break;
        case SootMethodHandle.REF_newInvokeSpecial:
            invokeOpCode = INVOKESPECIAL;
            break;
        case SootMethodHandle.REF_invokeStatic:
            invokeOpCode = INVOKESTATIC;
            break;
        case SootMethodHandle.REF_invokeVirtual:
            invokeOpCode = INVOKEVIRTUAL;
            isInstanceMethod = true;
            break;
        default:
            throw new CompilerException("Unknown invoke type: " + implMethod.getReferenceKind());
    }
    GeneratorAdapter caster = new GeneratorAdapter(mv, accessFlags, name, descriptor);
    // push the arguments
    pushArguments(caller, lambdaClassName, mv, caster, parameters, invokedParameters, implMethod, instantiatedMethodType, isInstanceMethod);
    // generate a descriptor for the lambda implementation
    // to invoke based on the parameters. If the lambda
    // is an instance method, we need to remove the first
    // parameter for the descriptor generation as it's
    // not part of the method signature.
    String implDescriptor = null;
    List<Type> paramTypes = new ArrayList<Type>(implMethod.getMethodType().getParameterTypes());
    if (isInstanceMethod)
        paramTypes.remove(0);
    implDescriptor = Types.getDescriptor(paramTypes, implMethod.getMethodType().getReturnType());
    // call the lambda implementation
    mv.visitMethodInsn(invokeOpCode, implClassName, implMethod.getMethodRef().name(), implDescriptor, invokeOpCode == INVOKEINTERFACE);
    // emit the return instruction based on the return type
    createForwardingMethodReturn(mv, caster, returnType, samMethodType, implMethod, instantiatedMethodType);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
}
Also used : RefType(soot.RefType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) Type(soot.Type) PrimType(soot.PrimType) VoidType(soot.VoidType) LongType(soot.LongType) SootMethodType(soot.SootMethodType) ArrayList(java.util.ArrayList) CompilerException(org.robovm.compiler.CompilerException) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 20 with GeneratorAdapter

use of org.objectweb.asm.commons.GeneratorAdapter in project aries by apache.

the class AbstractWovenProxyAdapter method writeStaticInitMethod.

/**
   * Create fields and an initialiser for {@link java.lang.reflect.Method}
   * objects in our class
   */
private final void writeStaticInitMethod() {
    for (String methodStaticFieldName : transformedMethods.keySet()) {
        // add a private static field for the method
        cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, methodStaticFieldName, METHOD_TYPE.getDescriptor(), null, null).visitEnd();
    }
    GeneratorAdapter staticAdapter = new GeneratorAdapter(staticInitMethodFlags, staticInitMethod, null, null, cv);
    for (Entry<String, TypeMethod> entry : transformedMethods.entrySet()) {
        // Add some more code to the static initializer
        TypeMethod m = entry.getValue();
        Type[] targetMethodParameters = m.method.getArgumentTypes();
        String methodStaticFieldName = entry.getKey();
        Label beginPopulate = staticAdapter.newLabel();
        Label endPopulate = staticAdapter.newLabel();
        Label catchHandler = staticAdapter.newLabel();
        staticAdapter.visitTryCatchBlock(beginPopulate, endPopulate, catchHandler, THROWABLE_INAME);
        staticAdapter.mark(beginPopulate);
        staticAdapter.push(m.declaringClass);
        // push the method name string arg onto the stack
        staticAdapter.push(m.method.getName());
        // create an array of the method parm class[] arg
        staticAdapter.push(targetMethodParameters.length);
        staticAdapter.newArray(CLASS_TYPE);
        int index = 0;
        for (Type t : targetMethodParameters) {
            staticAdapter.dup();
            staticAdapter.push(index);
            staticAdapter.push(t);
            staticAdapter.arrayStore(CLASS_TYPE);
            index++;
        }
        // invoke the getMethod
        staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getDeclaredMethod", METHOD_TYPE, new Type[] { STRING_TYPE, CLASS_ARRAY_TYPE }));
        // store the reflected method in the static field
        staticAdapter.putStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
        Label afterCatch = staticAdapter.newLabel();
        staticAdapter.mark(endPopulate);
        staticAdapter.goTo(afterCatch);
        staticAdapter.mark(catchHandler);
        // We don't care about the exception, so pop it off
        staticAdapter.pop();
        // store the reflected method in the static field
        staticAdapter.visitInsn(ACONST_NULL);
        staticAdapter.putStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
        staticAdapter.mark(afterCatch);
    }
    staticAdapter.returnValue();
    staticAdapter.endMethod();
}
Also used : Type(org.objectweb.asm.Type) Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method)

Aggregations

GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)33 Method (org.objectweb.asm.commons.Method)24 Type (org.objectweb.asm.Type)14 Label (org.objectweb.asm.Label)8 ClassWriter (org.objectweb.asm.ClassWriter)7 MethodVisitor (org.objectweb.asm.MethodVisitor)7 IOException (java.io.IOException)5 ClassReader (org.objectweb.asm.ClassReader)5 ClassVisitor (org.objectweb.asm.ClassVisitor)4 Schema (co.cask.cdap.api.data.schema.Schema)3 TypeToken (com.google.common.reflect.TypeToken)2 InvocationHandler (java.lang.reflect.InvocationHandler)2 ArrayList (java.util.ArrayList)2 Set (java.util.Set)2 SchemaHash (co.cask.cdap.api.data.schema.SchemaHash)1 MetricsContext (co.cask.cdap.api.metrics.MetricsContext)1 Encoder (co.cask.cdap.common.io.Encoder)1 Throwables (com.google.common.base.Throwables)1 Sets (com.google.common.collect.Sets)1 File (java.io.File)1