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/code_generator.h" // DartModulo. | 10 #include "vm/code_generator.h" // DartModulo. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 193 #endif | 193 #endif |
| 194 | 194 |
| 195 DEFINE_NATIVE_ENTRY(Double_toInt, 1) { | 195 DEFINE_NATIVE_ENTRY(Double_toInt, 1) { |
| 196 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 196 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 197 return DoubleToInteger(arg.value(), "Infinity or NaN toInt"); | 197 return DoubleToInteger(arg.value(), "Infinity or NaN toInt"); |
| 198 } | 198 } |
| 199 | 199 |
| 200 | 200 |
| 201 DEFINE_NATIVE_ENTRY(Double_parse, 1) { | 201 DEFINE_NATIVE_ENTRY(Double_parse, 1) { |
| 202 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); | 202 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); |
| 203 if (value.IsOneByteString()) { | |
| 204 // Quick conversion for unpadded doubles in strings. | |
| 205 const intptr_t len = value.Length(); | |
| 206 if (len > 0) { | |
| 207 const char* cstr = value.ToCString(); | |
| 208 ASSERT(cstr != NULL); | |
| 209 // Dart differences from strtod: | |
| 210 // a) '5.' is not a valid double (no digit after period). | |
| 211 // b) '+5.0' is not a valid double (leading plus). | |
| 212 if (cstr[0] != '+') { | |
| 213 bool dot_ok = true; | |
| 214 const char* tmp = cstr; | |
| 215 while (*tmp != '\0') { | |
| 216 const char ch = *tmp++; | |
| 217 if (ch == '.') { | |
| 218 const char nextCh = *tmp; | |
| 219 dot_ok = ('0' <= nextCh) && (nextCh <= '9'); | |
| 220 break; | |
| 221 } | |
| 222 } | |
| 223 if (dot_ok) { | |
| 224 double double_value; | |
| 225 if (CStringToDouble(cstr, len, &double_value)) { | |
| 226 return Double::New(double_value); | |
| 227 } | |
| 228 } | |
| 229 } | |
| 230 } | |
| 231 } | |
| 232 Scanner scanner(value, Symbols::Empty()); | |
| 233 const Scanner::GrowableTokenStream& tokens = scanner.GetStream(); | |
| 234 String* number_string; | |
| 235 bool is_positive; | |
| 236 if (Scanner::IsValidLiteral(tokens, | |
| 237 Token::kDOUBLE, | |
| 238 &is_positive, | |
| 239 &number_string)) { | |
| 240 // Even if original string was two byte string the scanner should produce | |
| 241 // literal value that is represented as a one byte string because all | |
| 242 // characters in the double literal are Latin-1. | |
| 243 ASSERT(number_string->IsOneByteString()); | |
| 244 const char* cstr = number_string->ToCString(); | |
| 245 | 203 |
| 246 double double_value; | 204 const intptr_t len = value.Length(); |
| 247 bool ok = CStringToDouble(cstr, number_string->Length(), &double_value); | |
| 248 ASSERT(ok); | |
| 249 | 205 |
| 250 if (!is_positive) { | 206 if (!value.IsOneByteString() || len == 0) { |
|
srdjan
2013/05/17 23:19:06
Please add parentheses.
floitsch
2013/05/20 13:15:29
Done.
| |
| 251 double_value = -double_value; | 207 return Object::null(); |
| 252 } | |
| 253 return Double::New(double_value); | |
| 254 } | 208 } |
| 255 | 209 |
| 256 if (Scanner::IsValidLiteral(tokens, | 210 double double_value; |
| 257 Token::kINTEGER, | 211 const char* cstr = value.ToCString(); |
| 258 &is_positive, | 212 ASSERT(cstr != NULL); |
| 259 &number_string)) { | 213 if (CStringToDouble(cstr, len, &double_value)) { |
| 260 Integer& res = Integer::Handle(Integer::New(*number_string)); | 214 return Double::New(double_value); |
| 261 if (is_positive) { | 215 } else { |
| 262 return Double::New(res.AsDoubleValue()); | 216 return Object::null(); |
| 263 } | |
| 264 return Double::New(-res.AsDoubleValue()); | |
| 265 } | 217 } |
| 266 | |
| 267 // Infinity and nan. | |
| 268 if (Scanner::IsValidLiteral(tokens, | |
| 269 Token::kIDENT, | |
| 270 &is_positive, | |
| 271 &number_string)) { | |
| 272 if (number_string->Equals("NaN")) { | |
| 273 return Double::New(NAN); | |
| 274 } | |
| 275 if (number_string->Equals("Infinity")) { | |
| 276 if (is_positive) { | |
| 277 return Double::New(INFINITY); | |
| 278 } | |
| 279 return Double::New(-INFINITY); | |
| 280 } | |
| 281 } | |
| 282 | |
| 283 const Array& args = Array::Handle(Array::New(1)); | |
| 284 args.SetAt(0, value); | |
| 285 Exceptions::ThrowByType(Exceptions::kFormat, args); | |
| 286 return Object::null(); | |
| 287 } | 218 } |
| 288 | 219 |
| 289 | 220 |
| 290 DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 2) { | 221 DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 2) { |
| 291 // The boundaries are exclusive. | 222 // The boundaries are exclusive. |
| 292 static const double kLowerBoundary = -1e21; | 223 static const double kLowerBoundary = -1e21; |
| 293 static const double kUpperBoundary = 1e21; | 224 static const double kUpperBoundary = 1e21; |
| 294 | 225 |
| 295 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 226 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 296 GET_NON_NULL_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1)); | 227 GET_NON_NULL_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1)); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 | 289 |
| 359 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { | 290 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { |
| 360 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 291 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
| 361 // Include negative zero, infinity. | 292 // Include negative zero, infinity. |
| 362 return Bool::Get(signbit(arg.value()) && !isnan(arg.value())); | 293 return Bool::Get(signbit(arg.value()) && !isnan(arg.value())); |
| 363 } | 294 } |
| 364 | 295 |
| 365 // Add here only functions using/referring to old-style casts. | 296 // Add here only functions using/referring to old-style casts. |
| 366 | 297 |
| 367 } // namespace dart | 298 } // namespace dart |
| OLD | NEW |