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