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