Fix error in static type information computation for bitwise shift.

Review URL: http://codereview.chromium.org/1756007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4471 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
whesse@chromium.org 2010-04-22 09:02:10 +00:00
parent 49d685684a
commit 5db2af4873
3 changed files with 24 additions and 8 deletions

View File

@ -1180,16 +1180,23 @@ static TypeInfo CalculateTypeInfo(TypeInfo operands_type,
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.

View File

@ -5840,9 +5840,9 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op,
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;

View File

@ -669,3 +669,12 @@ intConversion();
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));