Added patch from #1437426: error in assign template
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / BinaryExpression.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
14 import net.sourceforge.phpdt.internal.compiler.flow.FlowContext;
15 import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
16 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
17 import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
18 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
19 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
20
21 public class BinaryExpression extends OperatorExpression {
22
23         public Expression left, right;
24         public Constant optimizedBooleanConstant;
25
26         public BinaryExpression(Expression left, Expression right, int operator) {
27
28                 this.left = left;
29                 this.right = right;
30                 this.bits |= operator << OperatorSHIFT; // encode operator
31                 this.sourceStart = left.sourceStart;
32                 this.sourceEnd = right.sourceEnd;
33         }
34
35         public FlowInfo analyseCode(
36                 BlockScope currentScope,
37                 FlowContext flowContext,
38                 FlowInfo flowInfo) {
39
40                 return right
41                         .analyseCode(
42                                 currentScope,
43                                 flowContext,
44                                 left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits())
45                         .unconditionalInits();
46         }
47
48         public void computeConstant(BlockScope scope, int leftId, int rightId) {
49
50                 //compute the constant when valid
51                 if ((this.left.constant != Constant.NotAConstant)
52                         && (this.right.constant != Constant.NotAConstant)) {
53                         try {
54                                 this.constant =
55                                         Constant.computeConstantOperation(
56                                                 this.left.constant,
57                                                 leftId,
58                                                 (this.bits & OperatorMASK) >> OperatorSHIFT,
59                                                 this.right.constant,
60                                                 rightId);
61                         } catch (ArithmeticException e) {
62                                 this.constant = Constant.NotAConstant;
63                                 // 1.2 no longer throws an exception at compile-time
64                                 //scope.problemReporter().compileTimeConstantThrowsArithmeticException(this);
65                         }
66                 } else {
67                         this.constant = Constant.NotAConstant;
68                         //add some work for the boolean operators & |  
69 //                      this.optimizedBooleanConstant(
70 //                              leftId,
71 //                              (this.bits & OperatorMASK) >> OperatorSHIFT,
72 //                              rightId);
73                 }
74         }
75
76         public Constant optimizedBooleanConstant() {
77
78                 return this.optimizedBooleanConstant == null ? this.constant : this.optimizedBooleanConstant;
79         }
80
81         /**
82          * Code generation for a binary operation
83          */
84 //      public void generateCode(
85 //              BlockScope currentScope,
86 //              CodeStream codeStream,
87 //              boolean valueRequired) {
88 //
89 //              int pc = codeStream.position;
90 //              Label falseLabel, endLabel;
91 //              if (constant != Constant.NotAConstant) {
92 //                      if (valueRequired)
93 //                              codeStream.generateConstant(constant, implicitConversion);
94 //                      codeStream.recordPositionsFrom(pc, this.sourceStart);
95 //                      return;
96 //              }
97 //              bits |= OnlyValueRequiredMASK;
98 //              switch ((bits & OperatorMASK) >> OperatorSHIFT) {
99 //                      case PLUS :
100 //                              switch (bits & ReturnTypeIDMASK) {
101 //                                      case T_String :
102 //                                              codeStream.generateStringAppend(currentScope, left, right);
103 //                                              if (!valueRequired)
104 //                                                      codeStream.pop();
105 //                                              break;
106 //                                      case T_int :
107 //                                              left.generateCode(currentScope, codeStream, valueRequired);
108 //                                              right.generateCode(currentScope, codeStream, valueRequired);
109 //                                              if (valueRequired)
110 //                                                      codeStream.iadd();
111 //                                              break;
112 //                                      case T_long :
113 //                                              left.generateCode(currentScope, codeStream, valueRequired);
114 //                                              right.generateCode(currentScope, codeStream, valueRequired);
115 //                                              if (valueRequired)
116 //                                                      codeStream.ladd();
117 //                                              break;
118 //                                      case T_double :
119 //                                              left.generateCode(currentScope, codeStream, valueRequired);
120 //                                              right.generateCode(currentScope, codeStream, valueRequired);
121 //                                              if (valueRequired)
122 //                                                      codeStream.dadd();
123 //                                              break;
124 //                                      case T_float :
125 //                                              left.generateCode(currentScope, codeStream, valueRequired);
126 //                                              right.generateCode(currentScope, codeStream, valueRequired);
127 //                                              if (valueRequired)
128 //                                                      codeStream.fadd();
129 //                                              break;
130 //                              }
131 //                              break;
132 //                      case MINUS :
133 //                              switch (bits & ReturnTypeIDMASK) {
134 //                                      case T_int :
135 //                                              left.generateCode(currentScope, codeStream, valueRequired);
136 //                                              right.generateCode(currentScope, codeStream, valueRequired);
137 //                                              if (valueRequired)
138 //                                                      codeStream.isub();
139 //                                              break;
140 //                                      case T_long :
141 //                                              left.generateCode(currentScope, codeStream, valueRequired);
142 //                                              right.generateCode(currentScope, codeStream, valueRequired);
143 //                                              if (valueRequired)
144 //                                                      codeStream.lsub();
145 //                                              break;
146 //                                      case T_double :
147 //                                              left.generateCode(currentScope, codeStream, valueRequired);
148 //                                              right.generateCode(currentScope, codeStream, valueRequired);
149 //                                              if (valueRequired)
150 //                                                      codeStream.dsub();
151 //                                              break;
152 //                                      case T_float :
153 //                                              left.generateCode(currentScope, codeStream, valueRequired);
154 //                                              right.generateCode(currentScope, codeStream, valueRequired);
155 //                                              if (valueRequired)
156 //                                                      codeStream.fsub();
157 //                                              break;
158 //                              }
159 //                              break;
160 //                      case MULTIPLY :
161 //                              switch (bits & ReturnTypeIDMASK) {
162 //                                      case T_int :
163 //                                              left.generateCode(currentScope, codeStream, valueRequired);
164 //                                              right.generateCode(currentScope, codeStream, valueRequired);
165 //                                              if (valueRequired)
166 //                                                      codeStream.imul();
167 //                                              break;
168 //                                      case T_long :
169 //                                              left.generateCode(currentScope, codeStream, valueRequired);
170 //                                              right.generateCode(currentScope, codeStream, valueRequired);
171 //                                              if (valueRequired)
172 //                                                      codeStream.lmul();
173 //                                              break;
174 //                                      case T_double :
175 //                                              left.generateCode(currentScope, codeStream, valueRequired);
176 //                                              right.generateCode(currentScope, codeStream, valueRequired);
177 //                                              if (valueRequired)
178 //                                                      codeStream.dmul();
179 //                                              break;
180 //                                      case T_float :
181 //                                              left.generateCode(currentScope, codeStream, valueRequired);
182 //                                              right.generateCode(currentScope, codeStream, valueRequired);
183 //                                              if (valueRequired)
184 //                                                      codeStream.fmul();
185 //                                              break;
186 //                              }
187 //                              break;
188 //                      case DIVIDE :
189 //                              switch (bits & ReturnTypeIDMASK) {
190 //                                      case T_int :
191 //                                              left.generateCode(currentScope, codeStream, true);
192 //                                              right.generateCode(currentScope, codeStream, true);
193 //                                              codeStream.idiv();
194 //                                              if (!valueRequired)
195 //                                                      codeStream.pop();
196 //                                              break;
197 //                                      case T_long :
198 //                                              left.generateCode(currentScope, codeStream, true);
199 //                                              right.generateCode(currentScope, codeStream, true);
200 //                                              codeStream.ldiv();
201 //                                              if (!valueRequired)
202 //                                                      codeStream.pop2();
203 //                                              break;
204 //                                      case T_double :
205 //                                              left.generateCode(currentScope, codeStream, valueRequired);
206 //                                              right.generateCode(currentScope, codeStream, valueRequired);
207 //                                              if (valueRequired)
208 //                                                      codeStream.ddiv();
209 //                                              break;
210 //                                      case T_float :
211 //                                              left.generateCode(currentScope, codeStream, valueRequired);
212 //                                              right.generateCode(currentScope, codeStream, valueRequired);
213 //                                              if (valueRequired)
214 //                                                      codeStream.fdiv();
215 //                                              break;
216 //                              }
217 //                              break;
218 //                      case REMAINDER :
219 //                              switch (bits & ReturnTypeIDMASK) {
220 //                                      case T_int :
221 //                                              left.generateCode(currentScope, codeStream, true);
222 //                                              right.generateCode(currentScope, codeStream, true);
223 //                                              codeStream.irem();
224 //                                              if (!valueRequired)
225 //                                                      codeStream.pop();
226 //                                              break;
227 //                                      case T_long :
228 //                                              left.generateCode(currentScope, codeStream, true);
229 //                                              right.generateCode(currentScope, codeStream, true);
230 //                                              codeStream.lrem();
231 //                                              if (!valueRequired)
232 //                                                      codeStream.pop2();
233 //                                              break;
234 //                                      case T_double :
235 //                                              left.generateCode(currentScope, codeStream, valueRequired);
236 //                                              right.generateCode(currentScope, codeStream, valueRequired);
237 //                                              if (valueRequired)
238 //                                                      codeStream.drem();
239 //                                              break;
240 //                                      case T_float :
241 //                                              left.generateCode(currentScope, codeStream, valueRequired);
242 //                                              right.generateCode(currentScope, codeStream, valueRequired);
243 //                                              if (valueRequired)
244 //                                                      codeStream.frem();
245 //                                              break;
246 //                              }
247 //                              break;
248 //                      case AND :
249 //                              switch (bits & ReturnTypeIDMASK) {
250 //                                      case T_int :
251 //                                              // 0 & x
252 //                                              if ((left.constant != Constant.NotAConstant)
253 //                                                      && (left.constant.typeID() == T_int)
254 //                                                      && (left.constant.intValue() == 0)) {
255 //                                                      right.generateCode(currentScope, codeStream, false);
256 //                                                      if (valueRequired)
257 //                                                              codeStream.iconst_0();
258 //                                              } else {
259 //                                                      // x & 0
260 //                                                      if ((right.constant != Constant.NotAConstant)
261 //                                                              && (right.constant.typeID() == T_int)
262 //                                                              && (right.constant.intValue() == 0)) {
263 //                                                              left.generateCode(currentScope, codeStream, false);
264 //                                                              if (valueRequired)
265 //                                                                      codeStream.iconst_0();
266 //                                                      } else {
267 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
268 //                                                              right.generateCode(currentScope, codeStream, valueRequired);
269 //                                                              if (valueRequired)
270 //                                                                      codeStream.iand();
271 //                                                      }
272 //                                              }
273 //                                              break;
274 //                                      case T_long :
275 //                                              // 0 & x
276 //                                              if ((left.constant != Constant.NotAConstant)
277 //                                                      && (left.constant.typeID() == T_long)
278 //                                                      && (left.constant.longValue() == 0L)) {
279 //                                                      right.generateCode(currentScope, codeStream, false);
280 //                                                      if (valueRequired)
281 //                                                              codeStream.lconst_0();
282 //                                              } else {
283 //                                                      // x & 0
284 //                                                      if ((right.constant != Constant.NotAConstant)
285 //                                                              && (right.constant.typeID() == T_long)
286 //                                                              && (right.constant.longValue() == 0L)) {
287 //                                                              left.generateCode(currentScope, codeStream, false);
288 //                                                              if (valueRequired)
289 //                                                                      codeStream.lconst_0();
290 //                                                      } else {
291 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
292 //                                                              right.generateCode(currentScope, codeStream, valueRequired);
293 //                                                              if (valueRequired)
294 //                                                                      codeStream.land();
295 //                                                      }
296 //                                              }
297 //                                              break;
298 //                                      case T_boolean : // logical and
299 //                                              generateOptimizedLogicalAnd(
300 //                                                      currentScope,
301 //                                                      codeStream,
302 //                                                      null,
303 //                                                      (falseLabel = new Label(codeStream)),
304 //                                                      valueRequired);
305 //                                              /* improving code gen for such a case: boolean b = i < 0 && false;
306 //                                               * since the label has never been used, we have the inlined value on the stack. */
307 //                                              if (falseLabel.hasForwardReferences()) {
308 //                                                      if (valueRequired) {
309 //                                                              codeStream.iconst_1();
310 //                                                              if ((bits & ValueForReturnMASK) != 0) {
311 //                                                                      codeStream.ireturn();
312 //                                                                      falseLabel.place();
313 //                                                                      codeStream.iconst_0();
314 //                                                              } else {
315 //                                                                      codeStream.goto_(endLabel = new Label(codeStream));
316 //                                                                      codeStream.decrStackSize(1);
317 //                                                                      falseLabel.place();
318 //                                                                      codeStream.iconst_0();
319 //                                                                      endLabel.place();
320 //                                                              }
321 //                                                      } else {
322 //                                                              falseLabel.place();
323 //                                                      }
324 //                                              }
325 //                              }
326 //                              break;
327 //                      case OR :
328 //                              switch (bits & ReturnTypeIDMASK) {
329 //                                      case T_int :
330 //                                              // 0 | x
331 //                                              if ((left.constant != Constant.NotAConstant)
332 //                                                      && (left.constant.typeID() == T_int)
333 //                                                      && (left.constant.intValue() == 0)) {
334 //                                                      right.generateCode(currentScope, codeStream, valueRequired);
335 //                                              } else {
336 //                                                      // x | 0
337 //                                                      if ((right.constant != Constant.NotAConstant)
338 //                                                              && (right.constant.typeID() == T_int)
339 //                                                              && (right.constant.intValue() == 0)) {
340 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
341 //                                                      } else {
342 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
343 //                                                              right.generateCode(currentScope, codeStream, valueRequired);
344 //                                                              if (valueRequired)
345 //                                                                      codeStream.ior();
346 //                                                      }
347 //                                              }
348 //                                              break;
349 //                                      case T_long :
350 //                                              // 0 | x
351 //                                              if ((left.constant != Constant.NotAConstant)
352 //                                                      && (left.constant.typeID() == T_long)
353 //                                                      && (left.constant.longValue() == 0L)) {
354 //                                                      right.generateCode(currentScope, codeStream, valueRequired);
355 //                                              } else {
356 //                                                      // x | 0
357 //                                                      if ((right.constant != Constant.NotAConstant)
358 //                                                              && (right.constant.typeID() == T_long)
359 //                                                              && (right.constant.longValue() == 0L)) {
360 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
361 //                                                      } else {
362 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
363 //                                                              right.generateCode(currentScope, codeStream, valueRequired);
364 //                                                              if (valueRequired)
365 //                                                                      codeStream.lor();
366 //                                                      }
367 //                                              }
368 //                                              break;
369 //                                      case T_boolean : // logical or
370 //                                              generateOptimizedLogicalOr(
371 //                                                      currentScope,
372 //                                                      codeStream,
373 //                                                      null,
374 //                                                      (falseLabel = new Label(codeStream)),
375 //                                                      valueRequired);
376 //                                              /* improving code gen for such a case: boolean b = i < 0 || true;
377 //                                               * since the label has never been used, we have the inlined value on the stack. */
378 //                                              if (falseLabel.hasForwardReferences()) {
379 //                                                      if (valueRequired) {
380 //                                                              codeStream.iconst_1();
381 //                                                              if ((bits & ValueForReturnMASK) != 0) {
382 //                                                                      codeStream.ireturn();
383 //                                                                      falseLabel.place();
384 //                                                                      codeStream.iconst_0();
385 //                                                              } else {
386 //                                                                      codeStream.goto_(endLabel = new Label(codeStream));
387 //                                                                      codeStream.decrStackSize(1);
388 //                                                                      falseLabel.place();
389 //                                                                      codeStream.iconst_0();
390 //                                                                      endLabel.place();
391 //                                                              }
392 //                                                      } else {
393 //                                                              falseLabel.place();
394 //                                                      }
395 //                                              }
396 //                              }
397 //                              break;
398 //                      case XOR :
399 //                              switch (bits & ReturnTypeIDMASK) {
400 //                                      case T_int :
401 //                                              // 0 ^ x
402 //                                              if ((left.constant != Constant.NotAConstant)
403 //                                                      && (left.constant.typeID() == T_int)
404 //                                                      && (left.constant.intValue() == 0)) {
405 //                                                      right.generateCode(currentScope, codeStream, valueRequired);
406 //                                              } else {
407 //                                                      // x ^ 0
408 //                                                      if ((right.constant != Constant.NotAConstant)
409 //                                                              && (right.constant.typeID() == T_int)
410 //                                                              && (right.constant.intValue() == 0)) {
411 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
412 //                                                      } else {
413 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
414 //                                                              right.generateCode(currentScope, codeStream, valueRequired);
415 //                                                              if (valueRequired)
416 //                                                                      codeStream.ixor();
417 //                                                      }
418 //                                              }
419 //                                              break;
420 //                                      case T_long :
421 //                                              // 0 ^ x
422 //                                              if ((left.constant != Constant.NotAConstant)
423 //                                                      && (left.constant.typeID() == T_long)
424 //                                                      && (left.constant.longValue() == 0L)) {
425 //                                                      right.generateCode(currentScope, codeStream, valueRequired);
426 //                                              } else {
427 //                                                      // x ^ 0
428 //                                                      if ((right.constant != Constant.NotAConstant)
429 //                                                              && (right.constant.typeID() == T_long)
430 //                                                              && (right.constant.longValue() == 0L)) {
431 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
432 //                                                      } else {
433 //                                                              left.generateCode(currentScope, codeStream, valueRequired);
434 //                                                              right.generateCode(currentScope, codeStream, valueRequired);
435 //                                                              if (valueRequired)
436 //                                                                      codeStream.lxor();
437 //                                                      }
438 //                                              }
439 //                                              break;
440 //                                      case T_boolean :
441 //                                              generateOptimizedLogicalXor(
442 //                                                      currentScope,
443 //                                                      codeStream,
444 //                                                      null,
445 //                                                      (falseLabel = new Label(codeStream)),
446 //                                                      valueRequired);
447 //                                              /* improving code gen for such a case: boolean b = i < 0 ^ bool;
448 //                                               * since the label has never been used, we have the inlined value on the stack. */
449 //                                              if (falseLabel.hasForwardReferences()) {
450 //                                                      if (valueRequired) {
451 //                                                              codeStream.iconst_1();
452 //                                                              if ((bits & ValueForReturnMASK) != 0) {
453 //                                                                      codeStream.ireturn();
454 //                                                                      falseLabel.place();
455 //                                                                      codeStream.iconst_0();
456 //                                                              } else {
457 //                                                                      codeStream.goto_(endLabel = new Label(codeStream));
458 //                                                                      codeStream.decrStackSize(1);
459 //                                                                      falseLabel.place();
460 //                                                                      codeStream.iconst_0();
461 //                                                                      endLabel.place();
462 //                                                              }
463 //                                                      } else {
464 //                                                              falseLabel.place();
465 //                                                      }
466 //                                              }
467 //                              }
468 //                              break;
469 //                      case LEFT_SHIFT :
470 //                              switch (bits & ReturnTypeIDMASK) {
471 //                                      case T_int :
472 //                                              left.generateCode(currentScope, codeStream, valueRequired);
473 //                                              right.generateCode(currentScope, codeStream, valueRequired);
474 //                                              if (valueRequired)
475 //                                                      codeStream.ishl();
476 //                                              break;
477 //                                      case T_long :
478 //                                              left.generateCode(currentScope, codeStream, valueRequired);
479 //                                              right.generateCode(currentScope, codeStream, valueRequired);
480 //                                              if (valueRequired)
481 //                                                      codeStream.lshl();
482 //                              }
483 //                              break;
484 //                      case RIGHT_SHIFT :
485 //                              switch (bits & ReturnTypeIDMASK) {
486 //                                      case T_int :
487 //                                              left.generateCode(currentScope, codeStream, valueRequired);
488 //                                              right.generateCode(currentScope, codeStream, valueRequired);
489 //                                              if (valueRequired)
490 //                                                      codeStream.ishr();
491 //                                              break;
492 //                                      case T_long :
493 //                                              left.generateCode(currentScope, codeStream, valueRequired);
494 //                                              right.generateCode(currentScope, codeStream, valueRequired);
495 //                                              if (valueRequired)
496 //                                                      codeStream.lshr();
497 //                              }
498 //                              break;
499 //                      case UNSIGNED_RIGHT_SHIFT :
500 //                              switch (bits & ReturnTypeIDMASK) {
501 //                                      case T_int :
502 //                                              left.generateCode(currentScope, codeStream, valueRequired);
503 //                                              right.generateCode(currentScope, codeStream, valueRequired);
504 //                                              if (valueRequired)
505 //                                                      codeStream.iushr();
506 //                                              break;
507 //                                      case T_long :
508 //                                              left.generateCode(currentScope, codeStream, valueRequired);
509 //                                              right.generateCode(currentScope, codeStream, valueRequired);
510 //                                              if (valueRequired)
511 //                                                      codeStream.lushr();
512 //                              }
513 //                              break;
514 //                      case GREATER :
515 //                              generateOptimizedGreaterThan(
516 //                                      currentScope,
517 //                                      codeStream,
518 //                                      null,
519 //                                      (falseLabel = new Label(codeStream)),
520 //                                      valueRequired);
521 //                              if (valueRequired) {
522 //                                      codeStream.iconst_1();
523 //                                      if ((bits & ValueForReturnMASK) != 0) {
524 //                                              codeStream.ireturn();
525 //                                              falseLabel.place();
526 //                                              codeStream.iconst_0();
527 //                                      } else {
528 //                                              codeStream.goto_(endLabel = new Label(codeStream));
529 //                                              codeStream.decrStackSize(1);
530 //                                              falseLabel.place();
531 //                                              codeStream.iconst_0();
532 //                                              endLabel.place();
533 //                                      }
534 //                              }
535 //                              break;
536 //                      case GREATER_EQUAL :
537 //                              generateOptimizedGreaterThanOrEqual(
538 //                                      currentScope,
539 //                                      codeStream,
540 //                                      null,
541 //                                      (falseLabel = new Label(codeStream)),
542 //                                      valueRequired);
543 //                              if (valueRequired) {
544 //                                      codeStream.iconst_1();
545 //                                      if ((bits & ValueForReturnMASK) != 0) {
546 //                                              codeStream.ireturn();
547 //                                              falseLabel.place();
548 //                                              codeStream.iconst_0();
549 //                                      } else {
550 //                                              codeStream.goto_(endLabel = new Label(codeStream));
551 //                                              codeStream.decrStackSize(1);
552 //                                              falseLabel.place();
553 //                                              codeStream.iconst_0();
554 //                                              endLabel.place();
555 //                                      }
556 //                              }
557 //                              break;
558 //                      case LESS :
559 //                              generateOptimizedLessThan(
560 //                                      currentScope,
561 //                                      codeStream,
562 //                                      null,
563 //                                      (falseLabel = new Label(codeStream)),
564 //                                      valueRequired);
565 //                              if (valueRequired) {
566 //                                      codeStream.iconst_1();
567 //                                      if ((bits & ValueForReturnMASK) != 0) {
568 //                                              codeStream.ireturn();
569 //                                              falseLabel.place();
570 //                                              codeStream.iconst_0();
571 //                                      } else {
572 //                                              codeStream.goto_(endLabel = new Label(codeStream));
573 //                                              codeStream.decrStackSize(1);
574 //                                              falseLabel.place();
575 //                                              codeStream.iconst_0();
576 //                                              endLabel.place();
577 //                                      }
578 //                              }
579 //                              break;
580 //                      case LESS_EQUAL :
581 //                              generateOptimizedLessThanOrEqual(
582 //                                      currentScope,
583 //                                      codeStream,
584 //                                      null,
585 //                                      (falseLabel = new Label(codeStream)),
586 //                                      valueRequired);
587 //                              if (valueRequired) {
588 //                                      codeStream.iconst_1();
589 //                                      if ((bits & ValueForReturnMASK) != 0) {
590 //                                              codeStream.ireturn();
591 //                                              falseLabel.place();
592 //                                              codeStream.iconst_0();
593 //                                      } else {
594 //                                              codeStream.goto_(endLabel = new Label(codeStream));
595 //                                              codeStream.decrStackSize(1);
596 //                                              falseLabel.place();
597 //                                              codeStream.iconst_0();
598 //                                              endLabel.place();
599 //                                      }
600 //                              }
601 //              }
602 //              if (valueRequired) {
603 //                      codeStream.generateImplicitConversion(implicitConversion);
604 //              }
605 //              codeStream.recordPositionsFrom(pc, this.sourceStart);
606 //      }
607
608         /**
609          * Boolean operator code generation
610          *      Optimized operations are: <, <=, >, >=, &, |, ^
611          */
612 //      public void generateOptimizedBoolean(
613 //              BlockScope currentScope,
614 //              CodeStream codeStream,
615 //              Label trueLabel,
616 //              Label falseLabel,
617 //              boolean valueRequired) {
618 //
619 //              if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {
620 //                      super.generateOptimizedBoolean(
621 //                              currentScope,
622 //                              codeStream,
623 //                              trueLabel,
624 //                              falseLabel,
625 //                              valueRequired);
626 //                      return;
627 //              }
628 //              switch ((bits & OperatorMASK) >> OperatorSHIFT) {
629 //                      case LESS :
630 //                              generateOptimizedLessThan(
631 //                                      currentScope,
632 //                                      codeStream,
633 //                                      trueLabel,
634 //                                      falseLabel,
635 //                                      valueRequired);
636 //                              return;
637 //                      case LESS_EQUAL :
638 //                              generateOptimizedLessThanOrEqual(
639 //                                      currentScope,
640 //                                      codeStream,
641 //                                      trueLabel,
642 //                                      falseLabel,
643 //                                      valueRequired);
644 //                              return;
645 //                      case GREATER :
646 //                              generateOptimizedGreaterThan(
647 //                                      currentScope,
648 //                                      codeStream,
649 //                                      trueLabel,
650 //                                      falseLabel,
651 //                                      valueRequired);
652 //                              return;
653 //                      case GREATER_EQUAL :
654 //                              generateOptimizedGreaterThanOrEqual(
655 //                                      currentScope,
656 //                                      codeStream,
657 //                                      trueLabel,
658 //                                      falseLabel,
659 //                                      valueRequired);
660 //                              return;
661 //                      case AND :
662 //                              generateOptimizedLogicalAnd(
663 //                                      currentScope,
664 //                                      codeStream,
665 //                                      trueLabel,
666 //                                      falseLabel,
667 //                                      valueRequired);
668 //                              return;
669 //                      case OR :
670 //                              generateOptimizedLogicalOr(
671 //                                      currentScope,
672 //                                      codeStream,
673 //                                      trueLabel,
674 //                                      falseLabel,
675 //                                      valueRequired);
676 //                              return;
677 //                      case XOR :
678 //                              generateOptimizedLogicalXor(
679 //                                      currentScope,
680 //                                      codeStream,
681 //                                      trueLabel,
682 //                                      falseLabel,
683 //                                      valueRequired);
684 //                              return;
685 //              }
686 //              super.generateOptimizedBoolean(
687 //                      currentScope,
688 //                      codeStream,
689 //                      trueLabel,
690 //                      falseLabel,
691 //                      valueRequired);
692 //      }
693 //
694 //      /**
695 //       * Boolean generation for >
696 //       */
697 //      public void generateOptimizedGreaterThan(
698 //              BlockScope currentScope,
699 //              CodeStream codeStream,
700 //              Label trueLabel,
701 //              Label falseLabel,
702 //              boolean valueRequired) {
703 //
704 //              int promotedTypeID = left.implicitConversion >> 4;
705 //              // both sides got promoted in the same way
706 //              if (promotedTypeID == T_int) {
707 //                      // 0 > x
708 //                      if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) {
709 //                              right.generateCode(currentScope, codeStream, valueRequired);
710 //                              if (valueRequired) {
711 //                                      if (falseLabel == null) {
712 //                                              if (trueLabel != null) {
713 //                                                      // implicitly falling through the FALSE case
714 //                                                      codeStream.iflt(trueLabel);
715 //                                              }
716 //                                      } else {
717 //                                              if (trueLabel == null) {
718 //                                                      // implicitly falling through the TRUE case
719 //                                                      codeStream.ifge(falseLabel);
720 //                                              } else {
721 //                                                      // no implicit fall through TRUE/FALSE --> should never occur
722 //                                              }
723 //                                      }
724 //                              }
725 //                              // reposition the endPC
726 //                              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
727 //                              return;
728 //                      }
729 //                      // x > 0
730 //                      if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) {
731 //                              left.generateCode(currentScope, codeStream, valueRequired);
732 //                              if (valueRequired) {
733 //                                      if (falseLabel == null) {
734 //                                              if (trueLabel != null) {
735 //                                                      // implicitly falling through the FALSE case
736 //                                                      codeStream.ifgt(trueLabel);
737 //                                              }
738 //                                      } else {
739 //                                              if (trueLabel == null) {
740 //                                                      // implicitly falling through the TRUE case
741 //                                                      codeStream.ifle(falseLabel);
742 //                                              } else {
743 //                                                      // no implicit fall through TRUE/FALSE --> should never occur
744 //                                              }
745 //                                      }
746 //                              }
747 //                              // reposition the endPC
748 //                              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
749 //                              return;
750 //                      }
751 //              }
752 //              // default comparison
753 //              left.generateCode(currentScope, codeStream, valueRequired);
754 //              right.generateCode(currentScope, codeStream, valueRequired);
755 //              if (valueRequired) {
756 //                      if (falseLabel == null) {
757 //                              if (trueLabel != null) {
758 //                                      // implicit falling through the FALSE case
759 //                                      switch (promotedTypeID) {
760 //                                              case T_int :
761 //                                                      codeStream.if_icmpgt(trueLabel);
762 //                                                      break;
763 //                                              case T_float :
764 //                                                      codeStream.fcmpl();
765 //                                                      codeStream.ifgt(trueLabel);
766 //                                                      break;
767 //                                              case T_long :
768 //                                                      codeStream.lcmp();
769 //                                                      codeStream.ifgt(trueLabel);
770 //                                                      break;
771 //                                              case T_double :
772 //                                                      codeStream.dcmpl();
773 //                                                      codeStream.ifgt(trueLabel);
774 //                                      }
775 //                                      // reposition the endPC
776 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
777 //                                      return;
778 //                              }
779 //                      } else {
780 //                              if (trueLabel == null) {
781 //                                      // implicit falling through the TRUE case
782 //                                      switch (promotedTypeID) {
783 //                                              case T_int :
784 //                                                      codeStream.if_icmple(falseLabel);
785 //                                                      break;
786 //                                              case T_float :
787 //                                                      codeStream.fcmpl();
788 //                                                      codeStream.ifle(falseLabel);
789 //                                                      break;
790 //                                              case T_long :
791 //                                                      codeStream.lcmp();
792 //                                                      codeStream.ifle(falseLabel);
793 //                                                      break;
794 //                                              case T_double :
795 //                                                      codeStream.dcmpl();
796 //                                                      codeStream.ifle(falseLabel);
797 //                                      }
798 //                                      // reposition the endPC
799 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
800 //                                      return;
801 //                              } else {
802 //                                      // no implicit fall through TRUE/FALSE --> should never occur
803 //                              }
804 //                      }
805 //              }
806 //      }
807
808         /**
809          * Boolean generation for >=
810          */
811 //      public void generateOptimizedGreaterThanOrEqual(
812 //              BlockScope currentScope,
813 //              CodeStream codeStream,
814 //              Label trueLabel,
815 //              Label falseLabel,
816 //              boolean valueRequired) {
817 //
818 //              int promotedTypeID = left.implicitConversion >> 4;
819 //              // both sides got promoted in the same way
820 //              if (promotedTypeID == T_int) {
821 //                      // 0 >= x
822 //                      if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) {
823 //                              right.generateCode(currentScope, codeStream, valueRequired);
824 //                              if (valueRequired) {
825 //                                      if (falseLabel == null) {
826 //                                              if (trueLabel != null) {
827 //                                                      // implicitly falling through the FALSE case
828 //                                                      codeStream.ifle(trueLabel);
829 //                                              }
830 //                                      } else {
831 //                                              if (trueLabel == null) {
832 //                                                      // implicitly falling through the TRUE case
833 //                                                      codeStream.ifgt(falseLabel);
834 //                                              } else {
835 //                                                      // no implicit fall through TRUE/FALSE --> should never occur
836 //                                              }
837 //                                      }
838 //                              }
839 //                              // reposition the endPC
840 //                              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
841 //                              return;
842 //                      }
843 //                      // x >= 0
844 //                      if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) {
845 //                              left.generateCode(currentScope, codeStream, valueRequired);
846 //                              if (valueRequired) {
847 //                                      if (falseLabel == null) {
848 //                                              if (trueLabel != null) {
849 //                                                      // implicitly falling through the FALSE case
850 //                                                      codeStream.ifge(trueLabel);
851 //                                              }
852 //                                      } else {
853 //                                              if (trueLabel == null) {
854 //                                                      // implicitly falling through the TRUE case
855 //                                                      codeStream.iflt(falseLabel);
856 //                                              } else {
857 //                                                      // no implicit fall through TRUE/FALSE --> should never occur
858 //                                              }
859 //                                      }
860 //                              }
861 //                              // reposition the endPC
862 //                              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
863 //                              return;
864 //                      }
865 //              }
866 //              // default comparison
867 //              left.generateCode(currentScope, codeStream, valueRequired);
868 //              right.generateCode(currentScope, codeStream, valueRequired);
869 //              if (valueRequired) {
870 //                      if (falseLabel == null) {
871 //                              if (trueLabel != null) {
872 //                                      // implicit falling through the FALSE case
873 //                                      switch (promotedTypeID) {
874 //                                              case T_int :
875 //                                                      codeStream.if_icmpge(trueLabel);
876 //                                                      break;
877 //                                              case T_float :
878 //                                                      codeStream.fcmpl();
879 //                                                      codeStream.ifge(trueLabel);
880 //                                                      break;
881 //                                              case T_long :
882 //                                                      codeStream.lcmp();
883 //                                                      codeStream.ifge(trueLabel);
884 //                                                      break;
885 //                                              case T_double :
886 //                                                      codeStream.dcmpl();
887 //                                                      codeStream.ifge(trueLabel);
888 //                                      }
889 //                                      // reposition the endPC
890 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
891 //                                      return;
892 //                              }
893 //                      } else {
894 //                              if (trueLabel == null) {
895 //                                      // implicit falling through the TRUE case
896 //                                      switch (promotedTypeID) {
897 //                                              case T_int :
898 //                                                      codeStream.if_icmplt(falseLabel);
899 //                                                      break;
900 //                                              case T_float :
901 //                                                      codeStream.fcmpl();
902 //                                                      codeStream.iflt(falseLabel);
903 //                                                      break;
904 //                                              case T_long :
905 //                                                      codeStream.lcmp();
906 //                                                      codeStream.iflt(falseLabel);
907 //                                                      break;
908 //                                              case T_double :
909 //                                                      codeStream.dcmpl();
910 //                                                      codeStream.iflt(falseLabel);
911 //                                      }
912 //                                      // reposition the endPC
913 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
914 //                                      return;
915 //                              } else {
916 //                                      // no implicit fall through TRUE/FALSE --> should never occur
917 //                              }
918 //                      }
919 //              }
920 //      }
921 //
922 //      /**
923 //       * Boolean generation for <
924 //       */
925 //      public void generateOptimizedLessThan(
926 //              BlockScope currentScope,
927 //              CodeStream codeStream,
928 //              Label trueLabel,
929 //              Label falseLabel,
930 //              boolean valueRequired) {
931 //
932 //              int promotedTypeID = left.implicitConversion >> 4;
933 //              // both sides got promoted in the same way
934 //              if (promotedTypeID == T_int) {
935 //                      // 0 < x
936 //                      if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) {
937 //                              right.generateCode(currentScope, codeStream, valueRequired);
938 //                              if (valueRequired) {
939 //                                      if (falseLabel == null) {
940 //                                              if (trueLabel != null) {
941 //                                                      // implicitly falling through the FALSE case
942 //                                                      codeStream.ifgt(trueLabel);
943 //                                              }
944 //                                      } else {
945 //                                              if (trueLabel == null) {
946 //                                                      // implicitly falling through the TRUE case
947 //                                                      codeStream.ifle(falseLabel);
948 //                                              } else {
949 //                                                      // no implicit fall through TRUE/FALSE --> should never occur
950 //                                              }
951 //                                      }
952 //                              }
953 //                              codeStream.updateLastRecordedEndPC(codeStream.position);
954 //                              return;
955 //                      }
956 //                      // x < 0
957 //                      if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) {
958 //                              left.generateCode(currentScope, codeStream, valueRequired);
959 //                              if (valueRequired) {
960 //                                      if (falseLabel == null) {
961 //                                              if (trueLabel != null) {
962 //                                                      // implicitly falling through the FALSE case
963 //                                                      codeStream.iflt(trueLabel);
964 //                                              }
965 //                                      } else {
966 //                                              if (trueLabel == null) {
967 //                                                      // implicitly falling through the TRUE case
968 //                                                      codeStream.ifge(falseLabel);
969 //                                              } else {
970 //                                                      // no implicit fall through TRUE/FALSE --> should never occur
971 //                                              }
972 //                                      }
973 //                              }
974 //                              codeStream.updateLastRecordedEndPC(codeStream.position);
975 //                              return;
976 //                      }
977 //              }
978 //              // default comparison
979 //              left.generateCode(currentScope, codeStream, valueRequired);
980 //              right.generateCode(currentScope, codeStream, valueRequired);
981 //              if (valueRequired) {
982 //                      if (falseLabel == null) {
983 //                              if (trueLabel != null) {
984 //                                      // implicit falling through the FALSE case
985 //                                      switch (promotedTypeID) {
986 //                                              case T_int :
987 //                                                      codeStream.if_icmplt(trueLabel);
988 //                                                      break;
989 //                                              case T_float :
990 //                                                      codeStream.fcmpg();
991 //                                                      codeStream.iflt(trueLabel);
992 //                                                      break;
993 //                                              case T_long :
994 //                                                      codeStream.lcmp();
995 //                                                      codeStream.iflt(trueLabel);
996 //                                                      break;
997 //                                              case T_double :
998 //                                                      codeStream.dcmpg();
999 //                                                      codeStream.iflt(trueLabel);
1000 //                                      }
1001 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);
1002 //                                      return;
1003 //                              }
1004 //                      } else {
1005 //                              if (trueLabel == null) {
1006 //                                      // implicit falling through the TRUE case
1007 //                                      switch (promotedTypeID) {
1008 //                                              case T_int :
1009 //                                                      codeStream.if_icmpge(falseLabel);
1010 //                                                      break;
1011 //                                              case T_float :
1012 //                                                      codeStream.fcmpg();
1013 //                                                      codeStream.ifge(falseLabel);
1014 //                                                      break;
1015 //                                              case T_long :
1016 //                                                      codeStream.lcmp();
1017 //                                                      codeStream.ifge(falseLabel);
1018 //                                                      break;
1019 //                                              case T_double :
1020 //                                                      codeStream.dcmpg();
1021 //                                                      codeStream.ifge(falseLabel);
1022 //                                      }
1023 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);
1024 //                                      return;
1025 //                              } else {
1026 //                                      // no implicit fall through TRUE/FALSE --> should never occur
1027 //                              }
1028 //                      }
1029 //              }
1030 //      }
1031 //      
1032 //      /**
1033 //       * Boolean generation for <=
1034 //       */
1035 //      public void generateOptimizedLessThanOrEqual(
1036 //              BlockScope currentScope,
1037 //              CodeStream codeStream,
1038 //              Label trueLabel,
1039 //              Label falseLabel,
1040 //              boolean valueRequired) {
1041 //
1042 //              int promotedTypeID = left.implicitConversion >> 4;
1043 //              // both sides got promoted in the same way
1044 //              if (promotedTypeID == T_int) {
1045 //                      // 0 <= x
1046 //                      if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) {
1047 //                              right.generateCode(currentScope, codeStream, valueRequired);
1048 //                              if (valueRequired) {
1049 //                                      if (falseLabel == null) {
1050 //                                              if (trueLabel != null) {
1051 //                                                      // implicitly falling through the FALSE case
1052 //                                                      codeStream.ifge(trueLabel);
1053 //                                              }
1054 //                                      } else {
1055 //                                              if (trueLabel == null) {
1056 //                                                      // implicitly falling through the TRUE case
1057 //                                                      codeStream.iflt(falseLabel);
1058 //                                              } else {
1059 //                                                      // no implicit fall through TRUE/FALSE --> should never occur
1060 //                                              }
1061 //                                      }
1062 //                              }
1063 //                              // reposition the endPC
1064 //                              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1065 //                              return;
1066 //                      }
1067 //                      // x <= 0
1068 //                      if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) {
1069 //                              left.generateCode(currentScope, codeStream, valueRequired);
1070 //                              if (valueRequired) {
1071 //                                      if (falseLabel == null) {
1072 //                                              if (trueLabel != null) {
1073 //                                                      // implicitly falling through the FALSE case
1074 //                                                      codeStream.ifle(trueLabel);
1075 //                                              }
1076 //                                      } else {
1077 //                                              if (trueLabel == null) {
1078 //                                                      // implicitly falling through the TRUE case
1079 //                                                      codeStream.ifgt(falseLabel);
1080 //                                              } else {
1081 //                                                      // no implicit fall through TRUE/FALSE --> should never occur
1082 //                                              }
1083 //                                      }
1084 //                              }
1085 //                              // reposition the endPC
1086 //                              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1087 //                              return;
1088 //                      }
1089 //              }
1090 //              // default comparison
1091 //              left.generateCode(currentScope, codeStream, valueRequired);
1092 //              right.generateCode(currentScope, codeStream, valueRequired);
1093 //              if (valueRequired) {
1094 //                      if (falseLabel == null) {
1095 //                              if (trueLabel != null) {
1096 //                                      // implicit falling through the FALSE case
1097 //                                      switch (promotedTypeID) {
1098 //                                              case T_int :
1099 //                                                      codeStream.if_icmple(trueLabel);
1100 //                                                      break;
1101 //                                              case T_float :
1102 //                                                      codeStream.fcmpg();
1103 //                                                      codeStream.ifle(trueLabel);
1104 //                                                      break;
1105 //                                              case T_long :
1106 //                                                      codeStream.lcmp();
1107 //                                                      codeStream.ifle(trueLabel);
1108 //                                                      break;
1109 //                                              case T_double :
1110 //                                                      codeStream.dcmpg();
1111 //                                                      codeStream.ifle(trueLabel);
1112 //                                      }
1113 //                                      // reposition the endPC
1114 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1115 //                                      return;
1116 //                              }
1117 //                      } else {
1118 //                              if (trueLabel == null) {
1119 //                                      // implicit falling through the TRUE case
1120 //                                      switch (promotedTypeID) {
1121 //                                              case T_int :
1122 //                                                      codeStream.if_icmpgt(falseLabel);
1123 //                                                      break;
1124 //                                              case T_float :
1125 //                                                      codeStream.fcmpg();
1126 //                                                      codeStream.ifgt(falseLabel);
1127 //                                                      break;
1128 //                                              case T_long :
1129 //                                                      codeStream.lcmp();
1130 //                                                      codeStream.ifgt(falseLabel);
1131 //                                                      break;
1132 //                                              case T_double :
1133 //                                                      codeStream.dcmpg();
1134 //                                                      codeStream.ifgt(falseLabel);
1135 //                                      }
1136 //                                      // reposition the endPC
1137 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1138 //                                      return;
1139 //                              } else {
1140 //                                      // no implicit fall through TRUE/FALSE --> should never occur
1141 //                              }
1142 //                      }
1143 //              }
1144 //      }
1145 //      
1146 //      /**
1147 //       * Boolean generation for &
1148 //       */
1149 //      public void generateOptimizedLogicalAnd(
1150 //              BlockScope currentScope,
1151 //              CodeStream codeStream,
1152 //              Label trueLabel,
1153 //              Label falseLabel,
1154 //              boolean valueRequired) {
1155 //                      
1156 //              Constant condConst;
1157 //              if ((left.implicitConversion & 0xF) == T_boolean) {
1158 //                      if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) {
1159 //                              if (condConst.booleanValue() == true) {
1160 //                                      // <something equivalent to true> & x
1161 //                                      left.generateOptimizedBoolean(
1162 //                                              currentScope,
1163 //                                              codeStream,
1164 //                                              trueLabel,
1165 //                                              falseLabel,
1166 //                                              false);
1167 //                                      if ((bits & OnlyValueRequiredMASK) != 0) {
1168 //                                              right.generateCode(currentScope, codeStream, valueRequired);
1169 //                                      } else {
1170 //                                              right.generateOptimizedBoolean(
1171 //                                                      currentScope,
1172 //                                                      codeStream,
1173 //                                                      trueLabel,
1174 //                                                      falseLabel,
1175 //                                                      valueRequired);
1176 //                                      }
1177 //                              } else {
1178 //                                      // <something equivalent to false> & x
1179 //                                      left.generateOptimizedBoolean(
1180 //                                              currentScope,
1181 //                                              codeStream,
1182 //                                              trueLabel,
1183 //                                              falseLabel,
1184 //                                              false);
1185 //                                      right.generateOptimizedBoolean(
1186 //                                              currentScope,
1187 //                                              codeStream,
1188 //                                              trueLabel,
1189 //                                              falseLabel,
1190 //                                              false);
1191 //                                      if (valueRequired) {
1192 //                                              if ((bits & OnlyValueRequiredMASK) != 0) {
1193 //                                                      codeStream.iconst_0();
1194 //                                              } else {
1195 //                                                      if (falseLabel != null) {
1196 //                                                              // implicit falling through the TRUE case
1197 //                                                              codeStream.goto_(falseLabel);
1198 //                                                      }
1199 //                                              }
1200 //                                      }
1201 //                                      // reposition the endPC
1202 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1203 //                              }
1204 //                              return;
1205 //                      }
1206 //                      if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) {
1207 //                              if (condConst.booleanValue() == true) {
1208 //                                      // x & <something equivalent to true>
1209 //                                      if ((bits & OnlyValueRequiredMASK) != 0) {
1210 //                                              left.generateCode(currentScope, codeStream, valueRequired);
1211 //                                      } else {
1212 //                                              left.generateOptimizedBoolean(
1213 //                                                      currentScope,
1214 //                                                      codeStream,
1215 //                                                      trueLabel,
1216 //                                                      falseLabel,
1217 //                                                      valueRequired);
1218 //                                      }
1219 //                                      right.generateOptimizedBoolean(
1220 //                                              currentScope,
1221 //                                              codeStream,
1222 //                                              trueLabel,
1223 //                                              falseLabel,
1224 //                                              false);
1225 //                              } else {
1226 //                                      // x & <something equivalent to false>
1227 //                                      left.generateOptimizedBoolean(
1228 //                                              currentScope,
1229 //                                              codeStream,
1230 //                                              trueLabel,
1231 //                                              falseLabel,
1232 //                                              false);
1233 //                                      right.generateOptimizedBoolean(
1234 //                                              currentScope,
1235 //                                              codeStream,
1236 //                                              trueLabel,
1237 //                                              falseLabel,
1238 //                                              false);
1239 //                                      if (valueRequired) {
1240 //                                              if ((bits & OnlyValueRequiredMASK) != 0) {
1241 //                                                      codeStream.iconst_0();
1242 //                                              } else {
1243 //                                                      if (falseLabel != null) {
1244 //                                                              // implicit falling through the TRUE case
1245 //                                                              codeStream.goto_(falseLabel);
1246 //                                                      }
1247 //                                              }
1248 //                                      }
1249 //                                      // reposition the endPC
1250 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1251 //                              }
1252 //                              return;
1253 //                      }
1254 //              }
1255 //              // default case
1256 //              left.generateCode(currentScope, codeStream, valueRequired);
1257 //              right.generateCode(currentScope, codeStream, valueRequired);
1258 //              if (valueRequired) {
1259 //                      codeStream.iand();
1260 //                      if ((bits & OnlyValueRequiredMASK) == 0) {
1261 //                              if (falseLabel == null) {
1262 //                                      if (trueLabel != null) {
1263 //                                              // implicit falling through the FALSE case
1264 //                                              codeStream.ifne(trueLabel);
1265 //                                      }
1266 //                              } else {
1267 //                                      // implicit falling through the TRUE case
1268 //                                      if (trueLabel == null) {
1269 //                                              codeStream.ifeq(falseLabel);
1270 //                                      } else {
1271 //                                              // no implicit fall through TRUE/FALSE --> should never occur
1272 //                                      }
1273 //                              }
1274 //                      }
1275 //              }
1276 //              // reposition the endPC
1277 //              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1278 //      }
1279 //      
1280 //      /**
1281 //       * Boolean generation for |
1282 //       */
1283 //      public void generateOptimizedLogicalOr(
1284 //              BlockScope currentScope,
1285 //              CodeStream codeStream,
1286 //              Label trueLabel,
1287 //              Label falseLabel,
1288 //              boolean valueRequired) {
1289 //                      
1290 //              Constant condConst;
1291 //              if ((left.implicitConversion & 0xF) == T_boolean) {
1292 //                      if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) {
1293 //                              if (condConst.booleanValue() == true) {
1294 //                                      // <something equivalent to true> | x
1295 //                                      left.generateOptimizedBoolean(
1296 //                                              currentScope,
1297 //                                              codeStream,
1298 //                                              trueLabel,
1299 //                                              falseLabel,
1300 //                                              false);
1301 //                                      right.generateOptimizedBoolean(
1302 //                                              currentScope,
1303 //                                              codeStream,
1304 //                                              trueLabel,
1305 //                                              falseLabel,
1306 //                                              false);
1307 //                                      if (valueRequired) {
1308 //                                              if ((bits & OnlyValueRequiredMASK) != 0) {
1309 //                                                      codeStream.iconst_1();
1310 //                                              } else {
1311 //                                                      if (trueLabel != null) {
1312 //                                                              codeStream.goto_(trueLabel);
1313 //                                                      }
1314 //                                              }
1315 //                                      }
1316 //                                      // reposition the endPC
1317 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1318 //                              } else {
1319 //                                      // <something equivalent to false> | x
1320 //                                      left.generateOptimizedBoolean(
1321 //                                              currentScope,
1322 //                                              codeStream,
1323 //                                              trueLabel,
1324 //                                              falseLabel,
1325 //                                              false);
1326 //                                      if ((bits & OnlyValueRequiredMASK) != 0) {
1327 //                                              right.generateCode(currentScope, codeStream, valueRequired);
1328 //                                      } else {
1329 //                                              right.generateOptimizedBoolean(
1330 //                                                      currentScope,
1331 //                                                      codeStream,
1332 //                                                      trueLabel,
1333 //                                                      falseLabel,
1334 //                                                      valueRequired);
1335 //                                      }
1336 //                              }
1337 //                              return;
1338 //                      }
1339 //                      if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) {
1340 //                              if (condConst.booleanValue() == true) {
1341 //                                      // x | <something equivalent to true>
1342 //                                      left.generateOptimizedBoolean(
1343 //                                              currentScope,
1344 //                                              codeStream,
1345 //                                              trueLabel,
1346 //                                              falseLabel,
1347 //                                              false);
1348 //                                      right.generateOptimizedBoolean(
1349 //                                              currentScope,
1350 //                                              codeStream,
1351 //                                              trueLabel,
1352 //                                              falseLabel,
1353 //                                              false);
1354 //                                      if (valueRequired) {
1355 //                                              if ((bits & OnlyValueRequiredMASK) != 0) {
1356 //                                                      codeStream.iconst_1();
1357 //                                              } else {
1358 //                                                      if (trueLabel != null) {
1359 //                                                              codeStream.goto_(trueLabel);
1360 //                                                      }
1361 //                                              }
1362 //                                      }
1363 //                                      // reposition the endPC
1364 //                                      codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1365 //                              } else {
1366 //                                      // x | <something equivalent to false>
1367 //                                      if ((bits & OnlyValueRequiredMASK) != 0) {
1368 //                                              left.generateCode(currentScope, codeStream, valueRequired);
1369 //                                      } else {
1370 //                                              left.generateOptimizedBoolean(
1371 //                                                      currentScope,
1372 //                                                      codeStream,
1373 //                                                      trueLabel,
1374 //                                                      falseLabel,
1375 //                                                      valueRequired);
1376 //                                      }
1377 //                                      right.generateOptimizedBoolean(
1378 //                                              currentScope,
1379 //                                              codeStream,
1380 //                                              trueLabel,
1381 //                                              falseLabel,
1382 //                                              false);
1383 //                              }
1384 //                              return;
1385 //                      }
1386 //              }
1387 //              // default case
1388 //              left.generateCode(currentScope, codeStream, valueRequired);
1389 //              right.generateCode(currentScope, codeStream, valueRequired);
1390 //              if (valueRequired) {
1391 //                      codeStream.ior();
1392 //                      if ((bits & OnlyValueRequiredMASK) == 0) {
1393 //                              if (falseLabel == null) {
1394 //                                      if (trueLabel != null) {
1395 //                                              // implicit falling through the FALSE case
1396 //                                              codeStream.ifne(trueLabel);
1397 //                                      }
1398 //                              } else {
1399 //                                      // implicit falling through the TRUE case
1400 //                                      if (trueLabel == null) {
1401 //                                              codeStream.ifeq(falseLabel);
1402 //                                      } else {
1403 //                                              // no implicit fall through TRUE/FALSE --> should never occur
1404 //                                      }
1405 //                              }
1406 //                      }
1407 //              }
1408 //              // reposition the endPC
1409 //              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1410 //      }
1411 //      
1412 //      /**
1413 //       * Boolean generation for ^
1414 //       */
1415 //      public void generateOptimizedLogicalXor(
1416 //              BlockScope currentScope,
1417 //              CodeStream codeStream,
1418 //              Label trueLabel,
1419 //              Label falseLabel,
1420 //              boolean valueRequired) {
1421 //                      
1422 //              Constant condConst;
1423 //              if ((left.implicitConversion & 0xF) == T_boolean) {
1424 //                      if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) {
1425 //                              if (condConst.booleanValue() == true) {
1426 //                                      // <something equivalent to true> ^ x
1427 //                                      left.generateOptimizedBoolean(
1428 //                                              currentScope,
1429 //                                              codeStream,
1430 //                                              trueLabel,
1431 //                                              falseLabel,
1432 //                                              false);
1433 //                                      right.generateOptimizedBoolean(
1434 //                                              currentScope,
1435 //                                              codeStream,
1436 //                                              falseLabel,
1437 //                                              trueLabel,
1438 //                                              valueRequired);
1439 //                              } else {
1440 //                                      // <something equivalent to false> ^ x
1441 //                                      left.generateOptimizedBoolean(
1442 //                                              currentScope,
1443 //                                              codeStream,
1444 //                                              trueLabel,
1445 //                                              falseLabel,
1446 //                                              false);
1447 //                                      if ((bits & OnlyValueRequiredMASK) != 0) {
1448 //                                              right.generateCode(currentScope, codeStream, valueRequired);
1449 //                                      } else {
1450 //                                              right.generateOptimizedBoolean(
1451 //                                                      currentScope,
1452 //                                                      codeStream,
1453 //                                                      trueLabel,
1454 //                                                      falseLabel,
1455 //                                                      valueRequired);
1456 //                                      }
1457 //                              }
1458 //                              return;
1459 //                      }
1460 //                      if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) {
1461 //                              if (condConst.booleanValue() == true) {
1462 //                                      // x ^ <something equivalent to true>
1463 //                                      left.generateOptimizedBoolean(
1464 //                                              currentScope,
1465 //                                              codeStream,
1466 //                                              falseLabel,
1467 //                                              trueLabel,
1468 //                                              valueRequired);
1469 //                                      right.generateOptimizedBoolean(
1470 //                                              currentScope,
1471 //                                              codeStream,
1472 //                                              trueLabel,
1473 //                                              falseLabel,
1474 //                                              false);
1475 //                              } else {
1476 //                                      // x ^ <something equivalent to false>
1477 //                                      if ((bits & OnlyValueRequiredMASK) != 0) {
1478 //                                              left.generateCode(currentScope, codeStream, valueRequired);
1479 //                                      } else {
1480 //                                              left.generateOptimizedBoolean(
1481 //                                                      currentScope,
1482 //                                                      codeStream,
1483 //                                                      trueLabel,
1484 //                                                      falseLabel,
1485 //                                                      valueRequired);
1486 //                                      }
1487 //                                      right.generateOptimizedBoolean(
1488 //                                              currentScope,
1489 //                                              codeStream,
1490 //                                              trueLabel,
1491 //                                              falseLabel,
1492 //                                              false);
1493 //                              }
1494 //                              return;
1495 //                      }
1496 //              }
1497 //              // default case
1498 //              left.generateCode(currentScope, codeStream, valueRequired);
1499 //              right.generateCode(currentScope, codeStream, valueRequired);
1500 //              if (valueRequired) {
1501 //                      codeStream.ixor();
1502 //                      if ((bits & OnlyValueRequiredMASK) == 0) {
1503 //                              if (falseLabel == null) {
1504 //                                      if (trueLabel != null) {
1505 //                                              // implicit falling through the FALSE case
1506 //                                              codeStream.ifne(trueLabel);
1507 //                                      }
1508 //                              } else {
1509 //                                      // implicit falling through the TRUE case
1510 //                                      if (trueLabel == null) {
1511 //                                              codeStream.ifeq(falseLabel);
1512 //                                      } else {
1513 //                                              // no implicit fall through TRUE/FALSE --> should never occur
1514 //                                      }
1515 //                              }
1516 //                      }
1517 //              }
1518 //              // reposition the endPC
1519 //              codeStream.updateLastRecordedEndPC(codeStream.position);                                        
1520 //      }
1521 //      
1522 //      public void generateOptimizedStringBuffer(
1523 //              BlockScope blockScope,
1524 //              CodeStream codeStream,
1525 //              int typeID) {
1526 //                      
1527 //              /* In the case trying to make a string concatenation, there is no need to create a new
1528 //               * string buffer, thus use a lower-level API for code generation involving only the
1529 //               * appending of arguments to the existing StringBuffer
1530 //               */
1531 //
1532 //              if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS)
1533 //                      && ((bits & ReturnTypeIDMASK) == T_String)) {
1534 //                      if (constant != NotAConstant) {
1535 //                              codeStream.generateConstant(constant, implicitConversion);
1536 //                              codeStream.invokeStringBufferAppendForType(implicitConversion & 0xF);
1537 //                      } else {
1538 //                              int pc = codeStream.position;
1539 //                              left.generateOptimizedStringBuffer(
1540 //                                      blockScope,
1541 //                                      codeStream,
1542 //                                      left.implicitConversion & 0xF);
1543 //                              codeStream.recordPositionsFrom(pc, left.sourceStart);
1544 //                              pc = codeStream.position;
1545 //                              right.generateOptimizedStringBuffer(
1546 //                                      blockScope,
1547 //                                      codeStream,
1548 //                                      right.implicitConversion & 0xF);
1549 //                              codeStream.recordPositionsFrom(pc, right.sourceStart);
1550 //                      }
1551 //              } else {
1552 //                      super.generateOptimizedStringBuffer(blockScope, codeStream, typeID);
1553 //              }
1554 //      }
1555 //      
1556 //      public void generateOptimizedStringBufferCreation(
1557 //              BlockScope blockScope,
1558 //              CodeStream codeStream,
1559 //              int typeID) {
1560 //                      
1561 //              /* In the case trying to make a string concatenation, there is no need to create a new
1562 //               * string buffer, thus use a lower-level API for code generation involving only the 
1563 //               * appending of arguments to the existing StringBuffer
1564 //               */
1565 //
1566 //              if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS)
1567 //                      && ((bits & ReturnTypeIDMASK) == T_String)) {
1568 //                      if (constant != NotAConstant) {
1569 //                              codeStream.newStringBuffer(); // new: java.lang.StringBuffer
1570 //                              codeStream.dup();
1571 //                              codeStream.ldc(constant.stringValue());
1572 //                              codeStream.invokeStringBufferStringConstructor();
1573 //                              // invokespecial: java.lang.StringBuffer.<init>(Ljava.lang.String;)V
1574 //                      } else {
1575 //                              int pc = codeStream.position;
1576 //                              left.generateOptimizedStringBufferCreation(
1577 //                                      blockScope,
1578 //                                      codeStream,
1579 //                                      left.implicitConversion & 0xF);
1580 //                              codeStream.recordPositionsFrom(pc, left.sourceStart);
1581 //                              pc = codeStream.position;
1582 //                              right.generateOptimizedStringBuffer(
1583 //                                      blockScope,
1584 //                                      codeStream,
1585 //                                      right.implicitConversion & 0xF);
1586 //                              codeStream.recordPositionsFrom(pc, right.sourceStart);
1587 //                      }
1588 //              } else {
1589 //                      super.generateOptimizedStringBufferCreation(blockScope, codeStream, typeID);
1590 //              }
1591 //      }
1592 //      
1593 //      public boolean isCompactableOperation() {
1594 //              
1595 //              return true;
1596 //      }
1597 //      
1598 //      public void optimizedBooleanConstant(int leftId, int operator, int rightId) {
1599 //
1600 //              switch (operator) {
1601 //                      case AND :
1602 //                              if ((leftId != T_boolean) || (rightId != T_boolean))
1603 //                                      return;
1604 //                      case AND_AND :
1605 //                              Constant cst;
1606 //                              if ((cst = left.optimizedBooleanConstant()) != NotAConstant) {
1607 //                                      if (cst.booleanValue() == false) { // left is equivalent to false
1608 //                                              optimizedBooleanConstant = cst; // constant(false)
1609 //                                              return;
1610 //                                      } else { //left is equivalent to true
1611 //                                              if ((cst = right.optimizedBooleanConstant()) != NotAConstant) {
1612 //                                                      optimizedBooleanConstant = cst;
1613 //                                                      // the conditional result is equivalent to the right conditional value
1614 //                                              }
1615 //                                              return;
1616 //                                      }
1617 //                              }
1618 //                              if ((cst = right.optimizedBooleanConstant()) != NotAConstant) {
1619 //                                      if (cst.booleanValue() == false) { // right is equivalent to false
1620 //                                              optimizedBooleanConstant = cst; // constant(false)
1621 //                                      }
1622 //                              }
1623 //                              return;
1624 //                      case OR :
1625 //                              if ((leftId != T_boolean) || (rightId != T_boolean))
1626 //                                      return;
1627 //                      case OR_OR :
1628 //                              if ((cst = left.optimizedBooleanConstant()) != NotAConstant) {
1629 //                                      if (cst.booleanValue() == true) { // left is equivalent to true
1630 //                                              optimizedBooleanConstant = cst; // constant(true)
1631 //                                              return;
1632 //                                      } else { //left is equivalent to false
1633 //                                              if ((cst = right.optimizedBooleanConstant()) != NotAConstant) {
1634 //                                                      optimizedBooleanConstant = cst;
1635 //                                              }
1636 //                                              return;
1637 //                                      }
1638 //                              }
1639 //                              if ((cst = right.optimizedBooleanConstant()) != NotAConstant) {
1640 //                                      if (cst.booleanValue() == true) { // right is equivalent to true
1641 //                                              optimizedBooleanConstant = cst; // constant(true)
1642 //                                      }
1643 //                              }
1644 //              }
1645 //      } 
1646         public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) {
1647
1648                 left.printExpression(indent, output).append(' ').append(operatorToString()).append(' ');
1649                 return right.printExpression(0, output);
1650         }
1651         public TypeBinding resolveType(BlockScope scope) {
1652
1653                 // use the id of the type to navigate into the table
1654                 TypeBinding leftTb = left.resolveType(scope);
1655                 TypeBinding rightTb = right.resolveType(scope);
1656                 if (leftTb == null || rightTb == null) {
1657                         constant = Constant.NotAConstant;
1658                         return null;
1659                 }
1660                 int leftId = leftTb.id;
1661                 int rightId = rightTb.id;
1662                 if (leftId > 15
1663                         || rightId > 15) { // must convert String + Object || Object + String
1664                         if (leftId == T_String) {
1665                                 rightId = T_Object;
1666                         } else if (rightId == T_String) {
1667                                 leftId = T_Object;
1668                         } else {
1669                                 constant = Constant.NotAConstant;
1670                                 scope.problemReporter().invalidOperator(this, leftTb, rightTb);
1671                                 return null;
1672                         }
1673                 }
1674                 if (((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) {
1675                         if (leftId == T_String
1676                                 && rightTb.isArrayType()
1677                                 && ((ArrayBinding) rightTb).elementsType(scope) == CharBinding)
1678                                 scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(
1679                                         right);
1680                         else if (
1681                                 rightId == T_String
1682                                         && leftTb.isArrayType()
1683                                         && ((ArrayBinding) leftTb).elementsType(scope) == CharBinding)
1684                                 scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression(
1685                                         left);
1686                 }
1687
1688                 // the code is an int
1689                 // (cast)  left   Op (cast)  rigth --> result
1690                 //  0000   0000       0000   0000      0000
1691                 //  <<16   <<12       <<8    <<4       <<0
1692
1693                 // Don't test for result = 0. If it is zero, some more work is done.
1694                 // On the one hand when it is not zero (correct code) we avoid doing the test   
1695                 int result =
1696                         ResolveTypeTables[(bits & OperatorMASK) >> OperatorSHIFT][(leftId << 4)
1697                                 + rightId];
1698                 left.implicitConversion = result >>> 12;
1699                 right.implicitConversion = (result >>> 4) & 0x000FF;
1700
1701                 bits |= result & 0xF;
1702                 switch (result & 0xF) { // record the current ReturnTypeID
1703                         // only switch on possible result type.....
1704                         case T_boolean :
1705                                 this.resolvedType = BooleanBinding;
1706                                 break;
1707                         case T_byte :
1708                                 this.resolvedType = ByteBinding;
1709                                 break;
1710                         case T_char :
1711                                 this.resolvedType = CharBinding;
1712                                 break;
1713                         case T_double :
1714                                 this.resolvedType = DoubleBinding;
1715                                 break;
1716                         case T_float :
1717                                 this.resolvedType = FloatBinding;
1718                                 break;
1719                         case T_int :
1720                                 this.resolvedType = IntBinding;
1721                                 break;
1722                         case T_long :
1723                                 this.resolvedType = LongBinding;
1724                                 break;
1725                         case T_String :
1726                                 this.resolvedType = scope.getJavaLangString();
1727                                 break;
1728                         default : //error........
1729                                 constant = Constant.NotAConstant;
1730                                 scope.problemReporter().invalidOperator(this, leftTb, rightTb);
1731                                 return null;
1732                 }
1733
1734                 // compute the constant when valid
1735                 computeConstant(scope, leftId, rightId);
1736                 return this.resolvedType;
1737         }
1738         
1739         public String toStringExpressionNoParenthesis() {
1740
1741                 return left.toStringExpression() + " " + //$NON-NLS-1$
1742                 operatorToString() + " " + //$NON-NLS-1$
1743                 right.toStringExpression();
1744         }
1745
1746         public void traverse(ASTVisitor visitor, BlockScope scope) {
1747                 
1748                 if (visitor.visit(this, scope)) {
1749                         left.traverse(visitor, scope);
1750                         right.traverse(visitor, scope);
1751                 }
1752                 visitor.endVisit(this, scope);
1753         }
1754 }