Chromium Code Reviews| Index: runtime/lib/double.cc |
| diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc |
| index 8c1a9a1e4ca6813181a3e0bc642e107d18d611ce..f22b72d36f8bdadd3b7050e97a5f90b6a8e5fbc0 100644 |
| --- a/runtime/lib/double.cc |
| +++ b/runtime/lib/double.cc |
| @@ -79,7 +79,20 @@ DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { |
| if (FLAG_trace_intrinsified_natives) { |
| OS::Print("Double_trunc_div %f ~/ %f\n", left, right); |
| } |
| - return Double::New(trunc(left / right)); |
| + double result = trunc(left / right); |
| + if (isinf(result) || isnan(result)) { |
|
floitsch
2013/01/03 18:23:17
From here on same as 'toInt' on the left (except t
|
| + const Array& args = Array::Handle(Array::New(1)); |
| + args.SetAt(0, String::Handle(String::New( |
| + "Result of truncating division is Infinity or NaN"))); |
| + Exceptions::ThrowByType(Exceptions::kFormat, args); |
|
Lasse Reichstein Nielsen
2013/01/04 10:29:42
Consider using UnsupportedError instead of FormatE
|
| + } |
| + if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { |
| + return Smi::New(static_cast<intptr_t>(result)); |
| + } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { |
| + return Mint::New(static_cast<int64_t>(result)); |
| + } else { |
| + return BigintOperations::NewFromDouble(result); |
| + } |
| } |
| @@ -151,23 +164,71 @@ DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) { |
| DEFINE_NATIVE_ENTRY(Double_round, 1) { |
| const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| - return Double::New(round(arg.value())); |
| + if (isinf(arg.value()) || isnan(arg.value())) { |
|
floitsch
2013/01/03 18:23:17
same as "toInt" on the left. Only change: error-me
Lasse Reichstein Nielsen
2013/01/04 10:29:42
Repeated code should be abstracted into a helper m
|
| + const Array& args = Array::Handle(Array::New(1)); |
| + args.SetAt(0, String::Handle(String::New("Infinity or NaN round"))); |
| + Exceptions::ThrowByType(Exceptions::kFormat, args); |
| + } |
| + double result = round(arg.value()); |
| + if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { |
| + return Smi::New(static_cast<intptr_t>(result)); |
| + } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { |
| + return Mint::New(static_cast<int64_t>(result)); |
| + } else { |
| + return BigintOperations::NewFromDouble(result); |
| + } |
| } |
| DEFINE_NATIVE_ENTRY(Double_floor, 1) { |
| const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| - return Double::New(floor(arg.value())); |
| + if (isinf(arg.value()) || isnan(arg.value())) { |
| + const Array& args = Array::Handle(Array::New(1)); |
| + args.SetAt(0, String::Handle(String::New("Infinity or NaN floor"))); |
| + Exceptions::ThrowByType(Exceptions::kFormat, args); |
| + } |
| + double result = floor(arg.value()); |
| + if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { |
| + return Smi::New(static_cast<intptr_t>(result)); |
| + } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { |
| + return Mint::New(static_cast<int64_t>(result)); |
| + } else { |
| + return BigintOperations::NewFromDouble(result); |
| + } |
| } |
| DEFINE_NATIVE_ENTRY(Double_ceil, 1) { |
| const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| - return Double::New(ceil(arg.value())); |
| + if (isinf(arg.value()) || isnan(arg.value())) { |
| + const Array& args = Array::Handle(Array::New(1)); |
| + args.SetAt(0, String::Handle(String::New("Infinity or NaN ceil"))); |
| + Exceptions::ThrowByType(Exceptions::kFormat, args); |
| + } |
| + double result = ceil(arg.value()); |
| + if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { |
| + return Smi::New(static_cast<intptr_t>(result)); |
| + } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { |
| + return Mint::New(static_cast<int64_t>(result)); |
| + } else { |
| + return BigintOperations::NewFromDouble(result); |
| + } |
| } |
| DEFINE_NATIVE_ENTRY(Double_truncate, 1) { |
| const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| - return Double::New(trunc(arg.value())); |
| + if (isinf(arg.value()) || isnan(arg.value())) { |
| + const Array& args = Array::Handle(Array::New(1)); |
| + args.SetAt(0, String::Handle(String::New("Infinity or NaN truncate"))); |
| + Exceptions::ThrowByType(Exceptions::kFormat, args); |
| + } |
| + double result = trunc(arg.value()); |
| + if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { |
| + return Smi::New(static_cast<intptr_t>(result)); |
| + } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { |
| + return Mint::New(static_cast<int64_t>(result)); |
| + } else { |
| + return BigintOperations::NewFromDouble(result); |
| + } |
| } |
| @@ -186,24 +247,6 @@ DEFINE_NATIVE_ENTRY(Double_pow, 2) { |
| #pragma GCC diagnostic ignored "-Wold-style-cast" |
| #endif |
| -DEFINE_NATIVE_ENTRY(Double_toInt, 1) { |
| - const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| - if (isinf(arg.value()) || isnan(arg.value())) { |
| - const Array& args = Array::Handle(Array::New(1)); |
| - args.SetAt(0, String::Handle(String::New("Infinity or NaN toInt"))); |
| - Exceptions::ThrowByType(Exceptions::kFormat, args); |
| - } |
| - double result = trunc(arg.value()); |
| - if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { |
| - return Smi::New(static_cast<intptr_t>(result)); |
| - } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { |
| - return Mint::New(static_cast<int64_t>(result)); |
| - } else { |
| - return BigintOperations::NewFromDouble(result); |
| - } |
| -} |
| - |
| - |
| DEFINE_NATIVE_ENTRY(Double_parse, 1) { |
| GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); |
| const String& dummy_key = String::Handle(Symbols::Empty()); |