Chromium Code Reviews| Index: runtime/vm/object.cc |
| =================================================================== |
| --- runtime/vm/object.cc (revision 23187) |
| +++ runtime/vm/object.cc (working copy) |
| @@ -50,6 +50,8 @@ |
| "Huge method cutoff in tokens: Disables optimizations for huge methods."); |
| DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, |
| "Huge method cutoff in unoptimized code size (in bytes)."); |
| +DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, |
| + "Throw an exception when integer arithmetic exceeds 53 bits."); |
| DECLARE_FLAG(bool, trace_compiler); |
| DECLARE_FLAG(bool, eliminate_type_checks); |
| DECLARE_FLAG(bool, enable_type_checks); |
| @@ -10438,16 +10440,30 @@ |
| } |
| +// Throw FiftyThreeBitOverflow exception. |
| +static void ThrowFiftyThreeBitOverflow() { |
| + const Array& exc_args = Array::Handle(Array::New(0)); |
| + Exceptions::ThrowByType(Exceptions::kFiftyThreeBitOverflowError, exc_args); |
| + return; |
|
srdjan
2013/05/28 10:57:14
remove return.
zra
2013/05/28 17:06:39
Done.
|
| +} |
| + |
| + |
| RawInteger* Integer::New(int64_t value, Heap::Space space) { |
| if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { |
| return Smi::New(value); |
| } |
| + if (FLAG_throw_on_javascript_int_overflow && !Utils::IsInt(53, value)) { |
| + ThrowFiftyThreeBitOverflow(); |
| + } |
| return Mint::New(value, space); |
| } |
| RawInteger* Integer::NewFromUint64(uint64_t value, Heap::Space space) { |
| if (value > static_cast<uint64_t>(Mint::kMaxValue)) { |
| + if (FLAG_throw_on_javascript_int_overflow) { |
| + ThrowFiftyThreeBitOverflow(); |
| + } |
| return BigintOperations::NewFromUint64(value); |
| } else { |
| return Integer::New(value); |
| @@ -10473,7 +10489,33 @@ |
| } |
| +static void CheckFiftyThreeBitOverflow(const Integer &i) { |
|
srdjan
2013/05/28 10:57:14
Optional: The code would be simpler if you have Th
zra
2013/05/28 17:06:39
I gave this a shot. Please let me know if it looks
|
| + if (i.IsSmi()) return; |
| + if (i.IsMint()) { |
| + Mint& mint = Mint::Handle(); |
| + mint ^= i.raw(); |
| + if (!Utils::IsInt(53, mint.value())) { |
| + ThrowFiftyThreeBitOverflow(); |
| + } |
| + return; |
| + } |
| + ASSERT(i.IsBigint()); |
| + Bigint& big_value = Bigint::Handle(); |
| + big_value ^= i.raw(); |
| + if (BigintOperations::FitsIntoInt64(big_value)) { |
| + if (!Utils::IsInt(53, BigintOperations::ToInt64(big_value))) { |
| + ThrowFiftyThreeBitOverflow(); |
| + } |
| + } else { |
| + ThrowFiftyThreeBitOverflow(); |
| + } |
| +} |
| + |
| + |
| RawInteger* Integer::AsValidInteger() const { |
| + if (FLAG_throw_on_javascript_int_overflow) { |
| + CheckFiftyThreeBitOverflow(*this); |
| + } |
| if (IsSmi()) return raw(); |
| if (IsMint()) { |
| Mint& mint = Mint::Handle(); |