List of usage examples for org.objectweb.asm Label Label
public Label()
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); }