List of usage examples for org.objectweb.asm Opcodes RETURN
int RETURN
To view the source code for org.objectweb.asm Opcodes RETURN.
Click Source Link
From source file:com.android.build.gradle.internal.incremental.IncrementalChangeVisitor.java
License:Apache License
/** * Turns this class into an override class that can be loaded by our custom class loader: *<ul>/* www . ja va 2s. c o m*/ * <li>Make the class name be OriginalName$override</li> * <li>Ensure the class derives from java.lang.Object, no other inheritance</li> * <li>Ensure the class has a public parameterless constructor that is a noop.</li> *</ul> */ @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, name + OVERRIDE_SUFFIX, signature, "java/lang/Object", new String[] { CHANGE_TYPE.getInternalName() }); if (DEBUG) { System.out.println(">>>>>>>> Processing " + name + "<<<<<<<<<<<<<"); } visitedClassName = name; visitedSuperName = superName; instanceToStaticDescPrefix = "(L" + visitedClassName + ";"; // Create empty constructor MethodVisitor mv = super.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(0, 0); mv.visitEnd(); super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC, "$obsolete", "Z", null, null); }
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.//from w w w . j a v a 2s.c om * * <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.transforms.InstantRunTransform.java
License:Apache License
/** * Use asm to generate a concrete subclass of the AppPathLoaderImpl class. * It only implements one method :// w w w . j a v a 2 s . co m * String[] getPatchedClasses(); * * The method is supposed to return the list of classes that were patched in this iteration. * This will be used by the InstantRun runtime to load all patched classes and register them * as overrides on the original classes.2 class files. * * @param patchFileContents list of patched class names. * @param outputDir output directory where to generate the .class file in. */ private static void writePatchFileContents(@NonNull ImmutableList<String> patchFileContents, @NonNull File outputDir, long buildId) { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, IncrementalVisitor.APP_PATCHES_LOADER_IMPL, null, IncrementalVisitor.ABSTRACT_PATCHES_LOADER_IMPL, null); // Add the build ID to force the patch file to be repackaged. cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL, "BUILD_ID", "J", null, buildId); { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, IncrementalVisitor.ABSTRACT_PATCHES_LOADER_IMPL, "<init>", "()V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getPatchedClasses", "()[Ljava/lang/String;", null, null); mv.visitCode(); mv.visitIntInsn(Opcodes.BIPUSH, patchFileContents.size()); mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String"); for (int index = 0; index < patchFileContents.size(); index++) { mv.visitInsn(Opcodes.DUP); mv.visitIntInsn(Opcodes.BIPUSH, index); mv.visitLdcInsn(patchFileContents.get(index)); mv.visitInsn(Opcodes.AASTORE); } mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(4, 1); mv.visitEnd(); } cw.visitEnd(); byte[] classBytes = cw.toByteArray(); File outputFile = new File(outputDir, IncrementalVisitor.APP_PATCHES_LOADER_IMPL + ".class"); try { Files.createParentDirs(outputFile); Files.write(classBytes, outputFile); } catch (IOException e) { throw new RuntimeException(e); } }
From source file:com.android.build.gradle.internal2.incremental.IncrementalChangeVisitor.java
License:Apache License
/** * Turns this class into an override class that can be loaded by our custom class loader: *<ul>//from w w w . j av a 2s . c o m * <li>Make the class name be OriginalName$override</li> * <li>Ensure the class derives from java.lang.Object, no other inheritance</li> * <li>Ensure the class has a public parameterless constructor that is a noop.</li> *</ul> */ @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { // TODO: modified by achellies, ?,??,?ClassClass,Opcodes.INVOKESPECIAL?super super.visit(version, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, name + OVERRIDE_SUFFIX, signature, superName, // TODO modified by achellies, "java/lang/Object" -> superName new String[] { CHANGE_TYPE.getInternalName() }); if (DEBUG) { System.out.println(">>>>>>>> Processing " + name + "<<<<<<<<<<<<<"); } visitedClassName = name; visitedSuperName = superName; instanceToStaticDescPrefix = "(L" + visitedClassName + ";"; // Create empty constructor MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, ByteCodeUtils.CONSTRUCTOR, "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, ByteCodeUtils.CONSTRUCTOR, "()V", // TODO modified by achellies, "java/lang/Object" -> superName false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); super.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC, "$obsolete", "Z", null, null); }
From source file:com.android.builder.testing.MockableJarGenerator.java
License:Apache License
/** * Rewrites the method bytecode to remove the "Stub!" exception. *//*w w w .j av a 2 s. c o m*/ private void fixMethodBody(MethodNode methodNode, ClassNode classNode) { if ((methodNode.access & Opcodes.ACC_NATIVE) != 0 || (methodNode.access & Opcodes.ACC_ABSTRACT) != 0) { // Abstract and native method don't have bodies to rewrite. return; } if ((classNode.access & Opcodes.ACC_ENUM) != 0 && ENUM_METHODS.contains(methodNode.name)) { // Don't break enum classes. return; } Type returnType = Type.getReturnType(methodNode.desc); InsnList instructions = methodNode.instructions; if (methodNode.name.equals(CONSTRUCTOR)) { // Keep the call to parent constructor, delete the exception after that. boolean deadCode = false; for (AbstractInsnNode instruction : instructions.toArray()) { if (!deadCode) { if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) { instructions.insert(instruction, new InsnNode(Opcodes.RETURN)); // Start removing all following instructions. deadCode = true; } } else { instructions.remove(instruction); } } } else { instructions.clear(); if (returnDefaultValues || methodNode.name.equals(CLASS_CONSTRUCTOR)) { if (INTEGER_LIKE_TYPES.contains(returnType)) { instructions.add(new InsnNode(Opcodes.ICONST_0)); } else if (returnType.equals(Type.LONG_TYPE)) { instructions.add(new InsnNode(Opcodes.LCONST_0)); } else if (returnType.equals(Type.FLOAT_TYPE)) { instructions.add(new InsnNode(Opcodes.FCONST_0)); } else if (returnType.equals(Type.DOUBLE_TYPE)) { instructions.add(new InsnNode(Opcodes.DCONST_0)); } else { instructions.add(new InsnNode(Opcodes.ACONST_NULL)); } instructions.add(new InsnNode(returnType.getOpcode(Opcodes.IRETURN))); } else { instructions.insert(throwExceptionsList(methodNode, classNode)); } } }
From source file:com.android.ide.eclipse.apt.internal.analysis.InternalGetSetAnalyzer.java
License:Apache License
/** * Checks if a method is a setter//from ww w. j ava2 s . co m * @param methodTest The method to be checked * @return True if the method is a setter, false otherwise */ private boolean isSetter(final MethodNode methodTest) { boolean setter = false; final String desc = methodTest.desc; final Type[] arguments = Type.getArgumentTypes(desc); final Type returnType = Type.getReturnType(desc); if (arguments.length == 1 && returnType.getSort() == Type.VOID) { final InsnList instructions = methodTest.instructions; //skip label and line number instructions final AbstractInsnNode first = instructions.getFirst().getNext().getNext(); final int loadOp = arguments[0].getOpcode(Opcodes.ILOAD); final int firstOp = first.getOpcode(); //check for static setter if ((Opcodes.ACC_STATIC & methodTest.access) == 0) { if (firstOp == Opcodes.ALOAD) { final AbstractInsnNode second = first.getNext(); if (second.getOpcode() == loadOp) { final AbstractInsnNode third = second.getNext(); if (third.getOpcode() == Opcodes.PUTFIELD) { //three next to skip label and line number instructions final AbstractInsnNode fourth = third.getNext().getNext().getNext(); if (fourth.getOpcode() == Opcodes.RETURN) { setter = true; } } } } } else { if (firstOp == loadOp) { final AbstractInsnNode second = first.getNext(); if (second.getOpcode() == Opcodes.PUTSTATIC) { final AbstractInsnNode third = second.getNext().getNext().getNext(); if (third.getOpcode() == Opcodes.RETURN) { setter = true; } } } } } return setter; }
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 va 2s .c om*/ 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.android.tools.layoutlib.create.StubMethodAdapter.java
License:Apache License
/** * For non-constructor, rewrite existing "return" instructions to write the message. *//* w ww . j a va 2 s .co m*/ public void visitInsn(int opcode) { if (mIsInitMethod) { switch (opcode) { case Opcodes.RETURN: case Opcodes.ARETURN: case Opcodes.DRETURN: case Opcodes.FRETURN: case Opcodes.IRETURN: case Opcodes.LRETURN: // Pop the last word from the stack since invoke will generate its own return. generatePop(); generateInvoke(); mMessageGenerated = true; default: mParentVisitor.visitInsn(opcode); } } }
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;/* w w w . j a v a 2 s . c om*/ 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.android.tools.lint.checks.TrustAllX509TrustManagerDetector.java
License:Apache License
@Override @SuppressWarnings("rawtypes") public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) { if (!context.isFromClassLibrary()) { // Non-library code checked at the AST level return;// ww w . j av a 2 s . c om } if (!classNode.interfaces.contains("javax/net/ssl/X509TrustManager")) { return; } List methodList = classNode.methods; for (Object m : methodList) { MethodNode method = (MethodNode) m; if ("checkServerTrusted".equals(method.name) || "checkClientTrusted".equals(method.name)) { InsnList nodes = method.instructions; boolean emptyMethod = true; // Stays true if method doesn't perform any "real" // operations for (int i = 0, n = nodes.size(); i < n; i++) { // Future work: Improve this check to be less sensitive to irrelevant // instructions/statements/invocations (e.g. System.out.println) by // looking for calls that could lead to a CertificateException being // thrown, e.g. throw statement within the method itself or invocation // of another method that may throw a CertificateException, and only // reporting an issue if none of these calls are found. ControlFlowGraph // may be useful here. AbstractInsnNode instruction = nodes.get(i); int type = instruction.getType(); if (type != AbstractInsnNode.LABEL && type != AbstractInsnNode.LINE && !(type == AbstractInsnNode.INSN && instruction.getOpcode() == Opcodes.RETURN)) { emptyMethod = false; break; } } if (emptyMethod) { Location location = context.getLocation(method, classNode); context.report(ISSUE, location, getErrorMessage(method.name)); } } } }