1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.mkstubs.stubber; 18 19 import com.android.mkstubs.Main; 20 21 import org.objectweb.asm.AnnotationVisitor; 22 import org.objectweb.asm.Attribute; 23 import org.objectweb.asm.Label; 24 import org.objectweb.asm.MethodVisitor; 25 import org.objectweb.asm.Opcodes; 26 27 /** 28 * A method visitor that generates a code stub for the visited method. 29 * <p/> 30 * Annotations and parameters are passed as-is. 31 * All other code is replaced by the following: 32 * <pre>throw new RuntimeException("stub");</pre> 33 * Note that constructors rewritten this way will probably fail with the runtime bytecode 34 * verifier since no call to <code>super</code> is generated. 35 */ 36 public class MethodStubber extends MethodVisitor { 37 MethodStubber(MethodVisitor mw, int access, String name, String desc, String signature, String[] exceptions)38 public MethodStubber(MethodVisitor mw, 39 int access, String name, String desc, String signature, String[] exceptions) { 40 super(Main.ASM_VERSION, mw); 41 } 42 43 @Override visitCode()44 public void visitCode() { 45 Label l0 = new Label(); 46 mv.visitLabel(l0); 47 mv.visitLineNumber(36, l0); 48 mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException"); 49 mv.visitInsn(Opcodes.DUP); 50 mv.visitLdcInsn("stub"); 51 mv.visitMethodInsn( 52 Opcodes.INVOKESPECIAL, // opcode 53 "java/lang/RuntimeException", // owner 54 "<init>", // name 55 "(Ljava/lang/String;)V", // desc 56 false); 57 mv.visitInsn(Opcodes.ATHROW); 58 Label l1 = new Label(); 59 mv.visitLabel(l1); 60 mv.visitLocalVariable( 61 "this", // name 62 "Lcom/android/mkstubs/stubber/MethodStubber;", // desc 63 null, // signature 64 l0, // label start 65 l1, // label end 66 0); // index 67 mv.visitMaxs(3, 1); // maxStack, maxLocals 68 } 69 70 @Override visitEnd()71 public void visitEnd() { 72 super.visitEnd(); 73 } 74 75 @Override visitAnnotation(String desc, boolean visible)76 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 77 return super.visitAnnotation(desc, visible); 78 } 79 80 @Override visitAnnotationDefault()81 public AnnotationVisitor visitAnnotationDefault() { 82 return super.visitAnnotationDefault(); 83 } 84 85 @Override visitAttribute(Attribute attr)86 public void visitAttribute(Attribute attr) { 87 super.visitAttribute(attr); 88 } 89 90 @Override visitParameterAnnotation(int parameter, String desc, boolean visible)91 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { 92 return super.visitParameterAnnotation(parameter, desc, visible); 93 } 94 95 // -- stuff that gets skipped 96 97 @Override visitFieldInsn(int opcode, String owner, String name, String desc)98 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 99 // skip 100 } 101 102 @Override visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2)103 public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { 104 // skip 105 } 106 107 @Override visitIincInsn(int var, int increment)108 public void visitIincInsn(int var, int increment) { 109 // skip 110 } 111 112 @Override visitInsn(int opcode)113 public void visitInsn(int opcode) { 114 // skip 115 } 116 117 @Override visitIntInsn(int opcode, int operand)118 public void visitIntInsn(int opcode, int operand) { 119 // skip 120 } 121 122 @Override visitJumpInsn(int opcode, Label label)123 public void visitJumpInsn(int opcode, Label label) { 124 // skip 125 } 126 127 @Override visitLabel(Label label)128 public void visitLabel(Label label) { 129 // skip 130 } 131 132 @Override visitLdcInsn(Object cst)133 public void visitLdcInsn(Object cst) { 134 // skip 135 } 136 137 @Override visitLineNumber(int line, Label start)138 public void visitLineNumber(int line, Label start) { 139 // skip 140 } 141 142 @Override visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index)143 public void visitLocalVariable(String name, String desc, String signature, 144 Label start, Label end, int index) { 145 // skip 146 } 147 148 @Override visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)149 public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 150 // skip 151 } 152 153 @Override visitMaxs(int maxStack, int maxLocals)154 public void visitMaxs(int maxStack, int maxLocals) { 155 // skip 156 } 157 158 @Override visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf)159 public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { 160 // skip 161 } 162 163 @Override visitMultiANewArrayInsn(String desc, int dims)164 public void visitMultiANewArrayInsn(String desc, int dims) { 165 // skip 166 } 167 168 @Override visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels)169 public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 170 // skip 171 } 172 173 @Override visitTryCatchBlock(Label start, Label end, Label handler, String type)174 public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 175 // skip 176 } 177 178 @Override visitTypeInsn(int opcode, String type)179 public void visitTypeInsn(int opcode, String type) { 180 // skip 181 } 182 183 @Override visitVarInsn(int opcode, int var)184 public void visitVarInsn(int opcode, int var) { 185 // skip 186 } 187 } 188