1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import org.apache.bcel.generic.BranchHandle; 23 import org.apache.bcel.generic.BranchInstruction; 24 import org.apache.bcel.generic.ConstantPoolGen; 25 import org.apache.bcel.generic.GOTO; 26 import org.apache.bcel.generic.IFEQ; 27 import org.apache.bcel.generic.IFNE; 28 import org.apache.bcel.generic.IF_ICMPEQ; 29 import org.apache.bcel.generic.IF_ICMPNE; 30 import org.apache.bcel.generic.INVOKESTATIC; 31 import org.apache.bcel.generic.INVOKEVIRTUAL; 32 import org.apache.bcel.generic.InstructionList; 33 import org.apache.bcel.generic.PUSH; 34 import org.apache.xalan.xsltc.compiler.util.BooleanType; 35 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 36 import org.apache.xalan.xsltc.compiler.util.IntType; 37 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 38 import org.apache.xalan.xsltc.compiler.util.NodeSetType; 39 import org.apache.xalan.xsltc.compiler.util.NodeType; 40 import org.apache.xalan.xsltc.compiler.util.NumberType; 41 import org.apache.xalan.xsltc.compiler.util.RealType; 42 import org.apache.xalan.xsltc.compiler.util.ReferenceType; 43 import org.apache.xalan.xsltc.compiler.util.ResultTreeType; 44 import org.apache.xalan.xsltc.compiler.util.StringType; 45 import org.apache.xalan.xsltc.compiler.util.Type; 46 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 47 import org.apache.xalan.xsltc.runtime.Operators; 48 49 55 final class EqualityExpr extends Expression implements Operators { 56 private final int _op; 57 private Expression _left; 58 private Expression _right; 59 60 public EqualityExpr(int op, Expression left, Expression right) { 61 _op = op; 62 (_left = left).setParent(this); 63 (_right = right).setParent(this); 64 } 65 66 public void setParser(Parser parser) { 67 super.setParser(parser); 68 _left.setParser(parser); 69 _right.setParser(parser); 70 } 71 72 public String toString() { 73 return Operators.names[_op] + '(' + _left + ", " + _right + ')'; 74 } 75 76 public Expression getLeft() { 77 return _left; 78 } 79 80 public Expression getRight() { 81 return _right; 82 } 83 84 public boolean getOp() { 85 return (_op != Operators.NE); 86 } 87 88 92 public boolean hasPositionCall() { 93 if (_left.hasPositionCall()) return true; 94 if (_right.hasPositionCall()) return true; 95 return false; 96 } 97 98 public boolean hasLastCall() { 99 if (_left.hasLastCall()) return true; 100 if (_right.hasLastCall()) return true; 101 return false; 102 } 103 104 private void swapArguments() { 105 final Expression temp = _left; 106 _left = _right; 107 _right = temp; 108 } 109 110 113 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 114 final Type tleft = _left.typeCheck(stable); 115 final Type tright = _right.typeCheck(stable); 116 117 if (tleft.isSimple() && tright.isSimple()) { 118 if (tleft != tright) { 119 if (tleft instanceof BooleanType) { 120 _right = new CastExpr(_right, Type.Boolean); 121 } 122 else if (tright instanceof BooleanType) { 123 _left = new CastExpr(_left, Type.Boolean); 124 } 125 else if (tleft instanceof NumberType || 126 tright instanceof NumberType) { 127 _left = new CastExpr(_left, Type.Real); 128 _right = new CastExpr(_right, Type.Real); 129 } 130 else { _left = new CastExpr(_left, Type.String); 132 _right = new CastExpr(_right, Type.String); 133 } 134 } 135 } 136 else if (tleft instanceof ReferenceType) { 137 _right = new CastExpr(_right, Type.Reference); 138 } 139 else if (tright instanceof ReferenceType) { 140 _left = new CastExpr(_left, Type.Reference); 141 } 142 else if (tleft instanceof NodeType && tright == Type.String) { 144 _left = new CastExpr(_left, Type.String); 145 } 146 else if (tleft == Type.String && tright instanceof NodeType) { 147 _right = new CastExpr(_right, Type.String); 148 } 149 else if (tleft instanceof NodeType && tright instanceof NodeType) { 151 _left = new CastExpr(_left, Type.String); 152 _right = new CastExpr(_right, Type.String); 153 } 154 else if (tleft instanceof NodeType && tright instanceof NodeSetType) { 155 } 157 else if (tleft instanceof NodeSetType && tright instanceof NodeType) { 158 swapArguments(); } 160 else { 161 163 if (tleft instanceof NodeType) { 165 _left = new CastExpr(_left, Type.NodeSet); 166 } 167 if (tright instanceof NodeType) { 168 _right = new CastExpr(_right, Type.NodeSet); 169 } 170 171 if (tleft.isSimple() || 173 tleft instanceof ResultTreeType && 174 tright instanceof NodeSetType) { 175 swapArguments(); 176 } 177 178 if (_right.getType() instanceof IntType) { 180 _right = new CastExpr(_right, Type.Real); 181 } 182 } 183 return _type = Type.Boolean; 184 } 185 186 public void translateDesynthesized(ClassGenerator classGen, 187 MethodGenerator methodGen) { 188 final Type tleft = _left.getType(); 189 final InstructionList il = methodGen.getInstructionList(); 190 191 if (tleft instanceof BooleanType) { 192 _left.translate(classGen, methodGen); 193 _right.translate(classGen, methodGen); 194 _falseList.add(il.append(_op == Operators.EQ ? 195 (BranchInstruction)new IF_ICMPNE(null) : 196 (BranchInstruction)new IF_ICMPEQ(null))); 197 } 198 else if (tleft instanceof NumberType) { 199 _left.translate(classGen, methodGen); 200 _right.translate(classGen, methodGen); 201 202 if (tleft instanceof RealType) { 203 il.append(DCMPG); 204 _falseList.add(il.append(_op == Operators.EQ ? 205 (BranchInstruction)new IFNE(null) : 206 (BranchInstruction)new IFEQ(null))); 207 } 208 else { 209 _falseList.add(il.append(_op == Operators.EQ ? 210 (BranchInstruction)new IF_ICMPNE(null) : 211 (BranchInstruction)new IF_ICMPEQ(null))); 212 } 213 } 214 else { 215 translate(classGen, methodGen); 216 desynthesize(classGen, methodGen); 217 } 218 } 219 220 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 221 final ConstantPoolGen cpg = classGen.getConstantPool(); 222 final InstructionList il = methodGen.getInstructionList(); 223 224 final Type tleft = _left.getType(); 225 Type tright = _right.getType(); 226 227 if (tleft instanceof BooleanType || tleft instanceof NumberType) { 228 translateDesynthesized(classGen, methodGen); 229 synthesize(classGen, methodGen); 230 return; 231 } 232 233 if (tleft instanceof StringType) { 234 final int equals = cpg.addMethodref(STRING_CLASS, 235 "equals", 236 "(" + OBJECT_SIG +")Z"); 237 _left.translate(classGen, methodGen); 238 _right.translate(classGen, methodGen); 239 il.append(new INVOKEVIRTUAL(equals)); 240 241 if (_op == Operators.NE) { 242 il.append(ICONST_1); 243 il.append(IXOR); } 245 return; 246 } 247 248 BranchHandle truec, falsec; 249 250 if (tleft instanceof ResultTreeType) { 251 if (tright instanceof BooleanType) { 252 _right.translate(classGen, methodGen); 253 if (_op == Operators.NE) { 254 il.append(ICONST_1); 255 il.append(IXOR); } 257 return; 258 } 259 260 if (tright instanceof RealType) { 261 _left.translate(classGen, methodGen); 262 tleft.translateTo(classGen, methodGen, Type.Real); 263 _right.translate(classGen, methodGen); 264 265 il.append(DCMPG); 266 falsec = il.append(_op == Operators.EQ ? 267 (BranchInstruction) new IFNE(null) : 268 (BranchInstruction) new IFEQ(null)); 269 il.append(ICONST_1); 270 truec = il.append(new GOTO(null)); 271 falsec.setTarget(il.append(ICONST_0)); 272 truec.setTarget(il.append(NOP)); 273 return; 274 } 275 276 278 _left.translate(classGen, methodGen); 279 tleft.translateTo(classGen, methodGen, Type.String); 280 _right.translate(classGen, methodGen); 281 282 if (tright instanceof ResultTreeType) { 283 tright.translateTo(classGen, methodGen, Type.String); 284 } 285 286 final int equals = cpg.addMethodref(STRING_CLASS, 287 "equals", 288 "(" +OBJECT_SIG+ ")Z"); 289 il.append(new INVOKEVIRTUAL(equals)); 290 291 if (_op == Operators.NE) { 292 il.append(ICONST_1); 293 il.append(IXOR); } 295 return; 296 } 297 298 if (tleft instanceof NodeSetType && tright instanceof BooleanType) { 299 _left.translate(classGen, methodGen); 300 _left.startIterator(classGen, methodGen); 301 Type.NodeSet.translateTo(classGen, methodGen, Type.Boolean); 302 _right.translate(classGen, methodGen); 303 304 il.append(IXOR); if (_op == EQ) { 306 il.append(ICONST_1); 307 il.append(IXOR); } 309 return; 310 } 311 312 if (tleft instanceof NodeSetType && tright instanceof StringType) { 313 _left.translate(classGen, methodGen); 314 _left.startIterator(classGen, methodGen); _right.translate(classGen, methodGen); 316 il.append(new PUSH(cpg, _op)); 317 il.append(methodGen.loadDOM()); 318 final int cmp = cpg.addMethodref(BASIS_LIBRARY_CLASS, 319 "compare", 320 "(" 321 + tleft.toSignature() 322 + tright.toSignature() 323 + "I" 324 + DOM_INTF_SIG 325 + ")Z"); 326 il.append(new INVOKESTATIC(cmp)); 327 return; 328 } 329 330 _left.translate(classGen, methodGen); 332 _left.startIterator(classGen, methodGen); 333 _right.translate(classGen, methodGen); 334 _right.startIterator(classGen, methodGen); 335 336 if (tright instanceof ResultTreeType) { 338 tright.translateTo(classGen, methodGen, Type.String); 339 tright = Type.String; 340 } 341 342 il.append(new PUSH(cpg, _op)); 344 il.append(methodGen.loadDOM()); 345 346 final int compare = cpg.addMethodref(BASIS_LIBRARY_CLASS, 347 "compare", 348 "(" 349 + tleft.toSignature() 350 + tright.toSignature() 351 + "I" 352 + DOM_INTF_SIG 353 + ")Z"); 354 il.append(new INVOKESTATIC(compare)); 355 } 356 } 357 | Popular Tags |