Example usage for org.objectweb.asm Label Label

List of usage examples for org.objectweb.asm Label Label

Introduction

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

Prototype

public Label() 

Source Link

Document

Constructs a new label.

Usage

From source file:com.android.build.gradle.internal.incremental.IncrementalSupportVisitor.java

License:Apache License

/***
 * Inserts a trampoline to this class so that the updated methods can make calls to
 * constructors./* w w  w . j ava 2  s.  c o m*/
 *
 * <p>
 * Pseudo code for this trampoline:
 * <code>
 *   ClassName(Object[] args, Marker unused) {
 *      String name = (String) args[0];
 *      if (name.equals(
 *          "java/lang/ClassName.(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) {
 *        this((String)arg[1], arg[2]);
 *        return
 *      }
 *      if (name.equals("SuperClassName.(Ljava/lang/String;I)V")) {
 *        super((String)arg[1], (int)arg[2]);
 *        return;
 *      }
 *      ...
 *      StringBuilder $local1 = new StringBuilder();
 *      $local1.append("Method not found ");
 *      $local1.append(name);
 *      $local1.append(" in " $classType $super implementation");
 *      throw new $package/InstantReloadException($local1.toString());
 *   }
 * </code>
 */
private void createDispatchingThis() {
    // Gather all methods from itself and its superclasses to generate a giant constructor
    // implementation.
    // This will work fine as long as we don't support adding constructors to classes.
    final Map<String, MethodNode> uniqueMethods = new HashMap<>();

    addAllNewConstructors(uniqueMethods, classNode, true /*keepPrivateConstructors*/);
    for (ClassNode parentNode : parentNodes) {
        addAllNewConstructors(uniqueMethods, parentNode, false /*keepPrivateConstructors*/);
    }

    int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;

    Method m = new Method(ByteCodeUtils.CONSTRUCTOR, ConstructorRedirection.DISPATCHING_THIS_SIGNATURE);
    MethodVisitor visitor = super.visitMethod(0, m.getName(), m.getDescriptor(), null, null);
    final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor);

    mv.visitCode();
    // Mark this code as redirection code
    Label label = new Label();
    mv.visitLineNumber(0, label);

    // Get and store the constructor canonical name.
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.push(1);
    mv.visitInsn(Opcodes.AALOAD);
    mv.unbox(Type.getType("Ljava/lang/String;"));
    final int constructorCanonicalName = mv.newLocal(Type.getType("Ljava/lang/String;"));
    mv.storeLocal(constructorCanonicalName);

    new StringSwitch() {

        @Override
        void visitString() {
            mv.loadLocal(constructorCanonicalName);
        }

        @Override
        void visitCase(String canonicalName) {
            MethodNode methodNode = uniqueMethods.get(canonicalName);
            String owner = canonicalName.split("\\.")[0];

            // Parse method arguments and
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            Type[] args = Type.getArgumentTypes(methodNode.desc);
            int argc = 1;
            for (Type t : args) {
                mv.visitVarInsn(Opcodes.ALOAD, 1);
                mv.push(argc + 1);
                mv.visitInsn(Opcodes.AALOAD);
                ByteCodeUtils.unbox(mv, t);
                argc++;
            }

            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, owner, ByteCodeUtils.CONSTRUCTOR, methodNode.desc, false);

            mv.visitInsn(Opcodes.RETURN);
        }

        @Override
        void visitDefault() {
            writeMissingMessageWithHash(mv, visitedClassName);
        }
    }.visit(mv, uniqueMethods.keySet());

    mv.visitMaxs(1, 3);
    mv.visitEnd();
}

From source file:com.android.build.gradle.internal.incremental.Redirection.java

License:Apache License

/**
 * Adds the instructions to do a generic redirection.
 * <p>//from w w  w  .j a  v  a  2s  .  c  o  m
 * Note that the generated bytecode does not have a direct translation to code, but as an
 * example, the following code block gets inserted.
 * <code>
 * if ($change != null) {
 *   $change.access$dispatch($name, new object[] { arg0, ... argsN })
 *   $anyCodeInsertedbyRestore
 * }
 * $originalMethodBody
 *</code>
 * @param mv the method visitor to add the instructions to.
 * @param change the local variable containing the alternate implementation.
 */
void redirect(GeneratorAdapter mv, int change) {
    // code to check if a new implementation of the current class is available.
    Label l0 = new Label();
    mv.loadLocal(change);
    mv.visitJumpInsn(Opcodes.IFNULL, l0);

    doRedirect(mv, change);

    // Return
    if (type == Type.VOID_TYPE) {
        mv.pop();
    } else {
        ByteCodeUtils.unbox(mv, type);
    }
    mv.returnValue();

    // jump label for classes without any new implementation, just invoke the original
    // method implementation.
    mv.visitLabel(l0);
}

From source file:com.android.build.gradle.internal.incremental.StringSwitch.java

License:Apache License

/**
 * Emit code for a string if-else block.
 *
 *     if (s.equals("collided_method1")) {
 *         visit(s);/*from w w  w.jav  a  2s .  c  om*/
 *     } else if (s.equals("collided_method2")) {
 *         visit(s);
 *     }
 *
 * In the most common case of just one string, this degenerates to:
 *
 *      visit(s)
 *
 */
private void visitx(GeneratorAdapter mv, List<String> strings) {
    if (strings.size() == 1) {
        visitCase(strings.get(0));
        return;
    }
    for (String string : strings) {
        Label label = new Label();
        visitString();
        mv.visitLdcInsn(string);
        mv.invokeVirtual(STRING_TYPE, Method.getMethod("boolean equals(Object)"));
        mv.visitJumpInsn(Opcodes.IFEQ, label);
        visitCase(string);
        mv.visitLabel(label);
    }

    visitDefault();
}

From source file:com.android.build.gradle.internal.incremental.StringSwitch.java

License:Apache License

/**
 * Emit code for a string switch for the given string classifier.
 *
 * switch(s.hashCode()) {/*from  ww  w.  ja va2s  . co  m*/
 *   case 192: visitCase(s);
 *   case 312: visitCase(s);
 *   case 1024:
 *     if (s.equals("collided_method1")) {
 *         visit(s);
 *     } else if (s.equals("collided_method2")) {
 *         visit(s);
 *     }
 *     visitDefault();
 *   default:
 *     visitDefault();
 * }
 *
 **/
private void visitClassifier(GeneratorAdapter mv, Set<String> strings) {
    visitString();
    visitHashMethod(mv);

    // Group strings by hash code.
    Multimap<Integer, String> buckets = Multimaps.index(strings, HASH_METHOD::apply);
    List<Map.Entry<Integer, Collection<String>>> sorted = Ordering.natural()
            .onResultOf(Map.Entry<Integer, Collection<String>>::getKey)
            .immutableSortedCopy(buckets.asMap().entrySet());

    int sortedHashes[] = new int[sorted.size()];
    List<String> sortedCases[] = new List[sorted.size()];
    int index = 0;
    for (Map.Entry<Integer, Collection<String>> entry : sorted) {
        sortedHashes[index] = entry.getKey();
        sortedCases[index] = Lists.newCopyOnWriteArrayList(entry.getValue());
        index++;
    }

    // Label for each hash and for default.
    Label labels[] = new Label[sorted.size()];
    Label defaultLabel = new Label();
    for (int i = 0; i < sorted.size(); ++i) {
        labels[i] = new Label();
    }

    // Create a switch that dispatches to each label from the hash code of
    mv.visitLookupSwitchInsn(defaultLabel, sortedHashes, labels);

    // Create the cases.
    for (int i = 0; i < sorted.size(); ++i) {
        mv.visitLabel(labels[i]);
        visitx(mv, sortedCases[i]);
    }
    mv.visitLabel(defaultLabel);
    visitDefault();
}

From source file:com.android.build.gradle.internal2.incremental.StringSwitch.java

License:Apache License

/**
 * Emit code for a string switch for the given string classifier.
 *
 * switch(s.hashCode()) {//from   ww  w. ja v a  2s  . com
 *   case 192: visitCase(s);
 *   case 312: visitCase(s);
 *   case 1024:
 *     if (s.equals("collided_method1")) {
 *         visit(s);
 *     } else if (s.equals("collided_method2")) {
 *         visit(s);
 *     }
 *     visitDefault();
 *   default:
 *     visitDefault();
 * }
 *
 **/
private void visitClassifier(GeneratorAdapter mv, Set<String> strings) {
    visitString();
    visitHashMethod(mv);

    // Group strings by hash code.
    Multimap<Integer, String> buckets = Multimaps.index(strings, HASH_METHOD);
    List<Map.Entry<Integer, Collection<String>>> sorted = Ordering.natural()
            .onResultOf(new Function<Map.Entry<Integer, Collection<String>>, Integer>() {
                @Override
                public Integer apply(Map.Entry<Integer, Collection<String>> entry) {
                    return entry.getKey();
                }
            }).immutableSortedCopy(buckets.asMap().entrySet());

    int sortedHashes[] = new int[sorted.size()];
    List<String> sortedCases[] = new List[sorted.size()];
    int index = 0;
    for (Map.Entry<Integer, Collection<String>> entry : sorted) {
        sortedHashes[index] = entry.getKey();
        sortedCases[index] = Lists.newCopyOnWriteArrayList(entry.getValue());
        index++;
    }

    // Label for each hash and for default.
    Label labels[] = new Label[sorted.size()];
    Label defaultLabel = new Label();
    for (int i = 0; i < sorted.size(); ++i) {
        labels[i] = new Label();
    }

    // Create a switch that dispatches to each label from the hash code of
    mv.visitLookupSwitchInsn(defaultLabel, sortedHashes, labels);

    // Create the cases.
    for (int i = 0; i < sorted.size(); ++i) {
        mv.visitLabel(labels[i]);
        visitx(mv, sortedCases[i]);
    }
    mv.visitLabel(defaultLabel);
    visitDefault();
}

From source file:com.android.build.gradle.tasks.fd.GenerateInstantRunAppInfoTask.java

License:Apache License

void writeAppInfoClass(@NonNull String applicationId, @Nullable String applicationClass, long token)
        throws IOException {
    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;/* www .j  a  v a2s  .  c o  m*/
    MethodVisitor mv;

    String appInfoOwner = "com/android/tools/fd/runtime/AppInfo";
    cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, appInfoOwner, null, "java/lang/Object", null);

    fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, "applicationId", "Ljava/lang/String;", null, null);
    fv.visitEnd();
    fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, "applicationClass", "Ljava/lang/String;", null, null);
    fv.visitEnd();
    fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, "token", "J", null, null);
    fv.visitEnd();
    fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, "usingApkSplits", "Z", null, null);
    fv.visitEnd();
    mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
    mv.visitInsn(RETURN);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", "L" + appInfoOwner + ";", null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
    mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
    mv.visitCode();
    mv.visitLdcInsn(applicationId);
    mv.visitFieldInsn(PUTSTATIC, appInfoOwner, "applicationId", "Ljava/lang/String;");
    if (applicationClass != null) {
        mv.visitLdcInsn(applicationClass);
    } else {
        mv.visitInsn(ACONST_NULL);
    }
    mv.visitFieldInsn(PUTSTATIC, appInfoOwner, "applicationClass", "Ljava/lang/String;");
    if (token != 0L) {
        mv.visitLdcInsn(token);
    } else {
        mv.visitInsn(LCONST_0);
    }
    mv.visitFieldInsn(PUTSTATIC, appInfoOwner, "token", "J");
    if (isUsingMultiApks()) {
        mv.visitInsn(ICONST_1);
    } else {
        mv.visitInsn(ICONST_0);
    }
    mv.visitFieldInsn(PUTSTATIC, appInfoOwner, "usingApkSplits", "Z");

    mv.visitInsn(RETURN);
    mv.visitMaxs(2, 0);
    mv.visitEnd();
    cw.visitEnd();

    byte[] bytes = cw.toByteArray();

    try (JarOutputStream outputStream = new JarOutputStream(
            new BufferedOutputStream(new FileOutputStream(getOutputFile())))) {
        outputStream.putNextEntry(new ZipEntry("com/android/tools/fd/runtime/AppInfo.class"));
        outputStream.write(bytes);
        outputStream.closeEntry();
    }
}

From source file:com.android.build.gradle.tasks.ir.GenerateInstantRunAppInfoTask.java

License:Apache License

void writeAppInfoClass(@NonNull String applicationId, long token) throws IOException {
    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;// w ww.j a  va  2s . c  o  m
    MethodVisitor mv;

    String appInfoOwner = SERVER_PACKAGE + "/AppInfo";
    cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, appInfoOwner, null, "java/lang/Object", null);

    fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, "applicationId", "Ljava/lang/String;", null, null);
    fv.visitEnd();
    fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, "token", "J", null, null);
    fv.visitEnd();
    mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
    mv.visitInsn(RETURN);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", "L" + appInfoOwner + ";", null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
    mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
    mv.visitCode();
    mv.visitLdcInsn(applicationId);
    mv.visitFieldInsn(PUTSTATIC, appInfoOwner, "applicationId", "Ljava/lang/String;");
    if (token != 0L) {
        mv.visitLdcInsn(token);
    } else {
        mv.visitInsn(LCONST_0);
    }
    mv.visitFieldInsn(PUTSTATIC, appInfoOwner, "token", "J");

    mv.visitInsn(RETURN);
    mv.visitMaxs(2, 0);
    mv.visitEnd();
    cw.visitEnd();

    byte[] bytes = cw.toByteArray();

    try (JarOutputStream outputStream = new JarOutputStream(
            new BufferedOutputStream(new FileOutputStream(getOutputFile())))) {
        outputStream.putNextEntry(new ZipEntry(SERVER_PACKAGE + "/AppInfo.class"));
        outputStream.write(bytes);
        outputStream.closeEntry();
    }
}

From source file:com.android.mkstubs.stubber.MethodStubber.java

License:Apache License

@Override
public void visitCode() {
    Label l0 = new Label();
    mv.visitLabel(l0);/*ww  w. j  av  a 2 s  . co m*/
    mv.visitLineNumber(36, l0);
    mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
    mv.visitInsn(Opcodes.DUP);
    mv.visitLdcInsn("stub");
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, // opcode
            "java/lang/RuntimeException", // owner
            "<init>", // name
            "(Ljava/lang/String;)V", // desc
            false);
    mv.visitInsn(Opcodes.ATHROW);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", // name
            "Lcom/android/mkstubs/stubber/MethodStubber;", // desc
            null, // signature
            l0, // label start
            l1, // label end
            0); // index
    mv.visitMaxs(3, 1); // maxStack, maxLocals
}

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

License:Apache License

private void generateInvoke() {
    /* Generates the code:
     *  OverrideMethod.invoke("signature", mIsNative ? true : false, null or this);
     *///from  www .  j  a v  a2s  .  c  o  m
    mParentVisitor.visitLdcInsn(mInvokeSignature);
    // push true or false
    mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
    // push null or this
    if (mIsStatic) {
        mParentVisitor.visitInsn(Opcodes.ACONST_NULL);
    } else {
        mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0);
    }

    int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID;
    switch (sort) {
    case Type.VOID:
        mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/android/tools/layoutlib/create/OverrideMethod", "invokeV",
                "(Ljava/lang/String;ZLjava/lang/Object;)V");
        mParentVisitor.visitInsn(Opcodes.RETURN);
        break;
    case Type.BOOLEAN:
    case Type.CHAR:
    case Type.BYTE:
    case Type.SHORT:
    case Type.INT:
        mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/android/tools/layoutlib/create/OverrideMethod", "invokeI",
                "(Ljava/lang/String;ZLjava/lang/Object;)I");
        switch (sort) {
        case Type.BOOLEAN:
            Label l1 = new Label();
            mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1);
            mParentVisitor.visitInsn(Opcodes.ICONST_1);
            mParentVisitor.visitInsn(Opcodes.IRETURN);
            mParentVisitor.visitLabel(l1);
            mParentVisitor.visitInsn(Opcodes.ICONST_0);
            break;
        case Type.CHAR:
            mParentVisitor.visitInsn(Opcodes.I2C);
            break;
        case Type.BYTE:
            mParentVisitor.visitInsn(Opcodes.I2B);
            break;
        case Type.SHORT:
            mParentVisitor.visitInsn(Opcodes.I2S);
            break;
        }
        mParentVisitor.visitInsn(Opcodes.IRETURN);
        break;
    case Type.LONG:
        mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/android/tools/layoutlib/create/OverrideMethod", "invokeL",
                "(Ljava/lang/String;ZLjava/lang/Object;)J");
        mParentVisitor.visitInsn(Opcodes.LRETURN);
        break;
    case Type.FLOAT:
        mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/android/tools/layoutlib/create/OverrideMethod", "invokeF",
                "(Ljava/lang/String;ZLjava/lang/Object;)F");
        mParentVisitor.visitInsn(Opcodes.FRETURN);
        break;
    case Type.DOUBLE:
        mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/android/tools/layoutlib/create/OverrideMethod", "invokeD",
                "(Ljava/lang/String;ZLjava/lang/Object;)D");
        mParentVisitor.visitInsn(Opcodes.DRETURN);
        break;
    case Type.ARRAY:
    case Type.OBJECT:
        mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
                "com/android/tools/layoutlib/create/OverrideMethod", "invokeA",
                "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;");
        mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName());
        mParentVisitor.visitInsn(Opcodes.ARETURN);
        break;
    }

}

From source file:com.asakusafw.dag.compiler.builtin.BranchOperatorGenerator.java

License:Apache License

static void branch(MethodVisitor method, Context context, UserOperator operator, LocalVarRef input,
        Map<OperatorProperty, FieldRef> dependencies) {
    OperatorOutput[] outputs = outputs(context, operator);
    Label[] caseLabels = Stream.of(outputs).map(o -> new Label()).toArray(Label[]::new);
    Label defaultLabel = new Label();
    Label endLabel = new Label();

    method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typeOf(Enum.class).getInternalName(), "ordinal",
            Type.getMethodDescriptor(Type.INT_TYPE), false);
    method.visitTableSwitchInsn(0, caseLabels.length - 1, defaultLabel, caseLabels);

    for (int i = 0; i < outputs.length; i++) {
        method.visitLabel(caseLabels[i]);
        FieldRef ref = Invariants.requireNonNull(dependencies.get(outputs[i]));
        ref.load(method);//from w  w  w. ja  v  a  2s. c  o  m
        input.load(method);
        invokeResultAdd(method);
        method.visitJumpInsn(Opcodes.GOTO, endLabel);
    }
    method.visitLabel(defaultLabel);
    getNew(method, Descriptions.typeOf(AssertionError.class));
    method.visitInsn(Opcodes.ATHROW);

    method.visitLabel(endLabel);
}