1 /*
2 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. 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 package com.sun.org.apache.xalan.internal.xsltc.compiler.util;
22
23 import com.sun.org.apache.bcel.internal.generic.BranchHandle;
24 import com.sun.org.apache.bcel.internal.generic.BranchInstruction;
25 import com.sun.org.apache.bcel.internal.generic.CHECKCAST;
26 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
27 import com.sun.org.apache.bcel.internal.generic.GOTO;
28 import com.sun.org.apache.bcel.internal.generic.IFEQ;
29 import com.sun.org.apache.bcel.internal.generic.IFGE;
30 import com.sun.org.apache.bcel.internal.generic.IFGT;
31 import com.sun.org.apache.bcel.internal.generic.IFLE;
32 import com.sun.org.apache.bcel.internal.generic.IFLT;
33 import com.sun.org.apache.bcel.internal.generic.IF_ICMPGE;
34 import com.sun.org.apache.bcel.internal.generic.IF_ICMPGT;
35 import com.sun.org.apache.bcel.internal.generic.IF_ICMPLE;
36 import com.sun.org.apache.bcel.internal.generic.IF_ICMPLT;
37 import com.sun.org.apache.bcel.internal.generic.ILOAD;
38 import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
39 import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
40 import com.sun.org.apache.bcel.internal.generic.ISTORE;
41 import com.sun.org.apache.bcel.internal.generic.Instruction;
42 import com.sun.org.apache.bcel.internal.generic.InstructionList;
43 import com.sun.org.apache.bcel.internal.generic.NEW;
44 import com.sun.org.apache.bcel.internal.generic.PUSH;
45 import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants;
46
47 /**
48 * @author Jacek Ambroziak
49 * @author Santiago Pericas-Geertsen
50 * @LastModified: Oct 2017
51 */
52 public final class BooleanType extends Type {
53 protected BooleanType() {}
54
55 public String toString() {
56 return "boolean";
57 }
58
59 public boolean identicalTo(Type other) {
60 return this == other;
61 }
62
63 public String toSignature() {
64 return "Z";
65 }
66
67 public boolean isSimple() {
68 return true;
69 }
70
71 public com.sun.org.apache.bcel.internal.generic.Type toJCType() {
72 return com.sun.org.apache.bcel.internal.generic.Type.BOOLEAN;
73 }
74
75 /**
76 * Translates a real into an object of internal type <code>type</code>. The
77 * translation to int is undefined since booleans are always converted to
78 * reals in arithmetic expressions.
79 *
80 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
81 */
82 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
83 Type type) {
84 if (type == Type.String) {
85 translateTo(classGen, methodGen, (StringType) type);
86 }
87 else if (type == Type.Real) {
88 translateTo(classGen, methodGen, (RealType) type);
89 }
90 else if (type == Type.Reference) {
91 translateTo(classGen, methodGen, (ReferenceType) type);
92 }
93 else {
94 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
95 toString(), type.toString());
96 classGen.getParser().reportError(Constants.FATAL, err);
97 }
98 }
99
100 /**
101 * Expects a boolean on the stack and pushes a string. If the value on the
102 * stack is zero, then the string 'false' is pushed. Otherwise, the string
103 * 'true' is pushed.
104 *
105 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
106 */
107 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
108 StringType type) {
109 final ConstantPoolGen cpg = classGen.getConstantPool();
110 final InstructionList il = methodGen.getInstructionList();
111 final BranchHandle falsec = il.append(new IFEQ(null));
112 il.append(new PUSH(cpg, "true"));
113 final BranchHandle truec = il.append(new GOTO(null));
114 falsec.setTarget(il.append(new PUSH(cpg, "false")));
115 truec.setTarget(il.append(NOP));
116 }
117
118 /**
119 * Expects a boolean on the stack and pushes a real. The value "true" is
120 * converted to 1.0 and the value "false" to 0.0.
121 *
122 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
123 */
124 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
125 RealType type) {
126 methodGen.getInstructionList().append(I2D);
127 }
128
129 /**
130 * Expects a boolean on the stack and pushes a boxed boolean.
131 * Boxed booleans are represented by an instance of
132 * <code>java.lang.Boolean</code>.
133 *
134 * @see com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type#translateTo
135 */
136 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
137 ReferenceType type) {
138 final ConstantPoolGen cpg = classGen.getConstantPool();
139 final InstructionList il = methodGen.getInstructionList();
140 il.append(new NEW(cpg.addClass(BOOLEAN_CLASS)));
141 il.append(DUP_X1);
142 il.append(SWAP);
143 il.append(new INVOKESPECIAL(cpg.addMethodref(BOOLEAN_CLASS,
144 "<init>",
145 "(Z)V")));
146 }
147
148 /**
149 * Translates an internal boolean into an external (Java) boolean.
150 */
151 public void translateTo(ClassGenerator classGen, MethodGenerator methodGen,
152 Class<?> clazz) {
153 if (clazz == java.lang.Boolean.TYPE) {
154 methodGen.getInstructionList().append(NOP);
155 }
156 // Is Boolean <: clazz? I.e. clazz in { Boolean, Object }
157 else if (clazz.isAssignableFrom(java.lang.Boolean.class)) {
158 translateTo(classGen, methodGen, Type.Reference);
159 }
160 else {
161 ErrorMsg err = new ErrorMsg(ErrorMsg.DATA_CONVERSION_ERR,
162 toString(), clazz.getName());
163 classGen.getParser().reportError(Constants.FATAL, err);
164 }
165 }
166
167 /**
168 * Translates an external (Java) boolean into internal boolean.
169 */
170 public void translateFrom(ClassGenerator classGen, MethodGenerator methodGen,
171 Class<?> clazz) {
172 translateTo(classGen, methodGen, clazz);
173 }
174
175 /**
176 * Translates an object of this type to its boxed representation.
177 */
178 public void translateBox(ClassGenerator classGen,
179 MethodGenerator methodGen) {
180 translateTo(classGen, methodGen, Type.Reference);
181 }
182
183 /**
184 * Translates an object of this type to its unboxed representation.
185 */
186 public void translateUnBox(ClassGenerator classGen,
187 MethodGenerator methodGen) {
188 final ConstantPoolGen cpg = classGen.getConstantPool();
189 final InstructionList il = methodGen.getInstructionList();
190 il.append(new CHECKCAST(cpg.addClass(BOOLEAN_CLASS)));
191 il.append(new INVOKEVIRTUAL(cpg.addMethodref(BOOLEAN_CLASS,
192 BOOLEAN_VALUE,
193 BOOLEAN_VALUE_SIG)));
194 }
195
196 public Instruction LOAD(int slot) {
197 return new ILOAD(slot);
198 }
199
200 public Instruction STORE(int slot) {
201 return new ISTORE(slot);
202 }
203
204 public BranchInstruction GT(boolean tozero) {
205 return tozero ? (BranchInstruction) new IFGT(null) :
206 (BranchInstruction) new IF_ICMPGT(null);
207 }
208
209 public BranchInstruction GE(boolean tozero) {
210 return tozero ? (BranchInstruction) new IFGE(null) :
211 (BranchInstruction) new IF_ICMPGE(null);
212 }
213
214 public BranchInstruction LT(boolean tozero) {
215 return tozero ? (BranchInstruction) new IFLT(null) :
216 (BranchInstruction) new IF_ICMPLT(null);
217 }
218
219 public BranchInstruction LE(boolean tozero) {
220 return tozero ? (BranchInstruction) new IFLE(null) :
221 (BranchInstruction) new IF_ICMPLE(null);
222 }
223 }
--- EOF ---