1 /* 2 * Javassist, a Java-bytecode translator toolkit. 3 * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 4 * 5 * The contents of this file are subject to the Mozilla Public License Version 6 * 1.1 (the "License"); you may not use this file except in compliance with 7 * the License. Alternatively, the contents of this file may be used under 8 * the terms of the GNU Lesser General Public License Version 2.1 or later. 9 * 10 * Software distributed under the License is distributed on an "AS IS" basis, 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 * for the specific language governing rights and limitations under the 13 * License. 14 */ 15 16 package javassist.expr; 17 18 import javassist.*; 19 import javassist.bytecode.*; 20 import javassist.compiler.*; 21 22 /** 23 * A <code>catch</code> clause or a <code>finally</code> block. 24 */ 25 public class Handler extends Expr { 26 private static String EXCEPTION_NAME = "$1"; 27 private ExceptionTable etable; 28 private int index; 29 30 /** 31 * Undocumented constructor. Do not use; internal-use only. 32 */ Handler(ExceptionTable et, int nth, CodeIterator it, CtClass declaring, MethodInfo m)33 protected Handler(ExceptionTable et, int nth, 34 CodeIterator it, CtClass declaring, MethodInfo m) { 35 super(et.handlerPc(nth), it, declaring, m); 36 etable = et; 37 index = nth; 38 } 39 40 /** 41 * Returns the method or constructor containing the catch clause. 42 */ where()43 public CtBehavior where() { return super.where(); } 44 45 /** 46 * Returns the source line number of the catch clause. 47 * 48 * @return -1 if this information is not available. 49 */ getLineNumber()50 public int getLineNumber() { 51 return super.getLineNumber(); 52 } 53 54 /** 55 * Returns the source file containing the catch clause. 56 * 57 * @return null if this information is not available. 58 */ getFileName()59 public String getFileName() { 60 return super.getFileName(); 61 } 62 63 /** 64 * Returns the list of exceptions that the catch clause may throw. 65 */ mayThrow()66 public CtClass[] mayThrow() { 67 return super.mayThrow(); 68 } 69 70 /** 71 * Returns the type handled by the catch clause. 72 * If this is a <code>finally</code> block, <code>null</code> is returned. 73 */ getType()74 public CtClass getType() throws NotFoundException { 75 int type = etable.catchType(index); 76 if (type == 0) 77 return null; 78 else { 79 ConstPool cp = getConstPool(); 80 String name = cp.getClassInfo(type); 81 return thisClass.getClassPool().getCtClass(name); 82 } 83 } 84 85 /** 86 * Returns true if this is a <code>finally</code> block. 87 */ isFinally()88 public boolean isFinally() { 89 return etable.catchType(index) == 0; 90 } 91 92 /** 93 * This method has not been implemented yet. 94 * 95 * @param statement a Java statement except try-catch. 96 */ replace(String statement)97 public void replace(String statement) throws CannotCompileException { 98 throw new RuntimeException("not implemented yet"); 99 } 100 101 /** 102 * Inserts bytecode at the beginning of the catch clause. 103 * The caught exception is stored in <code>$1</code>. 104 * 105 * @param src the source code representing the inserted bytecode. 106 * It must be a single statement or block. 107 */ insertBefore(String src)108 public void insertBefore(String src) throws CannotCompileException { 109 edited = true; 110 111 ConstPool cp = getConstPool(); 112 CodeAttribute ca = iterator.get(); 113 Javac jv = new Javac(thisClass); 114 Bytecode b = jv.getBytecode(); 115 b.setStackDepth(1); 116 b.setMaxLocals(ca.getMaxLocals()); 117 118 try { 119 CtClass type = getType(); 120 int var = jv.recordVariable(type, EXCEPTION_NAME); 121 jv.recordReturnType(type, false); 122 b.addAstore(var); 123 jv.compileStmnt(src); 124 b.addAload(var); 125 126 int oldHandler = etable.handlerPc(index); 127 b.addOpcode(Opcode.GOTO); 128 b.addIndex(oldHandler - iterator.getCodeLength() 129 - b.currentPc() + 1); 130 131 maxStack = b.getMaxStack(); 132 maxLocals = b.getMaxLocals(); 133 134 int pos = iterator.append(b.get()); 135 iterator.append(b.getExceptionTable(), pos); 136 etable.setHandlerPc(index, pos); 137 } 138 catch (NotFoundException e) { 139 throw new CannotCompileException(e); 140 } 141 catch (CompileError e) { 142 throw new CannotCompileException(e); 143 } 144 } 145 } 146