/Users/lyon/j4p/src/javassist/expr/Instanceof.java
|
1 /*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2003 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 import javassist.compiler.ast.ASTList;
22
23 /**
24 * Instanceof operator.
25 */
26 public class Instanceof extends Expr {
27 /**
28 * Undocumented constructor. Do not use; internal-use only.
29 */
30 Instanceof(int pos, CodeIterator i, CtClass declaring, MethodInfo m) {
31 super(pos, i, declaring, m);
32 }
33
34 /**
35 * Returns the method or constructor containing the instanceof
36 * expression represented by this object.
37 */
38 public CtBehavior where() {
39 return super.where();
40 }
41
42 /**
43 * Returns the line number of the source line containing the
44 * instanceof expression.
45 *
46 * @return -1 if this information is not available.
47 */
48 public int getLineNumber() {
49 return super.getLineNumber();
50 }
51
52 /**
53 * Returns the source file containing the
54 * instanceof expression.
55 *
56 * @return null if this information is not available.
57 */
58 public String getFileName() {
59 return super.getFileName();
60 }
61
62 /**
63 * Returns the <code>CtClass</code> object representing
64 * the type name on the right hand side
65 * of the instanceof operator.
66 */
67 public CtClass getType() throws NotFoundException {
68 ConstPool cp = getConstPool();
69 int pos = currentPos;
70 int index = iterator.u16bitAt(pos + 1);
71 String name = cp.getClassInfo(index);
72 return Descriptor.toCtClass(name, thisClass.getClassPool());
73 }
74
75 /**
76 * Returns the list of exceptions that the expression may throw.
77 * This list includes both the exceptions that the try-catch statements
78 * including the expression can catch and the exceptions that
79 * the throws declaration allows the method to throw.
80 */
81 public CtClass[] mayThrow() {
82 return super.mayThrow();
83 }
84
85 /**
86 * Replaces the instanceof operator with the bytecode derived from
87 * the given source text.
88 *
89 * <p>$0 is available but the value is <code>null</code>.
90 *
91 * @param statement a Java statement.
92 */
93 public void replace(String statement) throws CannotCompileException {
94 ConstPool constPool = getConstPool();
95 int pos = currentPos;
96 int index = iterator.u16bitAt(pos + 1);
97
98 Javac jc = new Javac(thisClass);
99 ClassPool cp = thisClass.getClassPool();
100 CodeAttribute ca = iterator.get();
101
102 try {
103 CtClass[] params
104 = new CtClass[]{cp.get(javaLangObject)};
105 CtClass retType = CtClass.booleanType;
106
107 int paramVar = ca.getMaxLocals();
108 jc.recordParams(javaLangObject, params, true, paramVar,
109 withinStatic());
110 int retVar = jc.recordReturnType(retType, true);
111 jc.recordProceed(new ProceedForInstanceof(index));
112
113 // because $type is not the return type...
114 jc.recordType(getType());
115
116 /* Is $_ included in the source code?
117 */
118 checkResultValue(retType, statement);
119
120 Bytecode bytecode = jc.getBytecode();
121 storeStack(params, true, paramVar, bytecode);
122 jc.compileStmnt(statement);
123 bytecode.addLoad(retVar, retType);
124
125 replace0(pos, bytecode, 3);
126 } catch (CompileError e) {
127 throw new CannotCompileException(e);
128 } catch (NotFoundException e) {
129 throw new CannotCompileException(e);
130 } catch (BadBytecode e) {
131 throw new CannotCompileException("broken method");
132 }
133 }
134
135 /* boolean $proceed(Object obj)
136 */
137 static class ProceedForInstanceof implements ProceedHandler {
138 int index;
139
140 ProceedForInstanceof(int i) {
141 index = i;
142 }
143
144 public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args)
145 throws CompileError {
146 if (gen.atMethodArgsLength(args) != 1)
147 throw new CompileError(Javac.proceedName
148 + "() cannot take more than one parameter "
149 + "for instanceof");
150
151 gen.atMethodArgs(args, new int[1], new int[1], new String[1]);
152 bytecode.addOpcode(Opcode.INSTANCEOF);
153 bytecode.addIndex(index);
154 gen.setType(CtClass.booleanType);
155 }
156 }
157 }
158