private Node tryFoldShift ( Node n , Node left , Node right ) { if ( left . isNumber ( ) && right . isNumber ( ) ) { double result ; double lval = left . getDouble ( ) ; double rval = right . getDouble ( ) ; // only the lower 5 bits are used when shifting, so don't do anything // if the shift amount is outside [0,32) if ( ! ( rval >= 0 && rval < 32 ) ) { return n ; } int rvalInt = ( int ) rval ; if ( rvalInt != rval ) { report ( FRACTIONAL_BITWISE_OPERAND , right ) ; return n ; } if ( Math . floor ( lval ) != lval ) { report ( FRACTIONAL_BITWISE_OPERAND , left ) ; return n ; } int bits = jsConvertDoubleToBits ( lval ) ; switch ( n . getToken ( ) ) { case LSH : result = bits << rvalInt ; break ; case RSH : result = bits >> rvalInt ; break ; case URSH : // JavaScript always treats the result of >>> as unsigned. // We must force Java to do the same here. result = 0xffffffff L & ( bits >>> rvalInt ) ; break ; default : throw new AssertionError ( "Unknown shift operator: " + n . getToken ( ) ) ; } Node newNumber = IR . number ( result ) ; reportChangeToEnclosingScope ( n ) ; n . replaceWith ( newNumber ) ; return newNumber ; } return n ; }
Try to fold shift operations