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 }