1ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/* 2ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Copyright (C) 2008 The Android Open Source Project 3ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 4ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * you may not use this file except in compliance with the License. 6ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * You may obtain a copy of the License at 7ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 8ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 10ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Unless required by applicable law or agreed to in writing, software 11ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * See the License for the specific language governing permissions and 14ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * limitations under the License. 15ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 16ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 17ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipackage com.android.tools.layoutlib.create; 18ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 19ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.AnnotationVisitor; 20ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.Attribute; 21ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.Label; 22ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.MethodVisitor; 23ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.Opcodes; 24ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport org.objectweb.asm.Type; 25ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 26ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/** 27ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * This method adapter rewrites a method by discarding the original code and generating 28ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * a stub depending on the return type. Original annotations are passed along unchanged. 29ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 30ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiclass StubMethodAdapter extends MethodVisitor { 31ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 32b77a349014d1fade2185a53c2a58edaa4b971dbeDeepanshu Gupta private static final String CONSTRUCTOR = "<init>"; 33b77a349014d1fade2185a53c2a58edaa4b971dbeDeepanshu Gupta private static final String CLASS_INIT = "<clinit>"; 34ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 35ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** The parent method writer */ 36ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private MethodVisitor mParentVisitor; 37ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** The method return type. Can be null. */ 38ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private Type mReturnType; 39ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** Message to be printed by stub methods. */ 40ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private String mInvokeSignature; 41ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** Flag to output the first line number. */ 42ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private boolean mOutputFirstLineNumber = true; 43ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** Flag that is true when implementing a constructor, to accept all original 44ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * code calling the original super constructor. */ 45ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private boolean mIsInitMethod = false; 46ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 47ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private boolean mMessageGenerated; 48ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private final boolean mIsStatic; 49ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private final boolean mIsNative; 50ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 51ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType, 52ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String invokeSignature, boolean isStatic, boolean isNative) { 53528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta super(Main.ASM_VERSION); 54ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor = mv; 55ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mReturnType = returnType; 56ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mInvokeSignature = invokeSignature; 57ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mIsStatic = isStatic; 58ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mIsNative = isNative; 59ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 60ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) { 61ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mIsInitMethod = true; 62ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 63ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 64ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 65ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private void generateInvoke() { 66ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /* Generates the code: 67ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * OverrideMethod.invoke("signature", mIsNative ? true : false, null or this); 68ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 69ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitLdcInsn(mInvokeSignature); 70ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // push true or false 71ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0); 72ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // push null or this 73ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsStatic) { 74ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.ACONST_NULL); 75ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } else { 76ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0); 77ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 78ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 79ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID; 80ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski switch(sort) { 81ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.VOID: 82ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 83ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 84ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "invokeV", 85528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta "(Ljava/lang/String;ZLjava/lang/Object;)V", 86528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta false); 87ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.RETURN); 88ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 89ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.BOOLEAN: 90ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.CHAR: 91ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.BYTE: 92ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.SHORT: 93ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.INT: 94ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 95ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 96ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "invokeI", 97528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta "(Ljava/lang/String;ZLjava/lang/Object;)I", 98528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta false); 99ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski switch(sort) { 100ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.BOOLEAN: 101ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Label l1 = new Label(); 102ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1); 103ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.ICONST_1); 104ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.IRETURN); 105ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitLabel(l1); 106fbe158f5e1f77cea2a335834a1c91fea1c4680aaDeepanshu Gupta mParentVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null); 107ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.ICONST_0); 108ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 109ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.CHAR: 110ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.I2C); 111ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 112ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.BYTE: 113ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.I2B); 114ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 115ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.SHORT: 116ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.I2S); 117ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 118ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 119ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.IRETURN); 120ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 121ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.LONG: 122ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 123ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 124ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "invokeL", 125528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta "(Ljava/lang/String;ZLjava/lang/Object;)J", 126528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta false); 127ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.LRETURN); 128ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 129ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.FLOAT: 130ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 131ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 132ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "invokeF", 133528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta "(Ljava/lang/String;ZLjava/lang/Object;)F", 134528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta false); 135ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.FRETURN); 136ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 137ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.DOUBLE: 138ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 139ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 140ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "invokeD", 141528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta "(Ljava/lang/String;ZLjava/lang/Object;)D", 142528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta false); 143ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.DRETURN); 144ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 145ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.ARRAY: 146ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.OBJECT: 147ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 148ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 149ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "invokeA", 150528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;", 151528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta false); 152ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName()); 153ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.ARETURN); 154ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 155ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 156ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 157ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 158ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 159ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private void generatePop() { 160ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /* Pops the stack, depending on the return type. 161ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 162ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) { 163ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.VOID: 164ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 165ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.BOOLEAN: 166ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.CHAR: 167ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.BYTE: 168ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.SHORT: 169ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.INT: 170ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.FLOAT: 171ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.ARRAY: 172ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.OBJECT: 173ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.POP); 174ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 175ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.LONG: 176ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Type.DOUBLE: 177ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(Opcodes.POP2); 178ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski break; 179ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 180ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 181ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 182ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /* Pass down to visitor writer. In this implementation, either do nothing. */ 183ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 184ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitCode() { 185ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitCode(); 186ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 187ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 188ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /* 189ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * visitMaxs is called just before visitEnd if there was any code to rewrite. 190ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * For non-constructor, generate the messaging code and the return statement 191ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * if it hasn't been done before. 192ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 193ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 194ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitMaxs(int maxStack, int maxLocals) { 195ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (!mIsInitMethod && !mMessageGenerated) { 196ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski generateInvoke(); 197ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mMessageGenerated = true; 198ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 199ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMaxs(maxStack, maxLocals); 200ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 201ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 202ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 203ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * End of visiting. 204ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * For non-constructor, generate the messaging code and the return statement 205ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * if it hasn't been done before. 206ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 207ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 208ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitEnd() { 209ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (!mIsInitMethod && !mMessageGenerated) { 210ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski generateInvoke(); 211ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mMessageGenerated = true; 212ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMaxs(1, 1); 213ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 214ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitEnd(); 215ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 216ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 217ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /* Writes all annotation from the original method. */ 218ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 219ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 220ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mParentVisitor.visitAnnotation(desc, visible); 221ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 222ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 223ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /* Writes all annotation default values from the original method. */ 224ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 225ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitAnnotationDefault() { 226ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mParentVisitor.visitAnnotationDefault(); 227ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 228ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 229ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 230ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, 231ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski boolean visible) { 232ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mParentVisitor.visitParameterAnnotation(parameter, desc, visible); 233ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 234ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 235ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /* Writes all attributes from the original method. */ 236ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 237ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitAttribute(Attribute attr) { 238ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitAttribute(attr); 239ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 240ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 241ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /* 242ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Only writes the first line number present in the original code so that source 243ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * viewers can direct to the correct method, even if the content doesn't match. 244ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 245ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 246ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLineNumber(int line, Label start) { 247ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod || mOutputFirstLineNumber) { 248ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitLineNumber(line, start); 249ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mOutputFirstLineNumber = false; 250ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 251ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 252ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 253ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 254ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * For non-constructor, rewrite existing "return" instructions to write the message. 255ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 256ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 257ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitInsn(int opcode) { 258ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 259ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski switch (opcode) { 260ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Opcodes.RETURN: 261ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Opcodes.ARETURN: 262ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Opcodes.DRETURN: 263ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Opcodes.FRETURN: 264ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Opcodes.IRETURN: 265ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski case Opcodes.LRETURN: 266ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Pop the last word from the stack since invoke will generate its own return. 267ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski generatePop(); 268ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski generateInvoke(); 269ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mMessageGenerated = true; 270ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski //$FALL-THROUGH$ 271ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski default: 272ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitInsn(opcode); 273ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 274ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 275ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 276ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 277ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 278ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLabel(Label label) { 279ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 280ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitLabel(label); 281ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 282ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 283ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 284ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 285ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 286ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 287ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitTryCatchBlock(start, end, handler, type); 288ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 289ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 290ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 291ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 292528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { 293ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 294528ddbf71ab1cac494e9a1aa50b9c8b76ba29586Deepanshu Gupta mParentVisitor.visitMethodInsn(opcode, owner, name, desc, itf); 295ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 296ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 297ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 298ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 299ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitFieldInsn(int opcode, String owner, String name, String desc) { 300ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 301ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitFieldInsn(opcode, owner, name, desc); 302ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 303ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 304ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 305ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 306ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { 307ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 308ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitFrame(type, nLocal, local, nStack, stack); 309ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 310ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 311ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 312ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 313ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitIincInsn(int var, int increment) { 314ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 315ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitIincInsn(var, increment); 316ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 317ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 318ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 319ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 320ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitIntInsn(int opcode, int operand) { 321ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 322ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitIntInsn(opcode, operand); 323ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 324ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 325ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 326ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 327ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitJumpInsn(int opcode, Label label) { 328ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 329ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitJumpInsn(opcode, label); 330ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 331ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 332ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 333ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 334ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLdcInsn(Object cst) { 335ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 336ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitLdcInsn(cst); 337ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 338ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 339ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 340ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 341ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLocalVariable(String name, String desc, String signature, 342ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Label start, Label end, int index) { 343ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 344ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitLocalVariable(name, desc, signature, start, end, index); 345ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 346ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 347ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 348ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 349ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 350ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 351ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels); 352ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 353ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 354ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 355ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 356ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitMultiANewArrayInsn(String desc, int dims) { 357ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 358ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitMultiANewArrayInsn(desc, dims); 359ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 360ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 361ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 362ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 363ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 364ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 365ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels); 366ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 367ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 368ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 369ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 370ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitTypeInsn(int opcode, String type) { 371ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 372ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitTypeInsn(opcode, type); 373ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 374ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 375ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 376ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 377ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void visitVarInsn(int opcode, int var) { 378ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mIsInitMethod) { 379ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mParentVisitor.visitVarInsn(opcode, var); 380ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 381ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 382ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 383ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski} 384