X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/BinaryExpression.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/BinaryExpression.java index ce506cb..4f8e580 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/BinaryExpression.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/BinaryExpression.java @@ -10,6 +10,7 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.ast; +import net.sourceforge.phpdt.core.compiler.ITerminalSymbols.TokenName; import net.sourceforge.phpdt.internal.compiler.ASTVisitor; import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; @@ -21,10 +22,10 @@ import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; public class BinaryExpression extends OperatorExpression { public Expression left, right; + public Constant optimizedBooleanConstant; public BinaryExpression(Expression left, Expression right, int operator) { - this.left = left; this.right = right; this.bits |= operator << OperatorSHIFT; // encode operator @@ -32,1622 +33,1631 @@ public class BinaryExpression extends OperatorExpression { this.sourceEnd = right.sourceEnd; } - public FlowInfo analyseCode( - BlockScope currentScope, - FlowContext flowContext, - FlowInfo flowInfo) { + public FlowInfo analyseCode(BlockScope currentScope, + FlowContext flowContext, FlowInfo flowInfo) { - return right - .analyseCode( + return right.analyseCode( currentScope, flowContext, - left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()) - .unconditionalInits(); + left.analyseCode(currentScope, flowContext, flowInfo) + .unconditionalInits()).unconditionalInits(); } public void computeConstant(BlockScope scope, int leftId, int rightId) { - //compute the constant when valid + // compute the constant when valid if ((this.left.constant != Constant.NotAConstant) - && (this.right.constant != Constant.NotAConstant)) { + && (this.right.constant != Constant.NotAConstant)) { try { - this.constant = - Constant.computeConstantOperation( - this.left.constant, - leftId, + this.constant = Constant.computeConstantOperation( + this.left.constant, leftId, (this.bits & OperatorMASK) >> OperatorSHIFT, - this.right.constant, - rightId); + this.right.constant, rightId); } catch (ArithmeticException e) { this.constant = Constant.NotAConstant; // 1.2 no longer throws an exception at compile-time - //scope.problemReporter().compileTimeConstantThrowsArithmeticException(this); + // scope.problemReporter().compileTimeConstantThrowsArithmeticException(this); } } else { this.constant = Constant.NotAConstant; - //add some work for the boolean operators & | -// this.optimizedBooleanConstant( -// leftId, -// (this.bits & OperatorMASK) >> OperatorSHIFT, -// rightId); + // add some work for the boolean operators & | + // this.optimizedBooleanConstant( + // leftId, + // (this.bits & OperatorMASK) >> OperatorSHIFT, + // rightId); } } public Constant optimizedBooleanConstant() { - return this.optimizedBooleanConstant == null ? this.constant : this.optimizedBooleanConstant; + return this.optimizedBooleanConstant == null ? this.constant + : this.optimizedBooleanConstant; } /** * Code generation for a binary operation */ -// public void generateCode( -// BlockScope currentScope, -// CodeStream codeStream, -// boolean valueRequired) { -// -// int pc = codeStream.position; -// Label falseLabel, endLabel; -// if (constant != Constant.NotAConstant) { -// if (valueRequired) -// codeStream.generateConstant(constant, implicitConversion); -// codeStream.recordPositionsFrom(pc, this.sourceStart); -// return; -// } -// bits |= OnlyValueRequiredMASK; -// switch ((bits & OperatorMASK) >> OperatorSHIFT) { -// case PLUS : -// switch (bits & ReturnTypeIDMASK) { -// case T_String : -// codeStream.generateStringAppend(currentScope, left, right); -// if (!valueRequired) -// codeStream.pop(); -// break; -// case T_int : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.iadd(); -// break; -// case T_long : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.ladd(); -// break; -// case T_double : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.dadd(); -// break; -// case T_float : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.fadd(); -// break; -// } -// break; -// case MINUS : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.isub(); -// break; -// case T_long : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.lsub(); -// break; -// case T_double : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.dsub(); -// break; -// case T_float : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.fsub(); -// break; -// } -// break; -// case MULTIPLY : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.imul(); -// break; -// case T_long : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.lmul(); -// break; -// case T_double : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.dmul(); -// break; -// case T_float : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.fmul(); -// break; -// } -// break; -// case DIVIDE : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// left.generateCode(currentScope, codeStream, true); -// right.generateCode(currentScope, codeStream, true); -// codeStream.idiv(); -// if (!valueRequired) -// codeStream.pop(); -// break; -// case T_long : -// left.generateCode(currentScope, codeStream, true); -// right.generateCode(currentScope, codeStream, true); -// codeStream.ldiv(); -// if (!valueRequired) -// codeStream.pop2(); -// break; -// case T_double : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.ddiv(); -// break; -// case T_float : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.fdiv(); -// break; -// } -// break; -// case REMAINDER : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// left.generateCode(currentScope, codeStream, true); -// right.generateCode(currentScope, codeStream, true); -// codeStream.irem(); -// if (!valueRequired) -// codeStream.pop(); -// break; -// case T_long : -// left.generateCode(currentScope, codeStream, true); -// right.generateCode(currentScope, codeStream, true); -// codeStream.lrem(); -// if (!valueRequired) -// codeStream.pop2(); -// break; -// case T_double : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.drem(); -// break; -// case T_float : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.frem(); -// break; -// } -// break; -// case AND : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// // 0 & x -// if ((left.constant != Constant.NotAConstant) -// && (left.constant.typeID() == T_int) -// && (left.constant.intValue() == 0)) { -// right.generateCode(currentScope, codeStream, false); -// if (valueRequired) -// codeStream.iconst_0(); -// } else { -// // x & 0 -// if ((right.constant != Constant.NotAConstant) -// && (right.constant.typeID() == T_int) -// && (right.constant.intValue() == 0)) { -// left.generateCode(currentScope, codeStream, false); -// if (valueRequired) -// codeStream.iconst_0(); -// } else { -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.iand(); -// } -// } -// break; -// case T_long : -// // 0 & x -// if ((left.constant != Constant.NotAConstant) -// && (left.constant.typeID() == T_long) -// && (left.constant.longValue() == 0L)) { -// right.generateCode(currentScope, codeStream, false); -// if (valueRequired) -// codeStream.lconst_0(); -// } else { -// // x & 0 -// if ((right.constant != Constant.NotAConstant) -// && (right.constant.typeID() == T_long) -// && (right.constant.longValue() == 0L)) { -// left.generateCode(currentScope, codeStream, false); -// if (valueRequired) -// codeStream.lconst_0(); -// } else { -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.land(); -// } -// } -// break; -// case T_boolean : // logical and -// generateOptimizedLogicalAnd( -// currentScope, -// codeStream, -// null, -// (falseLabel = new Label(codeStream)), -// valueRequired); -// /* improving code gen for such a case: boolean b = i < 0 && false; -// * since the label has never been used, we have the inlined value on the stack. */ -// if (falseLabel.hasForwardReferences()) { -// if (valueRequired) { -// codeStream.iconst_1(); -// if ((bits & ValueForReturnMASK) != 0) { -// codeStream.ireturn(); -// falseLabel.place(); -// codeStream.iconst_0(); -// } else { -// codeStream.goto_(endLabel = new Label(codeStream)); -// codeStream.decrStackSize(1); -// falseLabel.place(); -// codeStream.iconst_0(); -// endLabel.place(); -// } -// } else { -// falseLabel.place(); -// } -// } -// } -// break; -// case OR : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// // 0 | x -// if ((left.constant != Constant.NotAConstant) -// && (left.constant.typeID() == T_int) -// && (left.constant.intValue() == 0)) { -// right.generateCode(currentScope, codeStream, valueRequired); -// } else { -// // x | 0 -// if ((right.constant != Constant.NotAConstant) -// && (right.constant.typeID() == T_int) -// && (right.constant.intValue() == 0)) { -// left.generateCode(currentScope, codeStream, valueRequired); -// } else { -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.ior(); -// } -// } -// break; -// case T_long : -// // 0 | x -// if ((left.constant != Constant.NotAConstant) -// && (left.constant.typeID() == T_long) -// && (left.constant.longValue() == 0L)) { -// right.generateCode(currentScope, codeStream, valueRequired); -// } else { -// // x | 0 -// if ((right.constant != Constant.NotAConstant) -// && (right.constant.typeID() == T_long) -// && (right.constant.longValue() == 0L)) { -// left.generateCode(currentScope, codeStream, valueRequired); -// } else { -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.lor(); -// } -// } -// break; -// case T_boolean : // logical or -// generateOptimizedLogicalOr( -// currentScope, -// codeStream, -// null, -// (falseLabel = new Label(codeStream)), -// valueRequired); -// /* improving code gen for such a case: boolean b = i < 0 || true; -// * since the label has never been used, we have the inlined value on the stack. */ -// if (falseLabel.hasForwardReferences()) { -// if (valueRequired) { -// codeStream.iconst_1(); -// if ((bits & ValueForReturnMASK) != 0) { -// codeStream.ireturn(); -// falseLabel.place(); -// codeStream.iconst_0(); -// } else { -// codeStream.goto_(endLabel = new Label(codeStream)); -// codeStream.decrStackSize(1); -// falseLabel.place(); -// codeStream.iconst_0(); -// endLabel.place(); -// } -// } else { -// falseLabel.place(); -// } -// } -// } -// break; -// case XOR : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// // 0 ^ x -// if ((left.constant != Constant.NotAConstant) -// && (left.constant.typeID() == T_int) -// && (left.constant.intValue() == 0)) { -// right.generateCode(currentScope, codeStream, valueRequired); -// } else { -// // x ^ 0 -// if ((right.constant != Constant.NotAConstant) -// && (right.constant.typeID() == T_int) -// && (right.constant.intValue() == 0)) { -// left.generateCode(currentScope, codeStream, valueRequired); -// } else { -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.ixor(); -// } -// } -// break; -// case T_long : -// // 0 ^ x -// if ((left.constant != Constant.NotAConstant) -// && (left.constant.typeID() == T_long) -// && (left.constant.longValue() == 0L)) { -// right.generateCode(currentScope, codeStream, valueRequired); -// } else { -// // x ^ 0 -// if ((right.constant != Constant.NotAConstant) -// && (right.constant.typeID() == T_long) -// && (right.constant.longValue() == 0L)) { -// left.generateCode(currentScope, codeStream, valueRequired); -// } else { -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.lxor(); -// } -// } -// break; -// case T_boolean : -// generateOptimizedLogicalXor( -// currentScope, -// codeStream, -// null, -// (falseLabel = new Label(codeStream)), -// valueRequired); -// /* improving code gen for such a case: boolean b = i < 0 ^ bool; -// * since the label has never been used, we have the inlined value on the stack. */ -// if (falseLabel.hasForwardReferences()) { -// if (valueRequired) { -// codeStream.iconst_1(); -// if ((bits & ValueForReturnMASK) != 0) { -// codeStream.ireturn(); -// falseLabel.place(); -// codeStream.iconst_0(); -// } else { -// codeStream.goto_(endLabel = new Label(codeStream)); -// codeStream.decrStackSize(1); -// falseLabel.place(); -// codeStream.iconst_0(); -// endLabel.place(); -// } -// } else { -// falseLabel.place(); -// } -// } -// } -// break; -// case LEFT_SHIFT : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.ishl(); -// break; -// case T_long : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.lshl(); -// } -// break; -// case RIGHT_SHIFT : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.ishr(); -// break; -// case T_long : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.lshr(); -// } -// break; -// case UNSIGNED_RIGHT_SHIFT : -// switch (bits & ReturnTypeIDMASK) { -// case T_int : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.iushr(); -// break; -// case T_long : -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) -// codeStream.lushr(); -// } -// break; -// case GREATER : -// generateOptimizedGreaterThan( -// currentScope, -// codeStream, -// null, -// (falseLabel = new Label(codeStream)), -// valueRequired); -// if (valueRequired) { -// codeStream.iconst_1(); -// if ((bits & ValueForReturnMASK) != 0) { -// codeStream.ireturn(); -// falseLabel.place(); -// codeStream.iconst_0(); -// } else { -// codeStream.goto_(endLabel = new Label(codeStream)); -// codeStream.decrStackSize(1); -// falseLabel.place(); -// codeStream.iconst_0(); -// endLabel.place(); -// } -// } -// break; -// case GREATER_EQUAL : -// generateOptimizedGreaterThanOrEqual( -// currentScope, -// codeStream, -// null, -// (falseLabel = new Label(codeStream)), -// valueRequired); -// if (valueRequired) { -// codeStream.iconst_1(); -// if ((bits & ValueForReturnMASK) != 0) { -// codeStream.ireturn(); -// falseLabel.place(); -// codeStream.iconst_0(); -// } else { -// codeStream.goto_(endLabel = new Label(codeStream)); -// codeStream.decrStackSize(1); -// falseLabel.place(); -// codeStream.iconst_0(); -// endLabel.place(); -// } -// } -// break; -// case LESS : -// generateOptimizedLessThan( -// currentScope, -// codeStream, -// null, -// (falseLabel = new Label(codeStream)), -// valueRequired); -// if (valueRequired) { -// codeStream.iconst_1(); -// if ((bits & ValueForReturnMASK) != 0) { -// codeStream.ireturn(); -// falseLabel.place(); -// codeStream.iconst_0(); -// } else { -// codeStream.goto_(endLabel = new Label(codeStream)); -// codeStream.decrStackSize(1); -// falseLabel.place(); -// codeStream.iconst_0(); -// endLabel.place(); -// } -// } -// break; -// case LESS_EQUAL : -// generateOptimizedLessThanOrEqual( -// currentScope, -// codeStream, -// null, -// (falseLabel = new Label(codeStream)), -// valueRequired); -// if (valueRequired) { -// codeStream.iconst_1(); -// if ((bits & ValueForReturnMASK) != 0) { -// codeStream.ireturn(); -// falseLabel.place(); -// codeStream.iconst_0(); -// } else { -// codeStream.goto_(endLabel = new Label(codeStream)); -// codeStream.decrStackSize(1); -// falseLabel.place(); -// codeStream.iconst_0(); -// endLabel.place(); -// } -// } -// } -// if (valueRequired) { -// codeStream.generateImplicitConversion(implicitConversion); -// } -// codeStream.recordPositionsFrom(pc, this.sourceStart); -// } - + // public void generateCode( + // BlockScope currentScope, + // CodeStream codeStream, + // boolean valueRequired) { + // + // int pc = codeStream.position; + // Label falseLabel, endLabel; + // if (constant != Constant.NotAConstant) { + // if (valueRequired) + // codeStream.generateConstant(constant, implicitConversion); + // codeStream.recordPositionsFrom(pc, this.sourceStart); + // return; + // } + // bits |= OnlyValueRequiredMASK; + // switch ((bits & OperatorMASK) >> OperatorSHIFT) { + // case PLUS : + // switch (bits & ReturnTypeIDMASK) { + // case T_String : + // codeStream.generateStringAppend(currentScope, left, right); + // if (!valueRequired) + // codeStream.pop(); + // break; + // case T_int : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.iadd(); + // break; + // case T_long : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.ladd(); + // break; + // case T_double : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.dadd(); + // break; + // case T_float : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.fadd(); + // break; + // } + // break; + // case MINUS : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.isub(); + // break; + // case T_long : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.lsub(); + // break; + // case T_double : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.dsub(); + // break; + // case T_float : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.fsub(); + // break; + // } + // break; + // case MULTIPLY : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.imul(); + // break; + // case T_long : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.lmul(); + // break; + // case T_double : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.dmul(); + // break; + // case T_float : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.fmul(); + // break; + // } + // break; + // case DIVIDE : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // left.generateCode(currentScope, codeStream, true); + // right.generateCode(currentScope, codeStream, true); + // codeStream.idiv(); + // if (!valueRequired) + // codeStream.pop(); + // break; + // case T_long : + // left.generateCode(currentScope, codeStream, true); + // right.generateCode(currentScope, codeStream, true); + // codeStream.ldiv(); + // if (!valueRequired) + // codeStream.pop2(); + // break; + // case T_double : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.ddiv(); + // break; + // case T_float : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.fdiv(); + // break; + // } + // break; + // case REMAINDER : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // left.generateCode(currentScope, codeStream, true); + // right.generateCode(currentScope, codeStream, true); + // codeStream.irem(); + // if (!valueRequired) + // codeStream.pop(); + // break; + // case T_long : + // left.generateCode(currentScope, codeStream, true); + // right.generateCode(currentScope, codeStream, true); + // codeStream.lrem(); + // if (!valueRequired) + // codeStream.pop2(); + // break; + // case T_double : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.drem(); + // break; + // case T_float : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.frem(); + // break; + // } + // break; + // case AND : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // // 0 & x + // if ((left.constant != Constant.NotAConstant) + // && (left.constant.typeID() == T_int) + // && (left.constant.intValue() == 0)) { + // right.generateCode(currentScope, codeStream, false); + // if (valueRequired) + // codeStream.iconst_0(); + // } else { + // // x & 0 + // if ((right.constant != Constant.NotAConstant) + // && (right.constant.typeID() == T_int) + // && (right.constant.intValue() == 0)) { + // left.generateCode(currentScope, codeStream, false); + // if (valueRequired) + // codeStream.iconst_0(); + // } else { + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.iand(); + // } + // } + // break; + // case T_long : + // // 0 & x + // if ((left.constant != Constant.NotAConstant) + // && (left.constant.typeID() == T_long) + // && (left.constant.longValue() == 0L)) { + // right.generateCode(currentScope, codeStream, false); + // if (valueRequired) + // codeStream.lconst_0(); + // } else { + // // x & 0 + // if ((right.constant != Constant.NotAConstant) + // && (right.constant.typeID() == T_long) + // && (right.constant.longValue() == 0L)) { + // left.generateCode(currentScope, codeStream, false); + // if (valueRequired) + // codeStream.lconst_0(); + // } else { + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.land(); + // } + // } + // break; + // case T_boolean : // logical and + // generateOptimizedLogicalAnd( + // currentScope, + // codeStream, + // null, + // (falseLabel = new Label(codeStream)), + // valueRequired); + // /* improving code gen for such a case: boolean b = i < 0 && false; + // * since the label has never been used, we have the inlined value on the + // stack. */ + // if (falseLabel.hasForwardReferences()) { + // if (valueRequired) { + // codeStream.iconst_1(); + // if ((bits & ValueForReturnMASK) != 0) { + // codeStream.ireturn(); + // falseLabel.place(); + // codeStream.iconst_0(); + // } else { + // codeStream.goto_(endLabel = new Label(codeStream)); + // codeStream.decrStackSize(1); + // falseLabel.place(); + // codeStream.iconst_0(); + // endLabel.place(); + // } + // } else { + // falseLabel.place(); + // } + // } + // } + // break; + // case OR : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // // 0 | x + // if ((left.constant != Constant.NotAConstant) + // && (left.constant.typeID() == T_int) + // && (left.constant.intValue() == 0)) { + // right.generateCode(currentScope, codeStream, valueRequired); + // } else { + // // x | 0 + // if ((right.constant != Constant.NotAConstant) + // && (right.constant.typeID() == T_int) + // && (right.constant.intValue() == 0)) { + // left.generateCode(currentScope, codeStream, valueRequired); + // } else { + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.ior(); + // } + // } + // break; + // case T_long : + // // 0 | x + // if ((left.constant != Constant.NotAConstant) + // && (left.constant.typeID() == T_long) + // && (left.constant.longValue() == 0L)) { + // right.generateCode(currentScope, codeStream, valueRequired); + // } else { + // // x | 0 + // if ((right.constant != Constant.NotAConstant) + // && (right.constant.typeID() == T_long) + // && (right.constant.longValue() == 0L)) { + // left.generateCode(currentScope, codeStream, valueRequired); + // } else { + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.lor(); + // } + // } + // break; + // case T_boolean : // logical or + // generateOptimizedLogicalOr( + // currentScope, + // codeStream, + // null, + // (falseLabel = new Label(codeStream)), + // valueRequired); + // /* improving code gen for such a case: boolean b = i < 0 || true; + // * since the label has never been used, we have the inlined value on the + // stack. */ + // if (falseLabel.hasForwardReferences()) { + // if (valueRequired) { + // codeStream.iconst_1(); + // if ((bits & ValueForReturnMASK) != 0) { + // codeStream.ireturn(); + // falseLabel.place(); + // codeStream.iconst_0(); + // } else { + // codeStream.goto_(endLabel = new Label(codeStream)); + // codeStream.decrStackSize(1); + // falseLabel.place(); + // codeStream.iconst_0(); + // endLabel.place(); + // } + // } else { + // falseLabel.place(); + // } + // } + // } + // break; + // case XOR : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // // 0 ^ x + // if ((left.constant != Constant.NotAConstant) + // && (left.constant.typeID() == T_int) + // && (left.constant.intValue() == 0)) { + // right.generateCode(currentScope, codeStream, valueRequired); + // } else { + // // x ^ 0 + // if ((right.constant != Constant.NotAConstant) + // && (right.constant.typeID() == T_int) + // && (right.constant.intValue() == 0)) { + // left.generateCode(currentScope, codeStream, valueRequired); + // } else { + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.ixor(); + // } + // } + // break; + // case T_long : + // // 0 ^ x + // if ((left.constant != Constant.NotAConstant) + // && (left.constant.typeID() == T_long) + // && (left.constant.longValue() == 0L)) { + // right.generateCode(currentScope, codeStream, valueRequired); + // } else { + // // x ^ 0 + // if ((right.constant != Constant.NotAConstant) + // && (right.constant.typeID() == T_long) + // && (right.constant.longValue() == 0L)) { + // left.generateCode(currentScope, codeStream, valueRequired); + // } else { + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.lxor(); + // } + // } + // break; + // case T_boolean : + // generateOptimizedLogicalXor( + // currentScope, + // codeStream, + // null, + // (falseLabel = new Label(codeStream)), + // valueRequired); + // /* improving code gen for such a case: boolean b = i < 0 ^ bool; + // * since the label has never been used, we have the inlined value on the + // stack. */ + // if (falseLabel.hasForwardReferences()) { + // if (valueRequired) { + // codeStream.iconst_1(); + // if ((bits & ValueForReturnMASK) != 0) { + // codeStream.ireturn(); + // falseLabel.place(); + // codeStream.iconst_0(); + // } else { + // codeStream.goto_(endLabel = new Label(codeStream)); + // codeStream.decrStackSize(1); + // falseLabel.place(); + // codeStream.iconst_0(); + // endLabel.place(); + // } + // } else { + // falseLabel.place(); + // } + // } + // } + // break; + // case LEFT_SHIFT : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.ishl(); + // break; + // case T_long : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.lshl(); + // } + // break; + // case RIGHT_SHIFT : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.ishr(); + // break; + // case T_long : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.lshr(); + // } + // break; + // case UNSIGNED_RIGHT_SHIFT : + // switch (bits & ReturnTypeIDMASK) { + // case T_int : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.iushr(); + // break; + // case T_long : + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) + // codeStream.lushr(); + // } + // break; + // case GREATER : + // generateOptimizedGreaterThan( + // currentScope, + // codeStream, + // null, + // (falseLabel = new Label(codeStream)), + // valueRequired); + // if (valueRequired) { + // codeStream.iconst_1(); + // if ((bits & ValueForReturnMASK) != 0) { + // codeStream.ireturn(); + // falseLabel.place(); + // codeStream.iconst_0(); + // } else { + // codeStream.goto_(endLabel = new Label(codeStream)); + // codeStream.decrStackSize(1); + // falseLabel.place(); + // codeStream.iconst_0(); + // endLabel.place(); + // } + // } + // break; + // case GREATER_EQUAL : + // generateOptimizedGreaterThanOrEqual( + // currentScope, + // codeStream, + // null, + // (falseLabel = new Label(codeStream)), + // valueRequired); + // if (valueRequired) { + // codeStream.iconst_1(); + // if ((bits & ValueForReturnMASK) != 0) { + // codeStream.ireturn(); + // falseLabel.place(); + // codeStream.iconst_0(); + // } else { + // codeStream.goto_(endLabel = new Label(codeStream)); + // codeStream.decrStackSize(1); + // falseLabel.place(); + // codeStream.iconst_0(); + // endLabel.place(); + // } + // } + // break; + // case LESS : + // generateOptimizedLessThan( + // currentScope, + // codeStream, + // null, + // (falseLabel = new Label(codeStream)), + // valueRequired); + // if (valueRequired) { + // codeStream.iconst_1(); + // if ((bits & ValueForReturnMASK) != 0) { + // codeStream.ireturn(); + // falseLabel.place(); + // codeStream.iconst_0(); + // } else { + // codeStream.goto_(endLabel = new Label(codeStream)); + // codeStream.decrStackSize(1); + // falseLabel.place(); + // codeStream.iconst_0(); + // endLabel.place(); + // } + // } + // break; + // case LESS_EQUAL : + // generateOptimizedLessThanOrEqual( + // currentScope, + // codeStream, + // null, + // (falseLabel = new Label(codeStream)), + // valueRequired); + // if (valueRequired) { + // codeStream.iconst_1(); + // if ((bits & ValueForReturnMASK) != 0) { + // codeStream.ireturn(); + // falseLabel.place(); + // codeStream.iconst_0(); + // } else { + // codeStream.goto_(endLabel = new Label(codeStream)); + // codeStream.decrStackSize(1); + // falseLabel.place(); + // codeStream.iconst_0(); + // endLabel.place(); + // } + // } + // } + // if (valueRequired) { + // codeStream.generateImplicitConversion(implicitConversion); + // } + // codeStream.recordPositionsFrom(pc, this.sourceStart); + // } /** - * Boolean operator code generation - * Optimized operations are: <, <=, >, >=, &, |, ^ + * Boolean operator code generation Optimized operations are: <, <=, >, >=, &, |, ^ */ -// public void generateOptimizedBoolean( -// BlockScope currentScope, -// CodeStream codeStream, -// Label trueLabel, -// Label falseLabel, -// boolean valueRequired) { -// -// if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) { -// super.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// return; -// } -// switch ((bits & OperatorMASK) >> OperatorSHIFT) { -// case LESS : -// generateOptimizedLessThan( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// return; -// case LESS_EQUAL : -// generateOptimizedLessThanOrEqual( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// return; -// case GREATER : -// generateOptimizedGreaterThan( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// return; -// case GREATER_EQUAL : -// generateOptimizedGreaterThanOrEqual( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// return; -// case AND : -// generateOptimizedLogicalAnd( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// return; -// case OR : -// generateOptimizedLogicalOr( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// return; -// case XOR : -// generateOptimizedLogicalXor( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// return; -// } -// super.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// } -// -// /** -// * Boolean generation for > -// */ -// public void generateOptimizedGreaterThan( -// BlockScope currentScope, -// CodeStream codeStream, -// Label trueLabel, -// Label falseLabel, -// boolean valueRequired) { -// -// int promotedTypeID = left.implicitConversion >> 4; -// // both sides got promoted in the same way -// if (promotedTypeID == T_int) { -// // 0 > x -// if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicitly falling through the FALSE case -// codeStream.iflt(trueLabel); -// } -// } else { -// if (trueLabel == null) { -// // implicitly falling through the TRUE case -// codeStream.ifge(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// // x > 0 -// if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) { -// left.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicitly falling through the FALSE case -// codeStream.ifgt(trueLabel); -// } -// } else { -// if (trueLabel == null) { -// // implicitly falling through the TRUE case -// codeStream.ifle(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// } -// // default comparison -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicit falling through the FALSE case -// switch (promotedTypeID) { -// case T_int : -// codeStream.if_icmpgt(trueLabel); -// break; -// case T_float : -// codeStream.fcmpl(); -// codeStream.ifgt(trueLabel); -// break; -// case T_long : -// codeStream.lcmp(); -// codeStream.ifgt(trueLabel); -// break; -// case T_double : -// codeStream.dcmpl(); -// codeStream.ifgt(trueLabel); -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// } else { -// if (trueLabel == null) { -// // implicit falling through the TRUE case -// switch (promotedTypeID) { -// case T_int : -// codeStream.if_icmple(falseLabel); -// break; -// case T_float : -// codeStream.fcmpl(); -// codeStream.ifle(falseLabel); -// break; -// case T_long : -// codeStream.lcmp(); -// codeStream.ifle(falseLabel); -// break; -// case T_double : -// codeStream.dcmpl(); -// codeStream.ifle(falseLabel); -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// } - + // public void generateOptimizedBoolean( + // BlockScope currentScope, + // CodeStream codeStream, + // Label trueLabel, + // Label falseLabel, + // boolean valueRequired) { + // + // if ((constant != Constant.NotAConstant) && (constant.typeID() == + // T_boolean)) { + // super.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // return; + // } + // switch ((bits & OperatorMASK) >> OperatorSHIFT) { + // case LESS : + // generateOptimizedLessThan( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // return; + // case LESS_EQUAL : + // generateOptimizedLessThanOrEqual( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // return; + // case GREATER : + // generateOptimizedGreaterThan( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // return; + // case GREATER_EQUAL : + // generateOptimizedGreaterThanOrEqual( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // return; + // case AND : + // generateOptimizedLogicalAnd( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // return; + // case OR : + // generateOptimizedLogicalOr( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // return; + // case XOR : + // generateOptimizedLogicalXor( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // return; + // } + // super.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // } + // + // /** + // * Boolean generation for > + // */ + // public void generateOptimizedGreaterThan( + // BlockScope currentScope, + // CodeStream codeStream, + // Label trueLabel, + // Label falseLabel, + // boolean valueRequired) { + // + // int promotedTypeID = left.implicitConversion >> 4; + // // both sides got promoted in the same way + // if (promotedTypeID == T_int) { + // // 0 > x + // if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicitly falling through the FALSE case + // codeStream.iflt(trueLabel); + // } + // } else { + // if (trueLabel == null) { + // // implicitly falling through the TRUE case + // codeStream.ifge(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // // x > 0 + // if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) + // { + // left.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicitly falling through the FALSE case + // codeStream.ifgt(trueLabel); + // } + // } else { + // if (trueLabel == null) { + // // implicitly falling through the TRUE case + // codeStream.ifle(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // } + // // default comparison + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicit falling through the FALSE case + // switch (promotedTypeID) { + // case T_int : + // codeStream.if_icmpgt(trueLabel); + // break; + // case T_float : + // codeStream.fcmpl(); + // codeStream.ifgt(trueLabel); + // break; + // case T_long : + // codeStream.lcmp(); + // codeStream.ifgt(trueLabel); + // break; + // case T_double : + // codeStream.dcmpl(); + // codeStream.ifgt(trueLabel); + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // } else { + // if (trueLabel == null) { + // // implicit falling through the TRUE case + // switch (promotedTypeID) { + // case T_int : + // codeStream.if_icmple(falseLabel); + // break; + // case T_float : + // codeStream.fcmpl(); + // codeStream.ifle(falseLabel); + // break; + // case T_long : + // codeStream.lcmp(); + // codeStream.ifle(falseLabel); + // break; + // case T_double : + // codeStream.dcmpl(); + // codeStream.ifle(falseLabel); + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // } /** * Boolean generation for >= */ -// public void generateOptimizedGreaterThanOrEqual( -// BlockScope currentScope, -// CodeStream codeStream, -// Label trueLabel, -// Label falseLabel, -// boolean valueRequired) { -// -// int promotedTypeID = left.implicitConversion >> 4; -// // both sides got promoted in the same way -// if (promotedTypeID == T_int) { -// // 0 >= x -// if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicitly falling through the FALSE case -// codeStream.ifle(trueLabel); -// } -// } else { -// if (trueLabel == null) { -// // implicitly falling through the TRUE case -// codeStream.ifgt(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// // x >= 0 -// if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) { -// left.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicitly falling through the FALSE case -// codeStream.ifge(trueLabel); -// } -// } else { -// if (trueLabel == null) { -// // implicitly falling through the TRUE case -// codeStream.iflt(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// } -// // default comparison -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicit falling through the FALSE case -// switch (promotedTypeID) { -// case T_int : -// codeStream.if_icmpge(trueLabel); -// break; -// case T_float : -// codeStream.fcmpl(); -// codeStream.ifge(trueLabel); -// break; -// case T_long : -// codeStream.lcmp(); -// codeStream.ifge(trueLabel); -// break; -// case T_double : -// codeStream.dcmpl(); -// codeStream.ifge(trueLabel); -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// } else { -// if (trueLabel == null) { -// // implicit falling through the TRUE case -// switch (promotedTypeID) { -// case T_int : -// codeStream.if_icmplt(falseLabel); -// break; -// case T_float : -// codeStream.fcmpl(); -// codeStream.iflt(falseLabel); -// break; -// case T_long : -// codeStream.lcmp(); -// codeStream.iflt(falseLabel); -// break; -// case T_double : -// codeStream.dcmpl(); -// codeStream.iflt(falseLabel); -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// } -// -// /** -// * Boolean generation for < -// */ -// public void generateOptimizedLessThan( -// BlockScope currentScope, -// CodeStream codeStream, -// Label trueLabel, -// Label falseLabel, -// boolean valueRequired) { -// -// int promotedTypeID = left.implicitConversion >> 4; -// // both sides got promoted in the same way -// if (promotedTypeID == T_int) { -// // 0 < x -// if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicitly falling through the FALSE case -// codeStream.ifgt(trueLabel); -// } -// } else { -// if (trueLabel == null) { -// // implicitly falling through the TRUE case -// codeStream.ifle(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// // x < 0 -// if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) { -// left.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicitly falling through the FALSE case -// codeStream.iflt(trueLabel); -// } -// } else { -// if (trueLabel == null) { -// // implicitly falling through the TRUE case -// codeStream.ifge(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// } -// // default comparison -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicit falling through the FALSE case -// switch (promotedTypeID) { -// case T_int : -// codeStream.if_icmplt(trueLabel); -// break; -// case T_float : -// codeStream.fcmpg(); -// codeStream.iflt(trueLabel); -// break; -// case T_long : -// codeStream.lcmp(); -// codeStream.iflt(trueLabel); -// break; -// case T_double : -// codeStream.dcmpg(); -// codeStream.iflt(trueLabel); -// } -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// } else { -// if (trueLabel == null) { -// // implicit falling through the TRUE case -// switch (promotedTypeID) { -// case T_int : -// codeStream.if_icmpge(falseLabel); -// break; -// case T_float : -// codeStream.fcmpg(); -// codeStream.ifge(falseLabel); -// break; -// case T_long : -// codeStream.lcmp(); -// codeStream.ifge(falseLabel); -// break; -// case T_double : -// codeStream.dcmpg(); -// codeStream.ifge(falseLabel); -// } -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// } -// -// /** -// * Boolean generation for <= -// */ -// public void generateOptimizedLessThanOrEqual( -// BlockScope currentScope, -// CodeStream codeStream, -// Label trueLabel, -// Label falseLabel, -// boolean valueRequired) { -// -// int promotedTypeID = left.implicitConversion >> 4; -// // both sides got promoted in the same way -// if (promotedTypeID == T_int) { -// // 0 <= x -// if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicitly falling through the FALSE case -// codeStream.ifge(trueLabel); -// } -// } else { -// if (trueLabel == null) { -// // implicitly falling through the TRUE case -// codeStream.iflt(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// // x <= 0 -// if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) { -// left.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicitly falling through the FALSE case -// codeStream.ifle(trueLabel); -// } -// } else { -// if (trueLabel == null) { -// // implicitly falling through the TRUE case -// codeStream.ifgt(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// } -// // default comparison -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicit falling through the FALSE case -// switch (promotedTypeID) { -// case T_int : -// codeStream.if_icmple(trueLabel); -// break; -// case T_float : -// codeStream.fcmpg(); -// codeStream.ifle(trueLabel); -// break; -// case T_long : -// codeStream.lcmp(); -// codeStream.ifle(trueLabel); -// break; -// case T_double : -// codeStream.dcmpg(); -// codeStream.ifle(trueLabel); -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } -// } else { -// if (trueLabel == null) { -// // implicit falling through the TRUE case -// switch (promotedTypeID) { -// case T_int : -// codeStream.if_icmpgt(falseLabel); -// break; -// case T_float : -// codeStream.fcmpg(); -// codeStream.ifgt(falseLabel); -// break; -// case T_long : -// codeStream.lcmp(); -// codeStream.ifgt(falseLabel); -// break; -// case T_double : -// codeStream.dcmpg(); -// codeStream.ifgt(falseLabel); -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// return; -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// } -// -// /** -// * Boolean generation for & -// */ -// public void generateOptimizedLogicalAnd( -// BlockScope currentScope, -// CodeStream codeStream, -// Label trueLabel, -// Label falseLabel, -// boolean valueRequired) { -// -// Constant condConst; -// if ((left.implicitConversion & 0xF) == T_boolean) { -// if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { -// if (condConst.booleanValue() == true) { -// // & x -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// if ((bits & OnlyValueRequiredMASK) != 0) { -// right.generateCode(currentScope, codeStream, valueRequired); -// } else { -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// } -// } else { -// // & x -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// if (valueRequired) { -// if ((bits & OnlyValueRequiredMASK) != 0) { -// codeStream.iconst_0(); -// } else { -// if (falseLabel != null) { -// // implicit falling through the TRUE case -// codeStream.goto_(falseLabel); -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// } -// return; -// } -// if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { -// if (condConst.booleanValue() == true) { -// // x & -// if ((bits & OnlyValueRequiredMASK) != 0) { -// left.generateCode(currentScope, codeStream, valueRequired); -// } else { -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// } -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// } else { -// // x & -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// if (valueRequired) { -// if ((bits & OnlyValueRequiredMASK) != 0) { -// codeStream.iconst_0(); -// } else { -// if (falseLabel != null) { -// // implicit falling through the TRUE case -// codeStream.goto_(falseLabel); -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// } -// return; -// } -// } -// // default case -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// codeStream.iand(); -// if ((bits & OnlyValueRequiredMASK) == 0) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicit falling through the FALSE case -// codeStream.ifne(trueLabel); -// } -// } else { -// // implicit falling through the TRUE case -// if (trueLabel == null) { -// codeStream.ifeq(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// } -// -// /** -// * Boolean generation for | -// */ -// public void generateOptimizedLogicalOr( -// BlockScope currentScope, -// CodeStream codeStream, -// Label trueLabel, -// Label falseLabel, -// boolean valueRequired) { -// -// Constant condConst; -// if ((left.implicitConversion & 0xF) == T_boolean) { -// if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { -// if (condConst.booleanValue() == true) { -// // | x -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// if (valueRequired) { -// if ((bits & OnlyValueRequiredMASK) != 0) { -// codeStream.iconst_1(); -// } else { -// if (trueLabel != null) { -// codeStream.goto_(trueLabel); -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// } else { -// // | x -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// if ((bits & OnlyValueRequiredMASK) != 0) { -// right.generateCode(currentScope, codeStream, valueRequired); -// } else { -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// } -// } -// return; -// } -// if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { -// if (condConst.booleanValue() == true) { -// // x | -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// if (valueRequired) { -// if ((bits & OnlyValueRequiredMASK) != 0) { -// codeStream.iconst_1(); -// } else { -// if (trueLabel != null) { -// codeStream.goto_(trueLabel); -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// } else { -// // x | -// if ((bits & OnlyValueRequiredMASK) != 0) { -// left.generateCode(currentScope, codeStream, valueRequired); -// } else { -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// } -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// } -// return; -// } -// } -// // default case -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// codeStream.ior(); -// if ((bits & OnlyValueRequiredMASK) == 0) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicit falling through the FALSE case -// codeStream.ifne(trueLabel); -// } -// } else { -// // implicit falling through the TRUE case -// if (trueLabel == null) { -// codeStream.ifeq(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// } -// -// /** -// * Boolean generation for ^ -// */ -// public void generateOptimizedLogicalXor( -// BlockScope currentScope, -// CodeStream codeStream, -// Label trueLabel, -// Label falseLabel, -// boolean valueRequired) { -// -// Constant condConst; -// if ((left.implicitConversion & 0xF) == T_boolean) { -// if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { -// if (condConst.booleanValue() == true) { -// // ^ x -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// falseLabel, -// trueLabel, -// valueRequired); -// } else { -// // ^ x -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// if ((bits & OnlyValueRequiredMASK) != 0) { -// right.generateCode(currentScope, codeStream, valueRequired); -// } else { -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// } -// } -// return; -// } -// if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { -// if (condConst.booleanValue() == true) { -// // x ^ -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// falseLabel, -// trueLabel, -// valueRequired); -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// } else { -// // x ^ -// if ((bits & OnlyValueRequiredMASK) != 0) { -// left.generateCode(currentScope, codeStream, valueRequired); -// } else { -// left.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// valueRequired); -// } -// right.generateOptimizedBoolean( -// currentScope, -// codeStream, -// trueLabel, -// falseLabel, -// false); -// } -// return; -// } -// } -// // default case -// left.generateCode(currentScope, codeStream, valueRequired); -// right.generateCode(currentScope, codeStream, valueRequired); -// if (valueRequired) { -// codeStream.ixor(); -// if ((bits & OnlyValueRequiredMASK) == 0) { -// if (falseLabel == null) { -// if (trueLabel != null) { -// // implicit falling through the FALSE case -// codeStream.ifne(trueLabel); -// } -// } else { -// // implicit falling through the TRUE case -// if (trueLabel == null) { -// codeStream.ifeq(falseLabel); -// } else { -// // no implicit fall through TRUE/FALSE --> should never occur -// } -// } -// } -// } -// // reposition the endPC -// codeStream.updateLastRecordedEndPC(codeStream.position); -// } -// -// public void generateOptimizedStringBuffer( -// BlockScope blockScope, -// CodeStream codeStream, -// int typeID) { -// -// /* In the case trying to make a string concatenation, there is no need to create a new -// * string buffer, thus use a lower-level API for code generation involving only the -// * appending of arguments to the existing StringBuffer -// */ -// -// if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) -// && ((bits & ReturnTypeIDMASK) == T_String)) { -// if (constant != NotAConstant) { -// codeStream.generateConstant(constant, implicitConversion); -// codeStream.invokeStringBufferAppendForType(implicitConversion & 0xF); -// } else { -// int pc = codeStream.position; -// left.generateOptimizedStringBuffer( -// blockScope, -// codeStream, -// left.implicitConversion & 0xF); -// codeStream.recordPositionsFrom(pc, left.sourceStart); -// pc = codeStream.position; -// right.generateOptimizedStringBuffer( -// blockScope, -// codeStream, -// right.implicitConversion & 0xF); -// codeStream.recordPositionsFrom(pc, right.sourceStart); -// } -// } else { -// super.generateOptimizedStringBuffer(blockScope, codeStream, typeID); -// } -// } -// -// public void generateOptimizedStringBufferCreation( -// BlockScope blockScope, -// CodeStream codeStream, -// int typeID) { -// -// /* In the case trying to make a string concatenation, there is no need to create a new -// * string buffer, thus use a lower-level API for code generation involving only the -// * appending of arguments to the existing StringBuffer -// */ -// -// if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) -// && ((bits & ReturnTypeIDMASK) == T_String)) { -// if (constant != NotAConstant) { -// codeStream.newStringBuffer(); // new: java.lang.StringBuffer -// codeStream.dup(); -// codeStream.ldc(constant.stringValue()); -// codeStream.invokeStringBufferStringConstructor(); -// // invokespecial: java.lang.StringBuffer.(Ljava.lang.String;)V -// } else { -// int pc = codeStream.position; -// left.generateOptimizedStringBufferCreation( -// blockScope, -// codeStream, -// left.implicitConversion & 0xF); -// codeStream.recordPositionsFrom(pc, left.sourceStart); -// pc = codeStream.position; -// right.generateOptimizedStringBuffer( -// blockScope, -// codeStream, -// right.implicitConversion & 0xF); -// codeStream.recordPositionsFrom(pc, right.sourceStart); -// } -// } else { -// super.generateOptimizedStringBufferCreation(blockScope, codeStream, typeID); -// } -// } -// -// public boolean isCompactableOperation() { -// -// return true; -// } -// -// public void optimizedBooleanConstant(int leftId, int operator, int rightId) { -// -// switch (operator) { -// case AND : -// if ((leftId != T_boolean) || (rightId != T_boolean)) -// return; -// case AND_AND : -// Constant cst; -// if ((cst = left.optimizedBooleanConstant()) != NotAConstant) { -// if (cst.booleanValue() == false) { // left is equivalent to false -// optimizedBooleanConstant = cst; // constant(false) -// return; -// } else { //left is equivalent to true -// if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { -// optimizedBooleanConstant = cst; -// // the conditional result is equivalent to the right conditional value -// } -// return; -// } -// } -// if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { -// if (cst.booleanValue() == false) { // right is equivalent to false -// optimizedBooleanConstant = cst; // constant(false) -// } -// } -// return; -// case OR : -// if ((leftId != T_boolean) || (rightId != T_boolean)) -// return; -// case OR_OR : -// if ((cst = left.optimizedBooleanConstant()) != NotAConstant) { -// if (cst.booleanValue() == true) { // left is equivalent to true -// optimizedBooleanConstant = cst; // constant(true) -// return; -// } else { //left is equivalent to false -// if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { -// optimizedBooleanConstant = cst; -// } -// return; -// } -// } -// if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { -// if (cst.booleanValue() == true) { // right is equivalent to true -// optimizedBooleanConstant = cst; // constant(true) -// } -// } -// } -// } - public StringBuffer printExpressionNoParenthesis(int indent, StringBuffer output) { + // public void generateOptimizedGreaterThanOrEqual( + // BlockScope currentScope, + // CodeStream codeStream, + // Label trueLabel, + // Label falseLabel, + // boolean valueRequired) { + // + // int promotedTypeID = left.implicitConversion >> 4; + // // both sides got promoted in the same way + // if (promotedTypeID == T_int) { + // // 0 >= x + // if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicitly falling through the FALSE case + // codeStream.ifle(trueLabel); + // } + // } else { + // if (trueLabel == null) { + // // implicitly falling through the TRUE case + // codeStream.ifgt(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // // x >= 0 + // if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) + // { + // left.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicitly falling through the FALSE case + // codeStream.ifge(trueLabel); + // } + // } else { + // if (trueLabel == null) { + // // implicitly falling through the TRUE case + // codeStream.iflt(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // } + // // default comparison + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicit falling through the FALSE case + // switch (promotedTypeID) { + // case T_int : + // codeStream.if_icmpge(trueLabel); + // break; + // case T_float : + // codeStream.fcmpl(); + // codeStream.ifge(trueLabel); + // break; + // case T_long : + // codeStream.lcmp(); + // codeStream.ifge(trueLabel); + // break; + // case T_double : + // codeStream.dcmpl(); + // codeStream.ifge(trueLabel); + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // } else { + // if (trueLabel == null) { + // // implicit falling through the TRUE case + // switch (promotedTypeID) { + // case T_int : + // codeStream.if_icmplt(falseLabel); + // break; + // case T_float : + // codeStream.fcmpl(); + // codeStream.iflt(falseLabel); + // break; + // case T_long : + // codeStream.lcmp(); + // codeStream.iflt(falseLabel); + // break; + // case T_double : + // codeStream.dcmpl(); + // codeStream.iflt(falseLabel); + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // } + // + // /** + // * Boolean generation for < + // */ + // public void generateOptimizedLessThan( + // BlockScope currentScope, + // CodeStream codeStream, + // Label trueLabel, + // Label falseLabel, + // boolean valueRequired) { + // + // int promotedTypeID = left.implicitConversion >> 4; + // // both sides got promoted in the same way + // if (promotedTypeID == T_int) { + // // 0 < x + // if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicitly falling through the FALSE case + // codeStream.ifgt(trueLabel); + // } + // } else { + // if (trueLabel == null) { + // // implicitly falling through the TRUE case + // codeStream.ifle(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // // x < 0 + // if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) + // { + // left.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicitly falling through the FALSE case + // codeStream.iflt(trueLabel); + // } + // } else { + // if (trueLabel == null) { + // // implicitly falling through the TRUE case + // codeStream.ifge(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // } + // // default comparison + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicit falling through the FALSE case + // switch (promotedTypeID) { + // case T_int : + // codeStream.if_icmplt(trueLabel); + // break; + // case T_float : + // codeStream.fcmpg(); + // codeStream.iflt(trueLabel); + // break; + // case T_long : + // codeStream.lcmp(); + // codeStream.iflt(trueLabel); + // break; + // case T_double : + // codeStream.dcmpg(); + // codeStream.iflt(trueLabel); + // } + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // } else { + // if (trueLabel == null) { + // // implicit falling through the TRUE case + // switch (promotedTypeID) { + // case T_int : + // codeStream.if_icmpge(falseLabel); + // break; + // case T_float : + // codeStream.fcmpg(); + // codeStream.ifge(falseLabel); + // break; + // case T_long : + // codeStream.lcmp(); + // codeStream.ifge(falseLabel); + // break; + // case T_double : + // codeStream.dcmpg(); + // codeStream.ifge(falseLabel); + // } + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // } + // + // /** + // * Boolean generation for <= + // */ + // public void generateOptimizedLessThanOrEqual( + // BlockScope currentScope, + // CodeStream codeStream, + // Label trueLabel, + // Label falseLabel, + // boolean valueRequired) { + // + // int promotedTypeID = left.implicitConversion >> 4; + // // both sides got promoted in the same way + // if (promotedTypeID == T_int) { + // // 0 <= x + // if ((left.constant != NotAConstant) && (left.constant.intValue() == 0)) { + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicitly falling through the FALSE case + // codeStream.ifge(trueLabel); + // } + // } else { + // if (trueLabel == null) { + // // implicitly falling through the TRUE case + // codeStream.iflt(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // // x <= 0 + // if ((right.constant != NotAConstant) && (right.constant.intValue() == 0)) + // { + // left.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicitly falling through the FALSE case + // codeStream.ifle(trueLabel); + // } + // } else { + // if (trueLabel == null) { + // // implicitly falling through the TRUE case + // codeStream.ifgt(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // } + // // default comparison + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicit falling through the FALSE case + // switch (promotedTypeID) { + // case T_int : + // codeStream.if_icmple(trueLabel); + // break; + // case T_float : + // codeStream.fcmpg(); + // codeStream.ifle(trueLabel); + // break; + // case T_long : + // codeStream.lcmp(); + // codeStream.ifle(trueLabel); + // break; + // case T_double : + // codeStream.dcmpg(); + // codeStream.ifle(trueLabel); + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } + // } else { + // if (trueLabel == null) { + // // implicit falling through the TRUE case + // switch (promotedTypeID) { + // case T_int : + // codeStream.if_icmpgt(falseLabel); + // break; + // case T_float : + // codeStream.fcmpg(); + // codeStream.ifgt(falseLabel); + // break; + // case T_long : + // codeStream.lcmp(); + // codeStream.ifgt(falseLabel); + // break; + // case T_double : + // codeStream.dcmpg(); + // codeStream.ifgt(falseLabel); + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // return; + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // } + // + // /** + // * Boolean generation for & + // */ + // public void generateOptimizedLogicalAnd( + // BlockScope currentScope, + // CodeStream codeStream, + // Label trueLabel, + // Label falseLabel, + // boolean valueRequired) { + // + // Constant condConst; + // if ((left.implicitConversion & 0xF) == T_boolean) { + // if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { + // if (condConst.booleanValue() == true) { + // // & x + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // if ((bits & OnlyValueRequiredMASK) != 0) { + // right.generateCode(currentScope, codeStream, valueRequired); + // } else { + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // } + // } else { + // // & x + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // if (valueRequired) { + // if ((bits & OnlyValueRequiredMASK) != 0) { + // codeStream.iconst_0(); + // } else { + // if (falseLabel != null) { + // // implicit falling through the TRUE case + // codeStream.goto_(falseLabel); + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // } + // return; + // } + // if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { + // if (condConst.booleanValue() == true) { + // // x & + // if ((bits & OnlyValueRequiredMASK) != 0) { + // left.generateCode(currentScope, codeStream, valueRequired); + // } else { + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // } + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // } else { + // // x & + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // if (valueRequired) { + // if ((bits & OnlyValueRequiredMASK) != 0) { + // codeStream.iconst_0(); + // } else { + // if (falseLabel != null) { + // // implicit falling through the TRUE case + // codeStream.goto_(falseLabel); + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // } + // return; + // } + // } + // // default case + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // codeStream.iand(); + // if ((bits & OnlyValueRequiredMASK) == 0) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicit falling through the FALSE case + // codeStream.ifne(trueLabel); + // } + // } else { + // // implicit falling through the TRUE case + // if (trueLabel == null) { + // codeStream.ifeq(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // } + // + // /** + // * Boolean generation for | + // */ + // public void generateOptimizedLogicalOr( + // BlockScope currentScope, + // CodeStream codeStream, + // Label trueLabel, + // Label falseLabel, + // boolean valueRequired) { + // + // Constant condConst; + // if ((left.implicitConversion & 0xF) == T_boolean) { + // if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { + // if (condConst.booleanValue() == true) { + // // | x + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // if (valueRequired) { + // if ((bits & OnlyValueRequiredMASK) != 0) { + // codeStream.iconst_1(); + // } else { + // if (trueLabel != null) { + // codeStream.goto_(trueLabel); + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // } else { + // // | x + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // if ((bits & OnlyValueRequiredMASK) != 0) { + // right.generateCode(currentScope, codeStream, valueRequired); + // } else { + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // } + // } + // return; + // } + // if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { + // if (condConst.booleanValue() == true) { + // // x | + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // if (valueRequired) { + // if ((bits & OnlyValueRequiredMASK) != 0) { + // codeStream.iconst_1(); + // } else { + // if (trueLabel != null) { + // codeStream.goto_(trueLabel); + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // } else { + // // x | + // if ((bits & OnlyValueRequiredMASK) != 0) { + // left.generateCode(currentScope, codeStream, valueRequired); + // } else { + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // } + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // } + // return; + // } + // } + // // default case + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // codeStream.ior(); + // if ((bits & OnlyValueRequiredMASK) == 0) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicit falling through the FALSE case + // codeStream.ifne(trueLabel); + // } + // } else { + // // implicit falling through the TRUE case + // if (trueLabel == null) { + // codeStream.ifeq(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // } + // + // /** + // * Boolean generation for ^ + // */ + // public void generateOptimizedLogicalXor( + // BlockScope currentScope, + // CodeStream codeStream, + // Label trueLabel, + // Label falseLabel, + // boolean valueRequired) { + // + // Constant condConst; + // if ((left.implicitConversion & 0xF) == T_boolean) { + // if ((condConst = left.optimizedBooleanConstant()) != NotAConstant) { + // if (condConst.booleanValue() == true) { + // // ^ x + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // falseLabel, + // trueLabel, + // valueRequired); + // } else { + // // ^ x + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // if ((bits & OnlyValueRequiredMASK) != 0) { + // right.generateCode(currentScope, codeStream, valueRequired); + // } else { + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // } + // } + // return; + // } + // if ((condConst = right.optimizedBooleanConstant()) != NotAConstant) { + // if (condConst.booleanValue() == true) { + // // x ^ + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // falseLabel, + // trueLabel, + // valueRequired); + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // } else { + // // x ^ + // if ((bits & OnlyValueRequiredMASK) != 0) { + // left.generateCode(currentScope, codeStream, valueRequired); + // } else { + // left.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // valueRequired); + // } + // right.generateOptimizedBoolean( + // currentScope, + // codeStream, + // trueLabel, + // falseLabel, + // false); + // } + // return; + // } + // } + // // default case + // left.generateCode(currentScope, codeStream, valueRequired); + // right.generateCode(currentScope, codeStream, valueRequired); + // if (valueRequired) { + // codeStream.ixor(); + // if ((bits & OnlyValueRequiredMASK) == 0) { + // if (falseLabel == null) { + // if (trueLabel != null) { + // // implicit falling through the FALSE case + // codeStream.ifne(trueLabel); + // } + // } else { + // // implicit falling through the TRUE case + // if (trueLabel == null) { + // codeStream.ifeq(falseLabel); + // } else { + // // no implicit fall through TRUE/FALSE --> should never occur + // } + // } + // } + // } + // // reposition the endPC + // codeStream.updateLastRecordedEndPC(codeStream.position); + // } + // + // public void generateOptimizedStringBuffer( + // BlockScope blockScope, + // CodeStream codeStream, + // int typeID) { + // + // /* In the case trying to make a string concatenation, there is no need to + // create a new + // * string buffer, thus use a lower-level API for code generation involving + // only the + // * appending of arguments to the existing StringBuffer + // */ + // + // if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) + // && ((bits & ReturnTypeIDMASK) == T_String)) { + // if (constant != NotAConstant) { + // codeStream.generateConstant(constant, implicitConversion); + // codeStream.invokeStringBufferAppendForType(implicitConversion & 0xF); + // } else { + // int pc = codeStream.position; + // left.generateOptimizedStringBuffer( + // blockScope, + // codeStream, + // left.implicitConversion & 0xF); + // codeStream.recordPositionsFrom(pc, left.sourceStart); + // pc = codeStream.position; + // right.generateOptimizedStringBuffer( + // blockScope, + // codeStream, + // right.implicitConversion & 0xF); + // codeStream.recordPositionsFrom(pc, right.sourceStart); + // } + // } else { + // super.generateOptimizedStringBuffer(blockScope, codeStream, typeID); + // } + // } + // + // public void generateOptimizedStringBufferCreation( + // BlockScope blockScope, + // CodeStream codeStream, + // int typeID) { + // + // /* In the case trying to make a string concatenation, there is no need to + // create a new + // * string buffer, thus use a lower-level API for code generation involving + // only the + // * appending of arguments to the existing StringBuffer + // */ + // + // if ((((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) + // && ((bits & ReturnTypeIDMASK) == T_String)) { + // if (constant != NotAConstant) { + // codeStream.newStringBuffer(); // new: java.lang.StringBuffer + // codeStream.dup(); + // codeStream.ldc(constant.stringValue()); + // codeStream.invokeStringBufferStringConstructor(); + // // invokespecial: java.lang.StringBuffer.(Ljava.lang.String;)V + // } else { + // int pc = codeStream.position; + // left.generateOptimizedStringBufferCreation( + // blockScope, + // codeStream, + // left.implicitConversion & 0xF); + // codeStream.recordPositionsFrom(pc, left.sourceStart); + // pc = codeStream.position; + // right.generateOptimizedStringBuffer( + // blockScope, + // codeStream, + // right.implicitConversion & 0xF); + // codeStream.recordPositionsFrom(pc, right.sourceStart); + // } + // } else { + // super.generateOptimizedStringBufferCreation(blockScope, codeStream, + // typeID); + // } + // } + // + // public boolean isCompactableOperation() { + // + // return true; + // } + // + // public void optimizedBooleanConstant(int leftId, int operator, int + // rightId) { + // + // switch (operator) { + // case AND : + // if ((leftId != T_boolean) || (rightId != T_boolean)) + // return; + // case AND_AND : + // Constant cst; + // if ((cst = left.optimizedBooleanConstant()) != NotAConstant) { + // if (cst.booleanValue() == false) { // left is equivalent to false + // optimizedBooleanConstant = cst; // constant(false) + // return; + // } else { //left is equivalent to true + // if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { + // optimizedBooleanConstant = cst; + // // the conditional result is equivalent to the right conditional value + // } + // return; + // } + // } + // if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { + // if (cst.booleanValue() == false) { // right is equivalent to false + // optimizedBooleanConstant = cst; // constant(false) + // } + // } + // return; + // case OR : + // if ((leftId != T_boolean) || (rightId != T_boolean)) + // return; + // case OR_OR : + // if ((cst = left.optimizedBooleanConstant()) != NotAConstant) { + // if (cst.booleanValue() == true) { // left is equivalent to true + // optimizedBooleanConstant = cst; // constant(true) + // return; + // } else { //left is equivalent to false + // if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { + // optimizedBooleanConstant = cst; + // } + // return; + // } + // } + // if ((cst = right.optimizedBooleanConstant()) != NotAConstant) { + // if (cst.booleanValue() == true) { // right is equivalent to true + // optimizedBooleanConstant = cst; // constant(true) + // } + // } + // } + // } + public StringBuffer printExpressionNoParenthesis(int indent, + StringBuffer output) { - left.printExpression(indent, output).append(' ').append(operatorToString()).append(' '); + left.printExpression(indent, output).append(' ').append( + operatorToString()).append(' '); return right.printExpression(0, output); } + public TypeBinding resolveType(BlockScope scope) { // use the id of the type to navigate into the table @@ -1659,8 +1669,8 @@ public class BinaryExpression extends OperatorExpression { } int leftId = leftTb.id; int rightId = rightTb.id; - if (leftId > 15 - || rightId > 15) { // must convert String + Object || Object + String + if (leftId > 15 || rightId > 15) { // must convert String + Object || + // Object + String if (leftId == T_String) { rightId = T_Object; } else if (rightId == T_String) { @@ -1673,78 +1683,81 @@ public class BinaryExpression extends OperatorExpression { } if (((bits & OperatorMASK) >> OperatorSHIFT) == PLUS) { if (leftId == T_String - && rightTb.isArrayType() - && ((ArrayBinding) rightTb).elementsType(scope) == CharBinding) - scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression( - right); - else if ( - rightId == T_String + && rightTb.isArrayType() + && ((ArrayBinding) rightTb).elementsType(scope) == CharBinding) + scope + .problemReporter() + .signalNoImplicitStringConversionForCharArrayExpression( + right); + else if (rightId == T_String && leftTb.isArrayType() && ((ArrayBinding) leftTb).elementsType(scope) == CharBinding) - scope.problemReporter().signalNoImplicitStringConversionForCharArrayExpression( - left); + scope + .problemReporter() + .signalNoImplicitStringConversionForCharArrayExpression( + left); } // the code is an int - // (cast) left Op (cast) rigth --> result - // 0000 0000 0000 0000 0000 - // <<16 <<12 <<8 <<4 <<0 + // (cast) left Op (cast) rigth --> result + // 0000 0000 0000 0000 0000 + // <<16 <<12 <<8 <<4 <<0 // Don't test for result = 0. If it is zero, some more work is done. - // On the one hand when it is not zero (correct code) we avoid doing the test - int result = - ResolveTypeTables[(bits & OperatorMASK) >> OperatorSHIFT][(leftId << 4) + // On the one hand when it is not zero (correct code) we avoid doing the + // test + int result = ResolveTypeTables[(bits & OperatorMASK) >> OperatorSHIFT][(leftId << 4) + rightId]; left.implicitConversion = result >>> 12; right.implicitConversion = (result >>> 4) & 0x000FF; bits |= result & 0xF; switch (result & 0xF) { // record the current ReturnTypeID - // only switch on possible result type..... - case T_boolean : - this.resolvedType = BooleanBinding; - break; - case T_byte : - this.resolvedType = ByteBinding; - break; - case T_char : - this.resolvedType = CharBinding; - break; - case T_double : - this.resolvedType = DoubleBinding; - break; - case T_float : - this.resolvedType = FloatBinding; - break; - case T_int : - this.resolvedType = IntBinding; - break; - case T_long : - this.resolvedType = LongBinding; - break; - case T_String : - this.resolvedType = scope.getJavaLangString(); - break; - default : //error........ - constant = Constant.NotAConstant; - scope.problemReporter().invalidOperator(this, leftTb, rightTb); - return null; + // only switch on possible result type..... + case T_boolean: + this.resolvedType = BooleanBinding; + break; + case T_byte: + this.resolvedType = ByteBinding; + break; + case T_char: + this.resolvedType = CharBinding; + break; + case T_double: + this.resolvedType = DoubleBinding; + break; + case T_float: + this.resolvedType = FloatBinding; + break; + case T_int: + this.resolvedType = IntBinding; + break; + case T_long: + this.resolvedType = LongBinding; + break; + case T_String: + this.resolvedType = scope.getJavaLangString(); + break; + default: // error........ + constant = Constant.NotAConstant; + scope.problemReporter().invalidOperator(this, leftTb, rightTb); + return null; } // compute the constant when valid computeConstant(scope, leftId, rightId); return this.resolvedType; } - + public String toStringExpressionNoParenthesis() { return left.toStringExpression() + " " + //$NON-NLS-1$ - operatorToString() + " " + //$NON-NLS-1$ - right.toStringExpression(); + operatorToString() + " " + //$NON-NLS-1$ + right.toStringExpression(); } public void traverse(ASTVisitor visitor, BlockScope scope) { - + if (visitor.visit(this, scope)) { left.traverse(visitor, scope); right.traverse(visitor, scope);