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: BooleanType.java,v 1.2.4.1 2005/09/05 11:03:37 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.INVOKEVIRTUAL;
43  import com.sun.org.apache.bcel.internal.generic.ISTORE;
44  import com.sun.org.apache.bcel.internal.generic.Instruction;
45  import com.sun.org.apache.bcel.internal.generic.InstructionList;
46  import com.sun.org.apache.bcel.internal.generic.NEW;
47  import com.sun.org.apache.bcel.internal.generic.PUSH;
48  import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
49  
50  /**
51   * @author Jacek Ambroziak
52   * @author Santiago Pericas-Geertsen
53   */
54  public final class BooleanType extends Type {
55      protected BooleanType() {}
56  
57      public String toString() {
58          return "boolean";
59      }
60  
61      public boolean identicalTo(Type other) {
62          return this == other;
63      }
64  
65      public String toSignature() {
66          return "Z";
67      }
68  
69      public boolean isSimple() {
70          return true;
71      }
72  
73      public com.sun.org.apache.bcel.internal.generic.Type toJCType() {
74          return com.sun.org.apache.bcel.internal.generic.Type.BOOLEAN;
75      }
76  
77      /**
78       * Translates a real into an object of internal type <code>type</code>. The
79       * translation to int is undefined since booleans are always converted to
80       * reals in arithmetic expressions.
81       *
82       * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
83       */
84      public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
85                              Type type) {
86          if (type == Type.String) {
87              translateTo(classGen, methodGen, (StringType) type);
88          }
89          else if (type == Type.Real) {
90              translateTo(classGen, methodGen, (RealType) 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     /**
103      * Expects a boolean on the stack and pushes a string. If the value on the
104      * stack is zero, then the string 'false' is pushed. Otherwise, the string
105      * 'true' is pushed.
106      *
107      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
108      */
109     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
110                             StringType type) {
111         final ConstantPoolGen cpg = classGen.getConstantPool();
112         final InstructionList il = methodGen.getInstructionList();
113         final BranchHandle falsec = il.append(new IFEQ(null));
114         il.append(new PUSH(cpg, "true"));
115         final BranchHandle truec = il.append(new GOTO(null));
116         falsec.setTarget(il.append(new PUSH(cpg, "false")));
117         truec.setTarget(il.append(NOP));
118     }
119 
120     /**
121      * Expects a boolean on the stack and pushes a real. The value "true" is
122      * converted to 1.0 and the value "false" to 0.0.
123      *
124      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
125      */
126     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
127                             RealType type) {
128         methodGen.getInstructionList().append(I2D);
129     }
130 
131     /**
132      * Expects a boolean on the stack and pushes a boxed boolean.
133      * Boxed booleans are represented by an instance of
134      * <code>java.lang.Boolean</code>.
135      *
136      * @see     com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
137      */
138     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
139                             ReferenceType type) {
140         final ConstantPoolGen cpg = classGen.getConstantPool();
141         final InstructionList il = methodGen.getInstructionList();
142         il.append(new NEW(cpg.addClass(BOOLEAN_CLASS)));
143         il.append(DUP_X1);
144         il.append(SWAP);
145         il.append(new INVOKESPECIAL(cpg.addMethodref(BOOLEAN_CLASS,
146                                                      "<init>",
147                                                      "(Z)V")));
148     }
149 
150     /**
151      * Translates an internal boolean into an external (Java) boolean.
152      */
153     public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
154                             Class clazz) {
155         if (clazz == java.lang.Boolean.TYPE) {
156             methodGen.getInstructionList().append(NOP);
157         }
158         // Is Boolean <: clazz? I.e. clazz in { Boolean, Object }
159         else if (clazz.isAssignableFrom(java.lang.Boolean.class)) {
160             translateTo(classGen, methodGen, Type.Reference);
161         }
162         else {
163             ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
164                                         toString(), clazz.getName());
165             classGen.getParser().reportError(Constants.FATAL, err);
166         }
167     }
168 
169     /**
170      * Translates an external (Java) boolean into internal boolean.
171      */
172     public void translateFrom(ClassGenerator classGen, MethodGenerator methodGen,
173                               Class clazz) {
174         translateTo(classGen, methodGen, clazz);
175     }
176 
177     /**
178      * Translates an object of this type to its boxed representation.
179      */
180     public void translateBox(ClassGenerator classGen,
181                              MethodGenerator methodGen) {
182         translateTo(classGen, methodGen, Type.Reference);
183     }
184 
185     /**
186      * Translates an object of this type to its unboxed representation.
187      */
188     public void translateUnBox(ClassGenerator classGen,
189                                MethodGenerator methodGen) {
190         final ConstantPoolGen cpg = classGen.getConstantPool();
191         final InstructionList il = methodGen.getInstructionList();
192         il.append(new CHECKCAST(cpg.addClass(BOOLEAN_CLASS)));
193         il.append(new INVOKEVIRTUAL(cpg.addMethodref(BOOLEAN_CLASS,
194                                                      BOOLEAN_VALUE,
195                                                      BOOLEAN_VALUE_SIG)));
196     }
197 
198     public Instruction LOAD(int slot) {
199         return new ILOAD(slot);
200     }
201 
202     public Instruction STORE(int slot) {
203         return new ISTORE(slot);
204     }
205 
206     public BranchInstruction GT(boolean tozero) {
207         return tozero ? (BranchInstruction) new IFGT(null) :
208             (BranchInstruction) new IF_ICMPGT(null);
209     }
210 
211     public BranchInstruction GE(boolean tozero) {
212         return tozero ? (BranchInstruction) new IFGE(null) :
213             (BranchInstruction) new IF_ICMPGE(null);
214     }
215 
216     public BranchInstruction LT(boolean tozero) {
217         return tozero ? (BranchInstruction) new IFLT(null) :
218             (BranchInstruction) new IF_ICMPLT(null);
219     }
220 
221     public BranchInstruction LE(boolean tozero) {
222         return tozero ? (BranchInstruction) new IFLE(null) :
223             (BranchInstruction) new IF_ICMPLE(null);
224     }
225 }