Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <math.h> | 5 #include <math.h> |
| 6 | 6 |
| 7 #include "vm/bootstrap_natives.h" | 7 #include "vm/bootstrap_natives.h" |
| 8 | 8 |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/double_conversion.h" | 10 #include "vm/double_conversion.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 } | 72 } |
| 73 | 73 |
| 74 | 74 |
| 75 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { | 75 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { |
| 76 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); | 76 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); |
| 77 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); | 77 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); |
| 78 double right = right_object.value(); | 78 double right = right_object.value(); |
| 79 if (FLAG_trace_intrinsified_natives) { | 79 if (FLAG_trace_intrinsified_natives) { |
| 80 OS::Print("Double_trunc_div %f ~/ %f\n", left, right); | 80 OS::Print("Double_trunc_div %f ~/ %f\n", left, right); |
| 81 } | 81 } |
| 82 return Double::New(trunc(left / right)); | 82 double result = trunc(left / right); |
| 83 if (isinf(result) || isnan(result)) { | |
|
floitsch
2013/01/03 18:23:17
From here on same as 'toInt' on the left (except t
| |
| 84 const Array& args = Array::Handle(Array::New(1)); | |
| 85 args.SetAt(0, String::Handle(String::New( | |
| 86 "Result of truncating division is Infinity or NaN"))); | |
| 87 Exceptions::ThrowByType(Exceptions::kFormat, args); | |
|
Lasse Reichstein Nielsen
2013/01/04 10:29:42
Consider using UnsupportedError instead of FormatE
| |
| 88 } | |
| 89 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { | |
| 90 return Smi::New(static_cast<intptr_t>(result)); | |
| 91 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { | |
| 92 return Mint::New(static_cast<int64_t>(result)); | |
| 93 } else { | |
| 94 return BigintOperations::NewFromDouble(result); | |
| 95 } | |
| 83 } | 96 } |
| 84 | 97 |
| 85 | 98 |
| 86 DEFINE_NATIVE_ENTRY(Double_modulo, 2) { | 99 DEFINE_NATIVE_ENTRY(Double_modulo, 2) { |
| 87 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); | 100 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); |
| 88 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); | 101 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); |
| 89 double right = right_object.value(); | 102 double right = right_object.value(); |
| 90 | 103 |
| 91 double remainder = fmod_ieee(left, right); | 104 double remainder = fmod_ieee(left, right); |
| 92 if (remainder == 0.0) { | 105 if (remainder == 0.0) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 | 157 |
| 145 DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) { | 158 DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) { |
| 146 const Double& left = Double::CheckedHandle(arguments->NativeArgAt(0)); | 159 const Double& left = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 147 GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1)); | 160 GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1)); |
| 148 return Bool::Get(left.value() == right.AsDoubleValue()); | 161 return Bool::Get(left.value() == right.AsDoubleValue()); |
| 149 } | 162 } |
| 150 | 163 |
| 151 | 164 |
| 152 DEFINE_NATIVE_ENTRY(Double_round, 1) { | 165 DEFINE_NATIVE_ENTRY(Double_round, 1) { |
| 153 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 166 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 154 return Double::New(round(arg.value())); | 167 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
| |
| 168 const Array& args = Array::Handle(Array::New(1)); | |
| 169 args.SetAt(0, String::Handle(String::New("Infinity or NaN round"))); | |
| 170 Exceptions::ThrowByType(Exceptions::kFormat, args); | |
| 171 } | |
| 172 double result = round(arg.value()); | |
| 173 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { | |
| 174 return Smi::New(static_cast<intptr_t>(result)); | |
| 175 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { | |
| 176 return Mint::New(static_cast<int64_t>(result)); | |
| 177 } else { | |
| 178 return BigintOperations::NewFromDouble(result); | |
| 179 } | |
| 155 } | 180 } |
| 156 | 181 |
| 157 DEFINE_NATIVE_ENTRY(Double_floor, 1) { | 182 DEFINE_NATIVE_ENTRY(Double_floor, 1) { |
| 158 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 183 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 159 return Double::New(floor(arg.value())); | 184 if (isinf(arg.value()) || isnan(arg.value())) { |
| 185 const Array& args = Array::Handle(Array::New(1)); | |
| 186 args.SetAt(0, String::Handle(String::New("Infinity or NaN floor"))); | |
| 187 Exceptions::ThrowByType(Exceptions::kFormat, args); | |
| 188 } | |
| 189 double result = floor(arg.value()); | |
| 190 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { | |
| 191 return Smi::New(static_cast<intptr_t>(result)); | |
| 192 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { | |
| 193 return Mint::New(static_cast<int64_t>(result)); | |
| 194 } else { | |
| 195 return BigintOperations::NewFromDouble(result); | |
| 196 } | |
| 160 } | 197 } |
| 161 | 198 |
| 162 DEFINE_NATIVE_ENTRY(Double_ceil, 1) { | 199 DEFINE_NATIVE_ENTRY(Double_ceil, 1) { |
| 163 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 200 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 164 return Double::New(ceil(arg.value())); | 201 if (isinf(arg.value()) || isnan(arg.value())) { |
| 202 const Array& args = Array::Handle(Array::New(1)); | |
| 203 args.SetAt(0, String::Handle(String::New("Infinity or NaN ceil"))); | |
| 204 Exceptions::ThrowByType(Exceptions::kFormat, args); | |
| 205 } | |
| 206 double result = ceil(arg.value()); | |
| 207 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { | |
| 208 return Smi::New(static_cast<intptr_t>(result)); | |
| 209 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { | |
| 210 return Mint::New(static_cast<int64_t>(result)); | |
| 211 } else { | |
| 212 return BigintOperations::NewFromDouble(result); | |
| 213 } | |
| 165 } | 214 } |
| 166 | 215 |
| 167 | 216 |
| 168 DEFINE_NATIVE_ENTRY(Double_truncate, 1) { | 217 DEFINE_NATIVE_ENTRY(Double_truncate, 1) { |
| 169 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 218 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 170 return Double::New(trunc(arg.value())); | 219 if (isinf(arg.value()) || isnan(arg.value())) { |
| 220 const Array& args = Array::Handle(Array::New(1)); | |
| 221 args.SetAt(0, String::Handle(String::New("Infinity or NaN truncate"))); | |
| 222 Exceptions::ThrowByType(Exceptions::kFormat, args); | |
| 223 } | |
| 224 double result = trunc(arg.value()); | |
| 225 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { | |
| 226 return Smi::New(static_cast<intptr_t>(result)); | |
| 227 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { | |
| 228 return Mint::New(static_cast<int64_t>(result)); | |
| 229 } else { | |
| 230 return BigintOperations::NewFromDouble(result); | |
| 231 } | |
| 171 } | 232 } |
| 172 | 233 |
| 173 | 234 |
| 174 DEFINE_NATIVE_ENTRY(Double_pow, 2) { | 235 DEFINE_NATIVE_ENTRY(Double_pow, 2) { |
| 175 const double operand = | 236 const double operand = |
| 176 Double::CheckedHandle(arguments->NativeArgAt(0)).value(); | 237 Double::CheckedHandle(arguments->NativeArgAt(0)).value(); |
| 177 GET_NON_NULL_NATIVE_ARGUMENT( | 238 GET_NON_NULL_NATIVE_ARGUMENT( |
| 178 Double, exponent_object, arguments->NativeArgAt(1)); | 239 Double, exponent_object, arguments->NativeArgAt(1)); |
| 179 const double exponent = exponent_object.value(); | 240 const double exponent = exponent_object.value(); |
| 180 return Double::New(pow(operand, exponent)); | 241 return Double::New(pow(operand, exponent)); |
| 181 } | 242 } |
| 182 | 243 |
| 183 | 244 |
| 184 #if defined(TARGET_OS_MACOS) | 245 #if defined(TARGET_OS_MACOS) |
| 185 // MAC OSX math library produces old style cast warning. | 246 // MAC OSX math library produces old style cast warning. |
| 186 #pragma GCC diagnostic ignored "-Wold-style-cast" | 247 #pragma GCC diagnostic ignored "-Wold-style-cast" |
| 187 #endif | 248 #endif |
| 188 | 249 |
| 189 DEFINE_NATIVE_ENTRY(Double_toInt, 1) { | |
| 190 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | |
| 191 if (isinf(arg.value()) || isnan(arg.value())) { | |
| 192 const Array& args = Array::Handle(Array::New(1)); | |
| 193 args.SetAt(0, String::Handle(String::New("Infinity or NaN toInt"))); | |
| 194 Exceptions::ThrowByType(Exceptions::kFormat, args); | |
| 195 } | |
| 196 double result = trunc(arg.value()); | |
| 197 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { | |
| 198 return Smi::New(static_cast<intptr_t>(result)); | |
| 199 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { | |
| 200 return Mint::New(static_cast<int64_t>(result)); | |
| 201 } else { | |
| 202 return BigintOperations::NewFromDouble(result); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 | |
| 207 DEFINE_NATIVE_ENTRY(Double_parse, 1) { | 250 DEFINE_NATIVE_ENTRY(Double_parse, 1) { |
| 208 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); | 251 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); |
| 209 const String& dummy_key = String::Handle(Symbols::Empty()); | 252 const String& dummy_key = String::Handle(Symbols::Empty()); |
| 210 Scanner scanner(value, dummy_key); | 253 Scanner scanner(value, dummy_key); |
| 211 const Scanner::GrowableTokenStream& tokens = scanner.GetStream(); | 254 const Scanner::GrowableTokenStream& tokens = scanner.GetStream(); |
| 212 String* number_string; | 255 String* number_string; |
| 213 bool is_positive; | 256 bool is_positive; |
| 214 if (Scanner::IsValidLiteral(tokens, | 257 if (Scanner::IsValidLiteral(tokens, |
| 215 Token::kDOUBLE, | 258 Token::kDOUBLE, |
| 216 &is_positive, | 259 &is_positive, |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 | 373 |
| 331 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { | 374 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { |
| 332 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 375 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 333 // Include negative zero, infinity. | 376 // Include negative zero, infinity. |
| 334 return Bool::Get(signbit(arg.value()) && !isnan(arg.value())); | 377 return Bool::Get(signbit(arg.value()) && !isnan(arg.value())); |
| 335 } | 378 } |
| 336 | 379 |
| 337 // Add here only functions using/referring to old-style casts. | 380 // Add here only functions using/referring to old-style casts. |
| 338 | 381 |
| 339 } // namespace dart | 382 } // namespace dart |
| OLD | NEW |