Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(943)

Side by Side Diff: runtime/lib/double.cc

Issue 509153003: New bigint implementation in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW
« runtime/lib/bigint.dart ('K') | « runtime/lib/date.cc ('k') | runtime/lib/double.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698