Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

Cast.java 6.1KB

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