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 org.objectweb.asm.AnnotationVisitor; 20 import org.objectweb.asm.Attribute; 21 import org.objectweb.asm.Label; 22 import org.objectweb.asm.MethodAdapter; 23 import org.objectweb.asm.MethodVisitor; 24 import org.objectweb.asm.Opcodes; 25 26 /** 27 * A method visitor that generates a code stub for the visited method. 28 * <p/> 29 * Annotations and parameters are passed as-is. 30 * All other code is replaced by the following: 31 * <pre>throw new RuntimeException("stub");</pre> 32 * Note that constructors rewritten this way will probably fail with the runtime bytecode 33 * verifier since no call to <code>super</code> is generated. 34 */ 35 public class MethodStubber extends MethodAdapter { 36 MethodStubber(MethodVisitor mw, int access, String name, String desc, String signature, String[] exceptions)37 public MethodStubber(MethodVisitor mw, 38 int access, String name, String desc, String signature, String[] exceptions) { 39 super(mw); 40 } 41 42 @Override visitCode()43 public void visitCode() { 44 Label l0 = new Label(); 45 mv.visitLabel(l0); 46 mv.visitLineNumber(36, l0); 47 mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException"); 48 mv.visitInsn(Opcodes.DUP); 49 mv.visitLdcInsn("stub"); 50 mv.visitMethodInsn( 51 Opcodes.INVOKESPECIAL, // opcode 52 "java/lang/RuntimeException", // owner 53 "<init>", // name 54 "(Ljava/lang/String;)V"); // desc 55 mv.visitInsn(Opcodes.ATHROW); 56 Label l1 = new Label(); 57 mv.visitLabel(l1); 58 mv.visitLocalVariable( 59 "this", // name 60 "Lcom/android/mkstubs/stubber/MethodStubber;", // desc 61 null, // signature 62 l0, // label start 63 l1, // label end 64 0); // index 65 mv.visitMaxs(3, 1); // maxStack, maxLocals 66 } 67 68 @Override visitEnd()69 public void visitEnd() { 70 super.visitEnd(); 71 } 72 73 @Override visitAnnotation(String desc, boolean visible)74 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 75 return super.visitAnnotation(desc, visible); 76 } 77 78 @Override visitAnnotationDefault()79 public AnnotationVisitor visitAnnotationDefault() { 80 return super.visitAnnotationDefault(); 81 } 82 83 @Override visitAttribute(Attribute attr)84 public void visitAttribute(Attribute attr) { 85 super.visitAttribute(attr); 86 } 87 88 @Override visitParameterAnnotation(int parameter, String desc, boolean visible)89 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { 90 return super.visitParameterAnnotation(parameter, desc, visible); 91 } 92 93 // -- stuff that gets skipped 94 95 @Override visitFieldInsn(int opcode, String owner, String name, String desc)96 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 97 // skip 98 } 99 100 @Override visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2)101 public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { 102 // skip 103 } 104 105 @Override visitIincInsn(int var, int increment)106 public void visitIincInsn(int var, int increment) { 107 // skip 108 } 109 110 @Override visitInsn(int opcode)111 public void visitInsn(int opcode) { 112 // skip 113 } 114 115 @Override visitIntInsn(int opcode, int operand)116 public void visitIntInsn(int opcode, int operand) { 117 // skip 118 } 119 120 @Override visitJumpInsn(int opcode, Label label)121 public void visitJumpInsn(int opcode, Label label) { 122 // skip 123 } 124 125 @Override visitLabel(Label label)126 public void visitLabel(Label label) { 127 // skip 128 } 129 130 @Override visitLdcInsn(Object cst)131 public void visitLdcInsn(Object cst) { 132 // skip 133 } 134 135 @Override visitLineNumber(int line, Label start)136 public void visitLineNumber(int line, Label start) { 137 // skip 138 } 139 140 @Override visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index)141 public void visitLocalVariable(String name, String desc, String signature, 142 Label start, Label end, int index) { 143 // skip 144 } 145 146 @Override visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)147 public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 148 // skip 149 } 150 151 @Override visitMaxs(int maxStack, int maxLocals)152 public void visitMaxs(int maxStack, int maxLocals) { 153 // skip 154 } 155 156 @Override visitMethodInsn(int opcode, String owner, String name, String desc)157 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 158 // skip 159 } 160 161 @Override visitMultiANewArrayInsn(String desc, int dims)162 public void visitMultiANewArrayInsn(String desc, int dims) { 163 // skip 164 } 165 166 @Override visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels)167 public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 168 // skip 169 } 170 171 @Override visitTryCatchBlock(Label start, Label end, Label handler, String type)172 public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 173 // skip 174 } 175 176 @Override visitTypeInsn(int opcode, String type)177 public void visitTypeInsn(int opcode, String type) { 178 // skip 179 } 180 181 @Override visitVarInsn(int opcode, int var)182 public void visitVarInsn(int opcode, int var) { 183 // skip 184 } 185 } 186