Example usage for org.objectweb.asm Opcodes GETFIELD

List of usage examples for org.objectweb.asm Opcodes GETFIELD

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes GETFIELD.

Prototype

int GETFIELD

To view the source code for org.objectweb.asm Opcodes GETFIELD.

Click Source Link

Usage

From source file:com.android.tools.layoutlib.create.DelegateMethodAdapter.java

License:Apache License

/**
 * Generates the new code for the method.
 * <p/>//from  www . java 2  s .c  o m
 * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
 * (since they have no code to visit).
 * <p/>
 * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
 * return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
 * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
 * this method will be invoked from {@link MethodVisitor#visitEnd()}.
 */
public void generateCode() {
    /*
     * The goal is to generate a call to a static delegate method.
     * If this method is non-static, the first parameter will be 'this'.
     * All the parameters must be passed and then the eventual return type returned.
     *
     * Example, let's say we have a method such as
     *   public void method_1(int a, Object b, ArrayList<String> c) { ... }
     *
     * We'll want to create a body that calls a delegate method like this:
     *   TheClass_Delegate.method_1(this, a, b, c);
     *
     * If the method is non-static and the class name is an inner class (e.g. has $ in its
     * last segment), we want to push the 'this' of the outer class first:
     *   OuterClass_InnerClass_Delegate.method_1(
     *     OuterClass.this,
     *     OuterClass$InnerClass.this,
     *     a, b, c);
     *
     * Only one level of inner class is supported right now, for simplicity and because
     * we don't need more.
     *
     * The generated class name is the current class name with "_Delegate" appended to it.
     * One thing to realize is that we don't care about generics -- since generic types
     * are erased at runtime, they have no influence on the method name being called.
     */

    // Add our annotation
    AnnotationVisitor aw = mParentVisitor.visitAnnotation(
            Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(), true); // visible at runtime
    aw.visitEnd();

    if (!mVisitCodeCalled) {
        // If this is a direct call to generateCode() as done by DelegateClassAdapter
        // for natives, visitCode() hasn't been called yet.
        mParentVisitor.visitCode();
        mVisitCodeCalled = true;
    }

    ArrayList<Type> paramTypes = new ArrayList<Type>();
    String delegateClassName = mClassName + DELEGATE_SUFFIX;
    boolean pushedArg0 = false;
    int maxStack = 0;

    // For an instance method (e.g. non-static), push the 'this' preceded
    // by the 'this' of any outer class, if any.
    if (!mIsStatic) {
        // Check if the last segment of the class name has inner an class.
        // Right now we only support one level of inner classes.
        int slash = mClassName.lastIndexOf('/');
        int dol = mClassName.lastIndexOf('$');
        if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
            String outerClass = mClassName.substring(0, dol);
            Type outerType = Type.getObjectType(outerClass);

            // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
            delegateClassName = delegateClassName.replace('$', '_');

            // The first-level inner class has a package-protected member called 'this$0'
            // that points to the outer class.

            // Push this.getField("this$0") on the call stack.
            mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0); // var 0 = this
            mParentVisitor.visitFieldInsn(Opcodes.GETFIELD, mClassName, // class where the field is defined
                    "this$0", // field name
                    outerType.getDescriptor()); // type of the field
            maxStack++;
            paramTypes.add(outerType);
        }

        // Push "this" for the instance method, which is always ALOAD 0
        mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
        maxStack++;
        pushedArg0 = true;
        paramTypes.add(Type.getObjectType(mClassName));
    }

    // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
    Type[] argTypes = Type.getArgumentTypes(mDesc);
    int maxLocals = pushedArg0 ? 1 : 0;
    for (Type t : argTypes) {
        int size = t.getSize();
        mParentVisitor.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
        maxLocals += size;
        maxStack += size;
        paramTypes.add(t);
    }

    // Construct the descriptor of the delegate based on the parameters
    // we pushed on the call stack. The return type remains unchanged.
    String desc = Type.getMethodDescriptor(Type.getReturnType(mDesc),
            paramTypes.toArray(new Type[paramTypes.size()]));

    // Invoke the static delegate
    mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, delegateClassName, mMethodName, desc);

    Type returnType = Type.getReturnType(mDesc);
    mParentVisitor.visitInsn(returnType.getOpcode(Opcodes.IRETURN));

    mParentVisitor.visitMaxs(maxStack, maxLocals);
    mParentVisitor.visitEnd();

    // For debugging now. Maybe we should collect these and store them in
    // a text file for helping create the delegates. We could also compare
    // the text file to a golden and break the build on unsupported changes
    // or regressions. Even better we could fancy-print something that looks
    // like the expected Java method declaration.
    mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
}

From source file:com.android.tools.layoutlib.create.DelegateMethodAdapter2.java

License:Apache License

/**
 * Generates the new code for the method.
 * <p/>/*from  w  ww .j ava 2s  . c  om*/
 * For native methods, this must be invoked directly by {@link DelegateClassAdapter}
 * (since they have no code to visit).
 * <p/>
 * Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
 * return this instance of {@link DelegateMethodAdapter2} and let the normal visitor pattern
 * invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
 * this method will be invoked from {@link MethodVisitor#visitEnd()}.
 */
public void generateDelegateCode() {
    /*
     * The goal is to generate a call to a static delegate method.
     * If this method is non-static, the first parameter will be 'this'.
     * All the parameters must be passed and then the eventual return type returned.
     *
     * Example, let's say we have a method such as
     *   public void myMethod(int a, Object b, ArrayList<String> c) { ... }
     *
     * We'll want to create a body that calls a delegate method like this:
     *   TheClass_Delegate.myMethod(this, a, b, c);
     *
     * If the method is non-static and the class name is an inner class (e.g. has $ in its
     * last segment), we want to push the 'this' of the outer class first:
     *   OuterClass_InnerClass_Delegate.myMethod(
     *     OuterClass.this,
     *     OuterClass$InnerClass.this,
     *     a, b, c);
     *
     * Only one level of inner class is supported right now, for simplicity and because
     * we don't need more.
     *
     * The generated class name is the current class name with "_Delegate" appended to it.
     * One thing to realize is that we don't care about generics -- since generic types
     * are erased at build time, they have no influence on the method name being called.
     */

    // Add our annotation
    AnnotationVisitor aw = mDelWriter.visitAnnotation(
            Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(), true); // visible at runtime
    if (aw != null) {
        aw.visitEnd();
    }

    mDelWriter.visitCode();

    if (mDelegateLineNumber != null) {
        Object[] p = mDelegateLineNumber;
        mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
    }

    ArrayList<Type> paramTypes = new ArrayList<Type>();
    String delegateClassName = mClassName + DELEGATE_SUFFIX;
    boolean pushedArg0 = false;
    int maxStack = 0;

    // Check if the last segment of the class name has inner an class.
    // Right now we only support one level of inner classes.
    Type outerType = null;
    int slash = mClassName.lastIndexOf('/');
    int dol = mClassName.lastIndexOf('$');
    if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
        String outerClass = mClassName.substring(0, dol);
        outerType = Type.getObjectType(outerClass);

        // Change a delegate class name to "com/foo/Outer_Inner_Delegate"
        delegateClassName = delegateClassName.replace('$', '_');
    }

    // For an instance method (e.g. non-static), push the 'this' preceded
    // by the 'this' of any outer class, if any.
    if (!mIsStatic) {

        if (outerType != null) {
            // The first-level inner class has a package-protected member called 'this$0'
            // that points to the outer class.

            // Push this.getField("this$0") on the call stack.
            mDelWriter.visitVarInsn(Opcodes.ALOAD, 0); // var 0 = this
            mDelWriter.visitFieldInsn(Opcodes.GETFIELD, mClassName, // class where the field is defined
                    "this$0", // field name
                    outerType.getDescriptor()); // type of the field
            maxStack++;
            paramTypes.add(outerType);

        }

        // Push "this" for the instance method, which is always ALOAD 0
        mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
        maxStack++;
        pushedArg0 = true;
        paramTypes.add(Type.getObjectType(mClassName));
    }

    // Push all other arguments. Start at arg 1 if we already pushed 'this' above.
    Type[] argTypes = Type.getArgumentTypes(mDesc);
    int maxLocals = pushedArg0 ? 1 : 0;
    for (Type t : argTypes) {
        int size = t.getSize();
        mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
        maxLocals += size;
        maxStack += size;
        paramTypes.add(t);
    }

    // Construct the descriptor of the delegate based on the parameters
    // we pushed on the call stack. The return type remains unchanged.
    String desc = Type.getMethodDescriptor(Type.getReturnType(mDesc),
            paramTypes.toArray(new Type[paramTypes.size()]));

    // Invoke the static delegate
    mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC, delegateClassName, mMethodName, desc);

    Type returnType = Type.getReturnType(mDesc);
    mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));

    mDelWriter.visitMaxs(maxStack, maxLocals);
    mDelWriter.visitEnd();

    // For debugging now. Maybe we should collect these and store them in
    // a text file for helping create the delegates. We could also compare
    // the text file to a golden and break the build on unsupported changes
    // or regressions. Even better we could fancy-print something that looks
    // like the expected Java method declaration.
    mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
}

From source file:com.android.tools.lint.checks.FieldGetterDetector.java

License:Apache License

private static Map<String, String> checkMethods(ClassNode classNode, Set<String> names) {
    Map<String, String> validGetters = Maps.newHashMap();
    @SuppressWarnings("rawtypes")
    List methods = classNode.methods;
    String fieldName = null;//from   w  w  w  . jav  a  2 s  .co  m
    checkMethod: for (Object methodObject : methods) {
        MethodNode method = (MethodNode) methodObject;
        if (names.contains(method.name) && method.desc.startsWith("()")) { //$NON-NLS-1$ // (): No arguments
            InsnList instructions = method.instructions;
            int mState = 1;
            for (AbstractInsnNode curr = instructions.getFirst(); curr != null; curr = curr.getNext()) {
                switch (curr.getOpcode()) {
                case -1:
                    // Skip label and line number nodes
                    continue;
                case Opcodes.ALOAD:
                    if (mState == 1) {
                        fieldName = null;
                        mState = 2;
                    } else {
                        continue checkMethod;
                    }
                    break;
                case Opcodes.GETFIELD:
                    if (mState == 2) {
                        FieldInsnNode field = (FieldInsnNode) curr;
                        fieldName = field.name;
                        mState = 3;
                    } else {
                        continue checkMethod;
                    }
                    break;
                case Opcodes.ARETURN:
                case Opcodes.FRETURN:
                case Opcodes.IRETURN:
                case Opcodes.DRETURN:
                case Opcodes.LRETURN:
                case Opcodes.RETURN:
                    if (mState == 3) {
                        validGetters.put(method.name, fieldName);
                    }
                    continue checkMethod;
                default:
                    continue checkMethod;
                }
            }
        }
    }

    return validGetters;
}

From source file:com.asakusafw.dag.compiler.codegen.AsmUtil.java

License:Apache License

/**
 * Performs {@code GETFIELD} instruction.
 * @param method the target method//from   www . ja  v a2  s.com
 * @param field the target field ref
 */
public static void getField(MethodVisitor method, FieldRef field) {
    method.visitFieldInsn(Opcodes.GETFIELD, field.declaring.getInternalName(), field.name,
            field.type.getDescriptor());
}

From source file:com.asakusafw.dag.compiler.codegen.OperationGenerator.java

License:Apache License

private static void addProcessMethod(ClassWriter writer, ClassDescription target, OperationSpec graph) {
    VertexElement consumer = graph.getInput().getConsumer();
    MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "process",
            Type.getMethodDescriptor(Type.VOID_TYPE, typeOf(Object.class)), null, null);
    method.visitVarInsn(Opcodes.ALOAD, 0);
    method.visitFieldInsn(Opcodes.GETFIELD, target.getInternalName(), graph.getId(consumer),
            typeOf(consumer.getRuntimeType()).getDescriptor());
    method.visitVarInsn(Opcodes.ALOAD, 1);
    invokeResultAdd(method);//from  ww w.jav  a 2  s.c o m
    method.visitInsn(Opcodes.RETURN);
    method.visitMaxs(0, 0);
    method.visitEnd();
}

From source file:com.asakusafw.dag.compiler.codegen.OperationGenerator.java

License:Apache License

private static void getContext(MethodVisitor method, ClassDescription target,
        Function<VertexElement, String> ids) {
    method.visitVarInsn(Opcodes.ALOAD, 0);
    method.visitFieldInsn(Opcodes.GETFIELD, target.getInternalName(), FIELD_CONTEXT,
            typeOf(OperationAdapter.Context.class).getDescriptor());
}

From source file:com.asakusafw.dag.compiler.codegen.OperationGenerator.java

License:Apache License

private static void get(MethodVisitor method, ClassDescription target, VertexElement element,
        Function<VertexElement, String> ids) {
    method.visitVarInsn(Opcodes.ALOAD, 0);
    method.visitFieldInsn(Opcodes.GETFIELD, target.getInternalName(), ids.apply(element),
            typeOf(element.getRuntimeType()).getDescriptor());
}

From source file:com.codename1.tools.translator.bytecodes.Field.java

License:Open Source License

@Override
public boolean assignTo(String varName, StringBuilder sb) {
    if (opcode == Opcodes.GETSTATIC || (opcode == Opcodes.GETFIELD)) {
        StringBuilder b = new StringBuilder();

        if (varName != null) {
            b.append(varName).append(" = ");
        }/*from   ww w . j  a  v  a 2s .  c  o  m*/
        if (opcode == Opcodes.GETSTATIC) {
            b.append("get_static_");
            b.append(owner.replace('/', '_').replace('$', '_'));
            b.append("_");
            b.append(name.replace('/', '_').replace('$', '_'));
            b.append("(threadStateData)");
        } else {

            b.append("get_field_");
            b.append(owner.replace('/', '_').replace('$', '_'));
            b.append("_");
            b.append(name);
            StringBuilder sb3 = new StringBuilder();
            boolean targetProvided = (targetOp != null && targetOp instanceof AssignableExpression
                    && ((AssignableExpression) targetOp).assignTo(null, sb3));
            if (targetProvided) {
                b.append("(").append(sb3.toString().trim()).append(")");
                //} else if (useThis) {
                //    b.append("(__cn1ThisObject)");
            } else {
                return false;
            }

        }
        if (varName != null) {
            b.append(";\n");
        }
        sb.append(b);
        return true;
    }

    return false;
}

From source file:com.codename1.tools.translator.bytecodes.Field.java

License:Open Source License

@Override
public void appendInstruction(StringBuilder sbOut) {
    valueOpAppended = false;/*from  w  ww.  j  av  a  2  s  . com*/
    targetOpAppended = false;
    StringBuilder b = new StringBuilder();
    b.append("    ");
    switch (opcode) {
    case Opcodes.GETSTATIC:
        switch (desc.charAt(0)) {
        case 'L':
        case '[':
            b.append("PUSH_POINTER");
            break;
        case 'D':
            b.append("PUSH_DOUBLE");
            break;
        case 'F':
            b.append("PUSH_FLOAT");
            break;
        case 'J':
            b.append("PUSH_LONG");
            break;
        default:
            b.append("PUSH_INT");
            break;
        }
        b.append("(get_static_");
        b.append(owner.replace('/', '_').replace('$', '_'));
        b.append("_");
        b.append(name.replace('/', '_').replace('$', '_'));
        b.append("(threadStateData));\n");
        break;
    case Opcodes.PUTSTATIC: {
        //b.append("SAFE_RETAIN(1);\n    ");
        b.append("set_static_");
        b.append(owner.replace('/', '_').replace('$', '_'));
        b.append("_");
        b.append(name.replace('/', '_').replace('$', '_'));
        b.append("(threadStateData, ");
        StringBuilder sb2 = new StringBuilder();
        StringBuilder sb3 = new StringBuilder();
        if (valueOp != null && valueOp instanceof AssignableExpression
                && ((AssignableExpression) valueOp).assignTo(null, sb2)) {
            b.append(sb2.toString().trim()).append(");\n");
            valueOpAppended = true;
        } else if (valueOp != null && valueOp instanceof CustomInvoke
                && ((CustomInvoke) valueOp).appendExpression(sb3)) {
            b.append(sb3.toString().trim()).append(");\n");
            valueOpAppended = true;
        } else {

            switch (desc.charAt(0)) {
            case 'L':
            case '[':
                b.append("PEEK_OBJ(1));\n    SP--;\n");
                sbOut.append(b);
                return;
            case 'D':
                b.append("POP_DOUBLE");
                break;
            case 'F':
                b.append("POP_FLOAT");
                break;
            case 'J':
                b.append("POP_LONG");
                break;
            default:
                b.append("POP_INT");
                break;
            }
            b.append("());\n");
        }

        break;
    }
    case Opcodes.GETFIELD: {
        StringBuilder sb3 = new StringBuilder();
        boolean targetProvided = (targetOp != null && targetOp instanceof AssignableExpression
                && ((AssignableExpression) targetOp).assignTo(null, sb3));

        switch (desc.charAt(0)) {
        case 'L':
        case '[':
            b.append("PUSH_POINTER");
            break;
        case 'D':
            b.append("PUSH_DOUBLE");
            break;
        case 'F':
            b.append("PUSH_FLOAT");
            break;
        case 'J':
            b.append("PUSH_LONG");
            break;
        default:
            b.append("PUSH_INT");
            break;
        }

        b.append("(get_field_");
        b.append(owner.replace('/', '_').replace('$', '_'));
        b.append("_");
        b.append(name);

        if (targetProvided) {
            b.append("(").append(sb3.toString().trim()).append("));\n");
            targetOpAppended = true;
            //} else if(useThis) {
            //    b.append("(__cn1ThisObject));\n");
        } else {
            b.append("(POP_OBJ()));\n");
        }
        break;
    }
    case Opcodes.PUTFIELD: {
        //b.append("SAFE_RETAIN(1);\n    ");
        b.append("set_field_");
        b.append(owner.replace('/', '_').replace('$', '_'));
        b.append("_");
        b.append(name);
        b.append("(threadStateData, ");

        StringBuilder sb2 = new StringBuilder();
        StringBuilder sb3 = new StringBuilder();

        String targetLiteral = null;
        String valueLiteral = null;
        if (valueOp != null && valueOp instanceof AssignableExpression
                && ((AssignableExpression) valueOp).assignTo(null, sb2)) {
            valueLiteral = sb2.toString().trim();
        } else if (valueOp != null && valueOp instanceof CustomInvoke
                && ((CustomInvoke) valueOp).appendExpression(sb3)) {
            valueLiteral = sb3.toString().trim();
        }
        sb3.setLength(0);
        if (targetOp != null && targetOp instanceof AssignableExpression
                && ((AssignableExpression) targetOp).assignTo(null, sb3)) {
            targetLiteral = sb3.toString().trim();
        }

        if (valueLiteral != null && targetLiteral != null) {
            b.append(valueLiteral).append(", ").append(targetLiteral).append(");\n");
            valueOpAppended = true;
            targetOpAppended = true;
        } else {
            switch (desc.charAt(0)) {
            case 'L':
            case '[':
                b.append("PEEK_OBJ");
                //if(useThis) {
                //    b.append("(1), __cn1ThisObject);\n    SP--;\n");
                //} else {
                b.append("(1), PEEK_OBJ(2));\n    POP_MANY(2);\n");
                //}
                sbOut.append(b);
                return;
            case 'D':
                b.append("POP_DOUBLE");
                break;
            case 'F':
                b.append("POP_FLOAT");
                break;
            case 'J':
                b.append("POP_LONG");
                break;
            default:
                b.append("POP_INT");
                break;
            }
            //if(useThis) {
            //    b.append("(), __cn1ThisObject);\n");
            //} else {
            b.append("(), POP_OBJ());\n");
            //}
        }
        break;
    }
    }
    if (valueOp != null && !valueOpAppended) {
        valueOp.appendInstruction(sbOut);
        valueOpAppended = true;
    }
    if (targetOp != null && !targetOpAppended) {
        targetOp.appendInstruction(sbOut);
        targetOpAppended = true;
    }
    sbOut.append(b);
}

From source file:com.codename1.tools.translator.bytecodes.Field.java

License:Open Source License

/**
 * @param useThis the useThis to set/*from  ww  w . j  a v  a2 s .c o m*/
 */
//public void setUseThis(boolean useThis) {
//    this.useThis = useThis;
//}

public static int tryReduce(List<Instruction> instructions, int index) {
    Instruction instr = instructions.get(index);
    if (!(instr instanceof Field)) {
        return -1;
    }
    if (instr.getOpcode() == Opcodes.PUTFIELD) {
        if (index < 2) {
            return -1;
        }

        Field f = (Field) instr;
        if (f.targetOp != null || f.valueOp != null) {
            return -1;
        }
        Instruction targetInstr = instructions.get(index - 2);
        if (!(targetInstr instanceof AssignableExpression)) {
            return -1;
        }
        Instruction valueInstr = instructions.get(index - 1);
        if (!(valueInstr instanceof AssignableExpression)) {
            return -1;
        }

        StringBuilder sb = new StringBuilder();

        AssignableExpression targetExpr = (AssignableExpression) targetInstr;
        if (!targetExpr.assignTo(null, sb)) {
            return -1;
        }

        AssignableExpression valueExpr = (AssignableExpression) valueInstr;
        if (!valueExpr.assignTo(null, sb)) {
            return -1;
        }

        f.targetOp = targetInstr;
        f.valueOp = valueInstr;

        instructions.remove(index - 2);
        instructions.remove(index - 2);
        return index - 2;
    } else if (instr.getOpcode() == Opcodes.PUTSTATIC) {
        if (index < 1) {
            return -1;
        }

        Field f = (Field) instr;
        if (f.valueOp != null) {
            return -1;
        }

        Instruction valueInstr = instructions.get(index - 1);
        if (!(valueInstr instanceof AssignableExpression)) {
            return -1;
        }

        StringBuilder sb = new StringBuilder();

        AssignableExpression valueExpr = (AssignableExpression) valueInstr;
        if (!valueExpr.assignTo(null, sb)) {
            return -1;
        }

        f.valueOp = valueInstr;

        instructions.remove(index - 1);

        return index - 1;
    } else if (instr.getOpcode() == Opcodes.GETFIELD) {
        if (index < 1) {
            return -1;
        }

        Field f = (Field) instr;
        //if (f.useThis) {
        //    return -1;
        //}

        Instruction targetInstr = instructions.get(index - 1);
        if (!(targetInstr instanceof AssignableExpression)) {
            return -1;
        }

        StringBuilder sb = new StringBuilder();

        AssignableExpression targetExpr = (AssignableExpression) targetInstr;
        if (!targetExpr.assignTo(null, sb)) {
            return -1;
        }

        f.targetOp = targetInstr;

        instructions.remove(index - 1);

        return index - 1;
    }
    return -1;
}