001: /*
002: * Javassist, a Java-bytecode translator toolkit.
003: * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
004: *
005: * The contents of this file are subject to the Mozilla Public License Version
006: * 1.1 (the "License"); you may not use this file except in compliance with
007: * the License. Alternatively, the contents of this file may be used under
008: * the terms of the GNU Lesser General Public License Version 2.1 or later.
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the
013: * License.
014: */
015:
016: package javassist.expr;
017:
018: import javassist.*;
019: import javassist.bytecode.*;
020: import javassist.compiler.*;
021:
022: /**
023: * Catch clause.
024: */
025: public class Handler extends Expr {
026: private static String EXCEPTION_NAME = "$1";
027: private ExceptionTable etable;
028: private int index;
029:
030: /**
031: * Undocumented constructor. Do not use; internal-use only.
032: */
033: protected Handler(ExceptionTable et, int nth, CodeIterator it,
034: CtClass declaring, MethodInfo m) {
035: super (et.handlerPc(nth), it, declaring, m);
036: etable = et;
037: index = nth;
038: }
039:
040: /**
041: * Returns the method or constructor containing the catch clause.
042: */
043: public CtBehavior where() {
044: return super .where();
045: }
046:
047: /**
048: * Returns the source line number of the catch clause.
049: *
050: * @return -1 if this information is not available.
051: */
052: public int getLineNumber() {
053: return super .getLineNumber();
054: }
055:
056: /**
057: * Returns the source file containing the catch clause.
058: *
059: * @return null if this information is not available.
060: */
061: public String getFileName() {
062: return super .getFileName();
063: }
064:
065: /**
066: * Returns the list of exceptions that the catch clause may throw.
067: */
068: public CtClass[] mayThrow() {
069: return super .mayThrow();
070: }
071:
072: /**
073: * Returns the type handled by the catch clause.
074: */
075: public CtClass getType() throws NotFoundException {
076: ConstPool cp = getConstPool();
077: String name = cp.getClassInfo(etable.catchType(index));
078: return Descriptor.toCtClass(name, this Class.getClassPool());
079: }
080:
081: /**
082: * This method has not been implemented yet.
083: *
084: * @param statement a Java statement.
085: */
086: public void replace(String statement) throws CannotCompileException {
087: throw new RuntimeException("not implemented yet");
088: }
089:
090: /**
091: * Inserts bytecode at the beginning of the catch clause.
092: * The caught exception is stored in <code>$1</code>.
093: *
094: * @param src the source code representing the inserted bytecode.
095: * It must be a single statement or block.
096: */
097: public void insertBefore(String src) throws CannotCompileException {
098: edited = true;
099:
100: ConstPool cp = getConstPool();
101: CodeAttribute ca = iterator.get();
102: Javac jv = new Javac(this Class);
103: Bytecode b = jv.getBytecode();
104: b.setStackDepth(1);
105: b.setMaxLocals(ca.getMaxLocals());
106:
107: try {
108: CtClass type = getType();
109: int var = jv.recordVariable(type, EXCEPTION_NAME);
110: jv.recordReturnType(type, false);
111: b.addAstore(var);
112: jv.compileStmnt(src);
113: b.addAload(var);
114:
115: int oldHandler = etable.handlerPc(index);
116: b.addOpcode(Opcode.GOTO);
117: b.addIndex(oldHandler - iterator.getCodeLength()
118: - b.currentPc() + 1);
119:
120: maxStack = b.getMaxStack();
121: maxLocals = b.getMaxLocals();
122:
123: int pos = iterator.append(b.get());
124: iterator.append(b.getExceptionTable(), pos);
125: etable.setHandlerPc(index, pos);
126: } catch (NotFoundException e) {
127: throw new CannotCompileException(e);
128: } catch (CompileError e) {
129: throw new CannotCompileException(e);
130: }
131: }
132: }
|