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