You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Instanceof.java 5.4KB

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