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

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

Issue 821123003: Simplify double to bigint conversion. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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/code_generator.h" // DartModulo. 9 #include "vm/code_generator.h" // DartModulo.
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 return Double::New(left / right); 72 return Double::New(left / right);
73 } 73 }
74 74
75 75
76 static RawInteger* DoubleToInteger(double val, const char* error_msg) { 76 static RawInteger* DoubleToInteger(double val, const char* error_msg) {
77 if (isinf(val) || isnan(val)) { 77 if (isinf(val) || isnan(val)) {
78 const Array& args = Array::Handle(Array::New(1)); 78 const Array& args = Array::Handle(Array::New(1));
79 args.SetAt(0, String::Handle(String::New(error_msg))); 79 args.SetAt(0, String::Handle(String::New(error_msg)));
80 Exceptions::ThrowByType(Exceptions::kUnsupported, args); 80 Exceptions::ThrowByType(Exceptions::kUnsupported, args);
81 } 81 }
82 // TODO(regis): Should we implement Bigint::NewFromDouble instead?
83 if ((-1.0 < val) && (val < 1.0)) { 82 if ((-1.0 < val) && (val < 1.0)) {
84 return Smi::New(0); 83 return Smi::New(0);
85 } 84 }
86 DoubleInternals internals = DoubleInternals(val); 85 DoubleInternals internals = DoubleInternals(val);
87 if (internals.IsSpecial()) { 86 ASSERT(!internals.IsSpecial()); // Only Infinity and NaN are special.
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(); 87 uint64_t significand = internals.Significand();
94 intptr_t exponent = internals.Exponent(); 88 intptr_t exponent = internals.Exponent();
95 intptr_t sign = internals.Sign();
96 if (exponent <= 0) { 89 if (exponent <= 0) {
97 significand >>= -exponent; 90 significand >>= -exponent;
98 exponent = 0; 91 exponent = 0;
99 } else if (exponent <= 10) { 92 } else if (exponent <= 10) {
100 // A double significand has at most 53 bits. The following shift will 93 // 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. 94 // hence not overflow, and yield an integer of at most 63 bits.
102 significand <<= exponent; 95 significand <<= exponent;
103 exponent = 0; 96 exponent = 0;
104 } 97 }
105 // A significand has at most 63 bits (after the shift above). 98 // A significand has at most 63 bits (after the shift above).
106 // The cast to int64_t is hence safe. 99 // The cast to int64_t is hence safe.
100 int64_t ival = static_cast<int64_t>(significand);
101 if (internals.Sign() < 0) {
102 ival = -ival;
103 }
107 if (exponent == 0) { 104 if (exponent == 0) {
108 // The double fits in a Smi or Mint. 105 // 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); 106 return Integer::New(ival);
114 } 107 }
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(); 108 Integer& result = Integer::Handle();
136 result ^= DartEntry::InvokeFunction(factory_method, args); 109 result = Bigint::NewFromShiftedInt64(ival, exponent);
137 ASSERT(result.IsBigint());
138 return result.AsValidInteger(); 110 return result.AsValidInteger();
139 } 111 }
140 112
141 113
142 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { 114 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) {
143 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); 115 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
144 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); 116 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
145 double right = right_object.value(); 117 double right = right_object.value();
146 if (FLAG_trace_intrinsified_natives) { 118 if (FLAG_trace_intrinsified_natives) {
147 OS::Print("Double_trunc_div %f ~/ %f\n", left, right); 119 OS::Print("Double_trunc_div %f ~/ %f\n", left, right);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { 296 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) {
325 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); 297 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
326 // Include negative zero, infinity. 298 // Include negative zero, infinity.
327 double dval = arg.value(); 299 double dval = arg.value();
328 return Bool::Get(signbit(dval) && !isnan(dval)).raw(); 300 return Bool::Get(signbit(dval) && !isnan(dval)).raw();
329 } 301 }
330 302
331 // Add here only functions using/referring to old-style casts. 303 // Add here only functions using/referring to old-style casts.
332 304
333 } // namespace dart 305 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698