1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * $Id: IntType.java,v 1.8 2004/02/16 22:26:44 minchau Exp $
  18. */
  19. package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
  20. import com.sun.org.apache.bcel.internal.generic.BranchHandle;
  21. import com.sun.org.apache.bcel.internal.generic.BranchInstruction;
  22. import com.sun.org.apache.bcel.internal.generic.CHECKCAST;
  23. import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
  24. import com.sun.org.apache.bcel.internal.generic.GOTO;
  25. import com.sun.org.apache.bcel.internal.generic.IFEQ;
  26. import com.sun.org.apache.bcel.internal.generic.IFGE;
  27. import com.sun.org.apache.bcel.internal.generic.IFGT;
  28. import com.sun.org.apache.bcel.internal.generic.IFLE;
  29. import com.sun.org.apache.bcel.internal.generic.IFLT;
  30. import com.sun.org.apache.bcel.internal.generic.IF_ICMPGE;
  31. import com.sun.org.apache.bcel.internal.generic.IF_ICMPGT;
  32. import com.sun.org.apache.bcel.internal.generic.IF_ICMPLE;
  33. import com.sun.org.apache.bcel.internal.generic.IF_ICMPLT;
  34. import com.sun.org.apache.bcel.internal.generic.ILOAD;
  35. import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
  36. import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
  37. import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
  38. import com.sun.org.apache.bcel.internal.generic.ISTORE;
  39. import com.sun.org.apache.bcel.internal.generic.Instruction;
  40. import com.sun.org.apache.bcel.internal.generic.InstructionConstants;
  41. import com.sun.org.apache.bcel.internal.generic.InstructionList;
  42. import com.sun.org.apache.bcel.internal.generic.NEW;
  43. import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
  44. import com.sun.org.apache.xalan.internal.xsltc.compiler.FlowList;
  45. /**
  46. * @author Jacek Ambroziak
  47. * @author Santiago Pericas-Geertsen
  48. */
  49. public final class IntType extends NumberType {
  50. protected IntType() {}
  51. public String toString() {
  52. return "int";
  53. }
  54. public boolean identicalTo(Type other) {
  55. return this == other;
  56. }
  57. public String toSignature() {
  58. return "I";
  59. }
  60. public com.sun.org.apache.bcel.internal.generic.Type toJCType() {
  61. return com.sun.org.apache.bcel.internal.generic.Type.INT;
  62. }
  63. /**
  64. * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#distanceTo
  65. */
  66. public int distanceTo(Type type) {
  67. if (type == this) {
  68. return 0;
  69. }
  70. else if (type == Type.Real) {
  71. return 1;
  72. }
  73. else
  74. return Integer.MAX_VALUE;
  75. }
  76. /**
  77. * Translates an integer into an object of internal type <code>type</code>.
  78. *
  79. * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
  80. */
  81. public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
  82. final Type type) {
  83. if (type == Type.Real) {
  84. translateTo(classGen, methodGen, (RealType) type);
  85. }
  86. else if (type == Type.String) {
  87. translateTo(classGen, methodGen, (StringType) type);
  88. }
  89. else if (type == Type.Boolean) {
  90. translateTo(classGen, methodGen, (BooleanType) type);
  91. }
  92. else if (type == Type.Reference) {
  93. translateTo(classGen, methodGen, (ReferenceType) type);
  94. }
  95. else {
  96. ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
  97. toString(), type.toString());
  98. classGen.getParser().reportError(Constants.FATAL, err);
  99. }
  100. }
  101. /**
  102. * Expects an integer on the stack and pushes a real.
  103. *
  104. * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
  105. */
  106. public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
  107. RealType type) {
  108. methodGen.getInstructionList().append(I2D);
  109. }
  110. /**
  111. * Expects an integer on the stack and pushes its string value by calling
  112. * <code>Integer.toString(int i)</code>.
  113. *
  114. * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
  115. */
  116. public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
  117. StringType type) {
  118. final ConstantPoolGen cpg = classGen.getConstantPool();
  119. final InstructionList il = methodGen.getInstructionList();
  120. il.append(new INVOKESTATIC(cpg.addMethodref(INTEGER_CLASS,
  121. "toString",
  122. "(I)" + STRING_SIG)));
  123. }
  124. /**
  125. * Expects an integer on the stack and pushes a 0 if its value is 0 and
  126. * a 1 otherwise.
  127. *
  128. * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
  129. */
  130. public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
  131. BooleanType type) {
  132. final InstructionList il = methodGen.getInstructionList();
  133. final BranchHandle falsec = il.append(new IFEQ(null));
  134. il.append(ICONST_1);
  135. final BranchHandle truec = il.append(new GOTO(null));
  136. falsec.setTarget(il.append(ICONST_0));
  137. truec.setTarget(il.append(NOP));
  138. }
  139. /**
  140. * Expects an integer on the stack and translates it to a non-synthesized
  141. * boolean. It does not push a 0 or a 1 but instead returns branchhandle
  142. * list to be appended to the false list.
  143. *
  144. * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateToDesynthesized
  145. */
  146. public FlowList translateToDesynthesized(ClassGenerator classGen,
  147. MethodGenerator methodGen,
  148. BooleanType type) {
  149. final InstructionList il = methodGen.getInstructionList();
  150. return new FlowList(il.append(new IFEQ(null)));
  151. }
  152. /**
  153. * Expects an integer on the stack and pushes a boxed integer.
  154. * Boxed integers are represented by an instance of
  155. * <code>java.lang.Integer</code>.
  156. *
  157. * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
  158. */
  159. public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
  160. ReferenceType type) {
  161. final ConstantPoolGen cpg = classGen.getConstantPool();
  162. final InstructionList il = methodGen.getInstructionList();
  163. il.append(new NEW(cpg.addClass(INTEGER_CLASS)));
  164. il.append(DUP_X1);
  165. il.append(SWAP);
  166. il.append(new INVOKESPECIAL(cpg.addMethodref(INTEGER_CLASS,
  167. "<init>", "(I)V")));
  168. }
  169. /**
  170. * Translates an integer into the Java type denoted by <code>clazz</code>.
  171. * Expects an integer on the stack and pushes a number of the appropriate
  172. * type after coercion.
  173. */
  174. public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
  175. Class clazz) {
  176. final InstructionList il = methodGen.getInstructionList();
  177. if (clazz == Character.TYPE) {
  178. il.append(I2C);
  179. }
  180. else if (clazz == Byte.TYPE) {
  181. il.append(I2B);
  182. }
  183. else if (clazz == Short.TYPE) {
  184. il.append(I2S);
  185. }
  186. else if (clazz == Integer.TYPE) {
  187. il.append(NOP);
  188. }
  189. else if (clazz == Long.TYPE) {
  190. il.append(I2L);
  191. }
  192. else if (clazz == Float.TYPE) {
  193. il.append(I2F);
  194. }
  195. else if (clazz == Double.TYPE) {
  196. il.append(I2D);
  197. }
  198. // Is Double <: clazz? I.e. clazz in { Double, Number, Object }
  199. else if (clazz.isAssignableFrom(java.lang.Double.class)) {
  200. il.append(I2D);
  201. Type.Real.translateTo(classGen, methodGen, Type.Reference);
  202. }
  203. else {
  204. ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
  205. toString(), clazz.getName());
  206. classGen.getParser().reportError(Constants.FATAL, err);
  207. }
  208. }
  209. /**
  210. * Translates an object of this type to its boxed representation.
  211. */
  212. public void translateBox(ClassGenerator classGen,
  213. MethodGenerator methodGen) {
  214. translateTo(classGen, methodGen, Type.Reference);
  215. }
  216. /**
  217. * Translates an object of this type to its unboxed representation.
  218. */
  219. public void translateUnBox(ClassGenerator classGen,
  220. MethodGenerator methodGen) {
  221. final ConstantPoolGen cpg = classGen.getConstantPool();
  222. final InstructionList il = methodGen.getInstructionList();
  223. il.append(new CHECKCAST(cpg.addClass(INTEGER_CLASS)));
  224. final int index = cpg.addMethodref(INTEGER_CLASS,
  225. INT_VALUE,
  226. INT_VALUE_SIG);
  227. il.append(new INVOKEVIRTUAL(index));
  228. }
  229. public Instruction ADD() {
  230. return InstructionConstants.IADD;
  231. }
  232. public Instruction SUB() {
  233. return InstructionConstants.ISUB;
  234. }
  235. public Instruction MUL() {
  236. return InstructionConstants.IMUL;
  237. }
  238. public Instruction DIV() {
  239. return InstructionConstants.IDIV;
  240. }
  241. public Instruction REM() {
  242. return InstructionConstants.IREM;
  243. }
  244. public Instruction NEG() {
  245. return InstructionConstants.INEG;
  246. }
  247. public Instruction LOAD(int slot) {
  248. return new ILOAD(slot);
  249. }
  250. public Instruction STORE(int slot) {
  251. return new ISTORE(slot);
  252. }
  253. public BranchInstruction GT(boolean tozero) {
  254. return tozero ? (BranchInstruction) new IFGT(null) :
  255. (BranchInstruction) new IF_ICMPGT(null);
  256. }
  257. public BranchInstruction GE(boolean tozero) {
  258. return tozero ? (BranchInstruction) new IFGE(null) :
  259. (BranchInstruction) new IF_ICMPGE(null);
  260. }
  261. public BranchInstruction LT(boolean tozero) {
  262. return tozero ? (BranchInstruction) new IFLT(null) :
  263. (BranchInstruction) new IF_ICMPLT(null);
  264. }
  265. public BranchInstruction LE(boolean tozero) {
  266. return tozero ? (BranchInstruction) new IFLE(null) :
  267. (BranchInstruction) new IF_ICMPLE(null);
  268. }
  269. }