19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.tools.layoutlib.create; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.AnnotationVisitor; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.Attribute; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.Label; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.MethodVisitor; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.Opcodes; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.objectweb.asm.Type; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This method adapter rewrites a method by discarding the original code and generating 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a stub depending on the return type. Original annotations are passed along unchanged. 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 30f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbyeclass StubMethodAdapter extends MethodVisitor { 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String CONSTRUCTOR = "<init>"; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static String CLASS_INIT = "<clinit>"; 34865c3bef54228a353fd449a093b0c8d155618296Raphael Moll 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The parent method writer */ 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MethodVisitor mParentVisitor; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The method return type. Can be null. */ 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Type mReturnType; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Message to be printed by stub methods. */ 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mInvokeSignature; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Flag to output the first line number. */ 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mOutputFirstLineNumber = true; 43865c3bef54228a353fd449a093b0c8d155618296Raphael Moll /** Flag that is true when implementing a constructor, to accept all original 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * code calling the original super constructor. */ 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mIsInitMethod = false; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mMessageGenerated; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final boolean mIsStatic; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final boolean mIsNative; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType, 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String invokeSignature, boolean isStatic, boolean isNative) { 53f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye super(Opcodes.ASM4); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor = mv; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReturnType = returnType; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInvokeSignature = invokeSignature; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsStatic = isStatic; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsNative = isNative; 59865c3bef54228a353fd449a093b0c8d155618296Raphael Moll 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIsInitMethod = true; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 64865c3bef54228a353fd449a093b0c8d155618296Raphael Moll 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void generateInvoke() { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Generates the code: 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * OverrideMethod.invoke("signature", mIsNative ? true : false, null or this); 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitLdcInsn(mInvokeSignature); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // push true or false 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // push null or this 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsStatic) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.ACONST_NULL); 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(sort) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.VOID: 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com/android/tools/layoutlib/create/OverrideMethod", 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "invokeV", 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(Ljava/lang/String;ZLjava/lang/Object;)V"); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.RETURN); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.BOOLEAN: 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.CHAR: 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.BYTE: 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.SHORT: 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.INT: 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com/android/tools/layoutlib/create/OverrideMethod", 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "invokeI", 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(Ljava/lang/String;ZLjava/lang/Object;)I"); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(sort) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.BOOLEAN: 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Label l1 = new Label(); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.ICONST_1); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.IRETURN); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitLabel(l1); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.ICONST_0); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.CHAR: 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.I2C); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.BYTE: 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.I2B); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.SHORT: 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.I2S); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.IRETURN); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.LONG: 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com/android/tools/layoutlib/create/OverrideMethod", 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "invokeL", 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(Ljava/lang/String;ZLjava/lang/Object;)J"); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.LRETURN); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.FLOAT: 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com/android/tools/layoutlib/create/OverrideMethod", 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "invokeF", 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(Ljava/lang/String;ZLjava/lang/Object;)F"); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.FRETURN); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.DOUBLE: 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com/android/tools/layoutlib/create/OverrideMethod", 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "invokeD", 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(Ljava/lang/String;ZLjava/lang/Object;)D"); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.DRETURN); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.ARRAY: 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.OBJECT: 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "com/android/tools/layoutlib/create/OverrideMethod", 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "invokeA", 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;"); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName()); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.ARETURN); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void generatePop() { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Pops the stack, depending on the return type. 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.VOID: 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.BOOLEAN: 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.CHAR: 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.BYTE: 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.SHORT: 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.INT: 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.FLOAT: 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.ARRAY: 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.OBJECT: 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.POP); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.LONG: 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Type.DOUBLE: 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(Opcodes.POP2); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Pass down to visitor writer. In this implementation, either do nothing. */ 176f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitCode() { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitCode(); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * visitMaxs is called just before visitEnd if there was any code to rewrite. 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For non-constructor, generate the messaging code and the return statement 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if it hasn't been done before. 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 186f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitMaxs(int maxStack, int maxLocals) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mIsInitMethod && !mMessageGenerated) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project generateInvoke(); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessageGenerated = true; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMaxs(maxStack, maxLocals); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 194865c3bef54228a353fd449a093b0c8d155618296Raphael Moll 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * End of visiting. 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For non-constructor, generate the messaging code and the return statement 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if it hasn't been done before. 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 200f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitEnd() { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mIsInitMethod && !mMessageGenerated) { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project generateInvoke(); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessageGenerated = true; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMaxs(1, 1); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitEnd(); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Writes all annotation from the original method. */ 211f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mParentVisitor.visitAnnotation(desc, visible); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Writes all annotation default values from the original method. */ 217f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AnnotationVisitor visitAnnotationDefault() { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mParentVisitor.visitAnnotationDefault(); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 222f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean visible) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mParentVisitor.visitParameterAnnotation(parameter, desc, visible); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Writes all attributes from the original method. */ 229f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitAttribute(Attribute attr) { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitAttribute(attr); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Only writes the first line number present in the original code so that source 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * viewers can direct to the correct method, even if the content doesn't match. 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 238f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitLineNumber(int line, Label start) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod || mOutputFirstLineNumber) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitLineNumber(line, start); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOutputFirstLineNumber = false; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For non-constructor, rewrite existing "return" instructions to write the message. 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 249f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitInsn(int opcode) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (opcode) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Opcodes.RETURN: 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Opcodes.ARETURN: 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Opcodes.DRETURN: 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Opcodes.FRETURN: 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Opcodes.IRETURN: 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case Opcodes.LRETURN: 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Pop the last word from the stack since invoke will generate its own return. 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project generatePop(); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project generateInvoke(); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessageGenerated = true; 263865c3bef54228a353fd449a093b0c8d155618296Raphael Moll //$FALL-THROUGH$ 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitInsn(opcode); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 270f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitLabel(Label label) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitLabel(label); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 277f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitTryCatchBlock(start, end, handler, type); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 284f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitMethodInsn(int opcode, String owner, String name, String desc) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMethodInsn(opcode, owner, name, desc); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 291f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitFieldInsn(int opcode, String owner, String name, String desc) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitFieldInsn(opcode, owner, name, desc); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 298f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitFrame(type, nLocal, local, nStack, stack); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 305f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitIincInsn(int var, int increment) { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitIincInsn(var, increment); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 312f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitIntInsn(int opcode, int operand) { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitIntInsn(opcode, operand); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitJumpInsn(int opcode, Label label) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitJumpInsn(opcode, label); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 326f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitLdcInsn(Object cst) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitLdcInsn(cst); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 333f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitLocalVariable(String name, String desc, String signature, 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Label start, Label end, int index) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitLocalVariable(name, desc, signature, start, end, index); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 341f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 348f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitMultiANewArrayInsn(String desc, int dims) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitMultiANewArrayInsn(desc, dims); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 355f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 362f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitTypeInsn(int opcode, String type) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitTypeInsn(opcode, type); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369f7270ba9083e5b0069f73fc88aec439ab439275bTor Norbye @Override 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void visitVarInsn(int opcode, int var) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mIsInitMethod) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mParentVisitor.visitVarInsn(opcode, var); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 375865c3bef54228a353fd449a093b0c8d155618296Raphael Moll 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 377