Index: runtime/lib/integers.cc |
=================================================================== |
--- runtime/lib/integers.cc (revision 2547) |
+++ runtime/lib/integers.cc (working copy) |
@@ -203,7 +203,7 @@ |
// The result is invalid if it is outside the range |
-// Smi::kMaxValue..Smi::kMinValue. |
+// Smi::kMinValue..Smi::kMaxValue. |
static int64_t BinaryOpWithTwoSmis(Token::Kind operation, |
const Smi& left, |
const Smi& right) { |
@@ -213,16 +213,18 @@ |
case Token::kSUB: |
return left.Value() - right.Value(); |
case Token::kMUL: { |
-#if defined(TARGET_ARCH_X64) |
- // Overflow check for 64-bit platforms unimplemented. |
- UNIMPLEMENTED(); |
- return 0; |
-#else |
- int64_t result_64 = |
- static_cast<int64_t>(left.Value()) * |
- static_cast<int64_t>(right.Value()); |
- return result_64; |
-#endif |
+ const Bigint& big_left = |
cshapiro
2011/12/17 00:09:44
This needs a TODO since it may cause a performance
regis
2011/12/17 00:47:44
Done.
|
+ Bigint::Handle(BigintOperations::NewFromSmi(left)); |
+ const Bigint& big_right = |
+ Bigint::Handle(BigintOperations::NewFromSmi(right)); |
+ const Bigint& big_result = |
+ Bigint::Handle(BigintOperations::Multiply(big_left, big_right)); |
+ if (BigintOperations::FitsIntoInt64(big_result)) { |
+ return BigintOperations::ToInt64(big_result); |
+ } else { |
+ // Overflow, return an invalid Smi. |
+ return Smi::kMaxValue + 1; |
+ } |
} |
case Token::kTRUNCDIV: |
return left.Value() / right.Value(); |
@@ -285,8 +287,14 @@ |
if (Smi::IsValid64(result)) { |
return Smi::New(result); |
} else { |
+ // TODO(regis): This is not going to work on x64. Check other operations. |
+#if defined(TARGET_ARCH_X64) |
+ UNIMPLEMENTED(); |
+ return 0; |
+#else |
// Overflow to Mint. |
return Mint::New(result); |
+#endif |
} |
} else if (AreBoth64bitOperands(left_int, right_int)) { |
// TODO(srdjan): Test for overflow of result instead of operand |