| 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 "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" | 
| 6 | 6 | 
| 7 #include "platform/math.h" | 7 #include "platform/math.h" | 
| 8 | 8 | 
| 9 #include "vm/bigint_operations.h" |  | 
| 10 #include "vm/code_generator.h"  // DartModulo. | 9 #include "vm/code_generator.h"  // DartModulo. | 
|  | 10 #include "vm/dart_entry.h" | 
| 11 #include "vm/double_conversion.h" | 11 #include "vm/double_conversion.h" | 
|  | 12 #include "vm/double_internals.h" | 
| 12 #include "vm/exceptions.h" | 13 #include "vm/exceptions.h" | 
| 13 #include "vm/native_entry.h" | 14 #include "vm/native_entry.h" | 
| 14 #include "vm/object.h" | 15 #include "vm/object.h" | 
| 15 #include "vm/symbols.h" | 16 #include "vm/symbols.h" | 
| 16 | 17 | 
| 17 namespace dart { | 18 namespace dart { | 
| 18 | 19 | 
| 19 DECLARE_FLAG(bool, trace_intrinsified_natives); | 20 DECLARE_FLAG(bool, trace_intrinsified_natives); | 
| 20 | 21 | 
| 21 DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) { | 22 DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) { | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 71   return Double::New(left / right); | 72   return Double::New(left / right); | 
| 72 } | 73 } | 
| 73 | 74 | 
| 74 | 75 | 
| 75 static RawInteger* DoubleToInteger(double val, const char* error_msg) { | 76 static RawInteger* DoubleToInteger(double val, const char* error_msg) { | 
| 76   if (isinf(val) || isnan(val)) { | 77   if (isinf(val) || isnan(val)) { | 
| 77     const Array& args = Array::Handle(Array::New(1)); | 78     const Array& args = Array::Handle(Array::New(1)); | 
| 78     args.SetAt(0, String::Handle(String::New(error_msg))); | 79     args.SetAt(0, String::Handle(String::New(error_msg))); | 
| 79     Exceptions::ThrowByType(Exceptions::kUnsupported, args); | 80     Exceptions::ThrowByType(Exceptions::kUnsupported, args); | 
| 80   } | 81   } | 
| 81   const Bigint& big = Bigint::Handle(BigintOperations::NewFromDouble(val)); | 82   // TODO(regis): Should we implement Bigint::NewFromDouble instead? | 
| 82   return big.AsValidInteger(); | 83   if ((-1.0 < val) && (val < 1.0)) { | 
|  | 84     return Smi::New(0); | 
|  | 85   } | 
|  | 86   DoubleInternals internals = DoubleInternals(val); | 
|  | 87   if (internals.IsSpecial()) { | 
|  | 88     const Array& exception_arguments = Array::Handle(Array::New(1)); | 
|  | 89     exception_arguments.SetAt( | 
|  | 90         0, Object::Handle(String::New("BigintOperations::NewFromDouble"))); | 
|  | 91     Exceptions::ThrowByType(Exceptions::kInternalError, exception_arguments); | 
|  | 92   } | 
|  | 93   uint64_t significand = internals.Significand(); | 
|  | 94   intptr_t exponent = internals.Exponent(); | 
|  | 95   intptr_t sign = internals.Sign(); | 
|  | 96   if (exponent <= 0) { | 
|  | 97     significand >>= -exponent; | 
|  | 98     exponent = 0; | 
|  | 99   } else if (exponent <= 10) { | 
|  | 100     // A double significand has at most 53 bits. The following shift will | 
|  | 101     // hence not overflow, and yield an integer of at most 63 bits. | 
|  | 102     significand <<= exponent; | 
|  | 103     exponent = 0; | 
|  | 104   } | 
|  | 105   // A significand has at most 63 bits (after the shift above). | 
|  | 106   // The cast to int64_t is hence safe. | 
|  | 107   if (exponent == 0) { | 
|  | 108     // The double fits in a Smi or Mint. | 
|  | 109     int64_t ival = static_cast<int64_t>(significand); | 
|  | 110     if (sign < 0) { | 
|  | 111       ival = -ival; | 
|  | 112     } | 
|  | 113     return Integer::New(ival); | 
|  | 114   } | 
|  | 115   // Lookup the factory creating a Bigint from a double. | 
|  | 116   const Class& bigint_class = | 
|  | 117       Class::Handle(Library::LookupCoreClass(Symbols::_Bigint())); | 
|  | 118   ASSERT(!bigint_class.IsNull()); | 
|  | 119   const Function& factory_method = Function::Handle( | 
|  | 120       bigint_class.LookupFactoryAllowPrivate( | 
|  | 121           Symbols::_BigintFromDoubleFactory())); | 
|  | 122   ASSERT(!factory_method.IsNull()); | 
|  | 123 | 
|  | 124   // Create the argument list. | 
|  | 125   const intptr_t kNumArgs = 4; | 
|  | 126   const Array& args = Array::Handle(Array::New(kNumArgs)); | 
|  | 127   // Factories get type arguments. | 
|  | 128   args.SetAt(0, Object::null_type_arguments()); | 
|  | 129   args.SetAt(1, Smi::Handle(Smi::New(sign))); | 
|  | 130   args.SetAt(2, | 
|  | 131              Integer::Handle(Integer::New(static_cast<int64_t>(significand)))); | 
|  | 132   args.SetAt(3, Integer::Handle(Integer::New(exponent))); | 
|  | 133 | 
|  | 134   // Invoke the constructor and return the new object. | 
|  | 135   Integer& result = Integer::Handle(); | 
|  | 136   result ^= DartEntry::InvokeFunction(factory_method, args); | 
|  | 137   ASSERT(result.IsBigint()); | 
|  | 138   return result.AsValidInteger(); | 
| 83 } | 139 } | 
| 84 | 140 | 
| 85 | 141 | 
| 86 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { | 142 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { | 
| 87   double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); | 143   double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); | 
| 88   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); | 144   GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); | 
| 89   double right = right_object.value(); | 145   double right = right_object.value(); | 
| 90   if (FLAG_trace_intrinsified_natives) { | 146   if (FLAG_trace_intrinsified_natives) { | 
| 91     OS::Print("Double_trunc_div %f ~/ %f\n", left, right); | 147     OS::Print("Double_trunc_div %f ~/ %f\n", left, right); | 
| 92   } | 148   } | 
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 268 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { | 324 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { | 
| 269   const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 325   const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); | 
| 270   // Include negative zero, infinity. | 326   // Include negative zero, infinity. | 
| 271   double dval = arg.value(); | 327   double dval = arg.value(); | 
| 272   return Bool::Get(signbit(dval) && !isnan(dval)).raw(); | 328   return Bool::Get(signbit(dval) && !isnan(dval)).raw(); | 
| 273 } | 329 } | 
| 274 | 330 | 
| 275 // Add here only functions using/referring to old-style casts. | 331 // Add here only functions using/referring to old-style casts. | 
| 276 | 332 | 
| 277 }  // namespace dart | 333 }  // namespace dart | 
| OLD | NEW | 
|---|