case Token::SAR:
if (left.is_smi()) return TypeInfo::Smi();
// Result is a smi if we shift by a constant >= 1, otherwise an integer32.
+ // Shift amount is masked with 0x1F (ECMA standard 11.7.2).
return (right.is_constant() && right.handle()->IsSmi()
- && Smi::cast(*right.handle())->value() >= 1)
+ && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
? TypeInfo::Smi()
: TypeInfo::Integer32();
case Token::SHR:
- // Result is a smi if we shift by a constant >= 2, otherwise an integer32.
- return (right.is_constant() && right.handle()->IsSmi()
- && Smi::cast(*right.handle())->value() >= 2)
- ? TypeInfo::Smi()
- : TypeInfo::Integer32();
+ // Result is a smi if we shift by a constant >= 2, an integer32 if
+ // we shift by 1, and an unsigned 32-bit integer if we shift by 0.
+ if (right.is_constant() && right.handle()->IsSmi()) {
+ int shift_amount = Smi::cast(*right.handle())->value() & 0x1F;
+ if (shift_amount > 1) {
+ return TypeInfo::Smi();
+ } else if (shift_amount > 0) {
+ return TypeInfo::Integer32();
+ }
+ }
+ return TypeInfo::Number();
case Token::ADD:
if (operands_type.IsSmi()) {
// The Integer32 range is big enough to take the sum of any two Smis.
result_type = TypeInfo::Smi();
break;
case Token::SHR:
- // Result of x >>> y is always a smi if y >= 1, otherwise a number.
+ // Result of x >>> y is always a smi if masked y >= 1, otherwise a number.
result_type = (right.is_constant() && right.handle()->IsSmi()
- && Smi::cast(*right.handle())->value() >= 1)
+ && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
? TypeInfo::Smi()
: TypeInfo::Number();
break;
function shiftByZero(n) { return n << 0; }
assertEquals(3, shiftByZero(3.1415));
+
+// Verify that the static type information of x >>> 32 is computed correctly.
+function LogicalShiftRightByMultipleOf32(x) {
+ x = x >>> 32;
+ return x + x;
+}
+
+assertEquals(4589934592, LogicalShiftRightByMultipleOf32(-2000000000));
+assertEquals(4589934592, LogicalShiftRightByMultipleOf32(-2000000000));