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" |
11 #include "vm/exceptions.h" | 11 #include "vm/exceptions.h" |
12 #include "vm/native_entry.h" | 12 #include "vm/native_entry.h" |
13 #include "vm/object.h" | 13 #include "vm/object.h" |
| 14 #include "vm/symbols.h" |
14 | 15 |
15 namespace dart { | 16 namespace dart { |
16 | 17 |
17 DECLARE_FLAG(bool, trace_intrinsified_natives); | 18 DECLARE_FLAG(bool, trace_intrinsified_natives); |
18 | 19 |
19 DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) { | 20 DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) { |
20 ASSERT(AbstractTypeArguments::CheckedHandle( | 21 ASSERT(AbstractTypeArguments::CheckedHandle( |
21 arguments->NativeArgAt(0)).IsNull()); | 22 arguments->NativeArgAt(0)).IsNull()); |
22 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(1)); | 23 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(1)); |
23 if (FLAG_trace_intrinsified_natives) { | 24 if (FLAG_trace_intrinsified_natives) { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { | 196 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { |
196 return Smi::New(static_cast<intptr_t>(result)); | 197 return Smi::New(static_cast<intptr_t>(result)); |
197 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { | 198 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { |
198 return Mint::New(static_cast<int64_t>(result)); | 199 return Mint::New(static_cast<int64_t>(result)); |
199 } else { | 200 } else { |
200 return BigintOperations::NewFromDouble(result); | 201 return BigintOperations::NewFromDouble(result); |
201 } | 202 } |
202 } | 203 } |
203 | 204 |
204 | 205 |
| 206 DEFINE_NATIVE_ENTRY(Double_parse, 1) { |
| 207 GET_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); |
| 208 const String& dummy_key = String::Handle(Symbols::Empty()); |
| 209 Scanner scanner(value, dummy_key); |
| 210 const Scanner::GrowableTokenStream& tokens = scanner.GetStream(); |
| 211 String* number_string; |
| 212 bool is_positive; |
| 213 if (Scanner::IsValidLiteral(tokens, |
| 214 Token::kDOUBLE, |
| 215 &is_positive, |
| 216 &number_string)) { |
| 217 const char* cstr = number_string->ToCString(); |
| 218 char* p_end = NULL; |
| 219 double double_value = strtod(cstr, &p_end); |
| 220 ASSERT(p_end != cstr); |
| 221 if (!is_positive) { |
| 222 double_value = -double_value; |
| 223 } |
| 224 return Double::New(double_value); |
| 225 } |
| 226 |
| 227 if (Scanner::IsValidLiteral(tokens, |
| 228 Token::kINTEGER, |
| 229 &is_positive, |
| 230 &number_string)) { |
| 231 Integer& res = Integer::Handle(Integer::New(*number_string)); |
| 232 if (is_positive) { |
| 233 return Double::New(res.AsDoubleValue()); |
| 234 } |
| 235 return Double::New(-res.AsDoubleValue()); |
| 236 } |
| 237 |
| 238 // Infinity and nan. |
| 239 if (Scanner::IsValidLiteral(tokens, |
| 240 Token::kIDENT, |
| 241 &is_positive, |
| 242 &number_string)) { |
| 243 if (number_string->Equals("NaN")) { |
| 244 return Double::New(NAN); |
| 245 } |
| 246 if (number_string->Equals("Infinity")) { |
| 247 if (is_positive) { |
| 248 return Double::New(INFINITY); |
| 249 } |
| 250 return Double::New(-INFINITY); |
| 251 } |
| 252 } |
| 253 |
| 254 GrowableArray<const Object*> args; |
| 255 args.Add(&value); |
| 256 Exceptions::ThrowByType(Exceptions::kFormat, args); |
| 257 return Object::null(); |
| 258 } |
| 259 |
| 260 |
205 DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 2) { | 261 DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 2) { |
206 // The boundaries are exclusive. | 262 // The boundaries are exclusive. |
207 static const double kLowerBoundary = -1e21; | 263 static const double kLowerBoundary = -1e21; |
208 static const double kUpperBoundary = 1e21; | 264 static const double kUpperBoundary = 1e21; |
209 | 265 |
210 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 266 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
211 GET_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1)); | 267 GET_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1)); |
212 double d = arg.value(); | 268 double d = arg.value(); |
213 intptr_t fraction_digits_value = fraction_digits.Value(); | 269 intptr_t fraction_digits_value = fraction_digits.Value(); |
214 if (0 <= fraction_digits_value && fraction_digits_value <= 20 | 270 if (0 <= fraction_digits_value && fraction_digits_value <= 20 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 329 |
274 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { | 330 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { |
275 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 331 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); |
276 // Include negative zero, infinity. | 332 // Include negative zero, infinity. |
277 return Bool::Get(signbit(arg.value()) && !isnan(arg.value())); | 333 return Bool::Get(signbit(arg.value()) && !isnan(arg.value())); |
278 } | 334 } |
279 | 335 |
280 // Add here only functions using/referring to old-style casts. | 336 // Add here only functions using/referring to old-style casts. |
281 | 337 |
282 } // namespace dart | 338 } // namespace dart |
OLD | NEW |