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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: runtime/lib/double.cc
===================================================================
--- runtime/lib/double.cc (revision 40060)
+++ runtime/lib/double.cc (working copy)
@@ -6,9 +6,10 @@
#include "platform/math.h"
-#include "vm/bigint_operations.h"
#include "vm/code_generator.h" // DartModulo.
+#include "vm/dart_entry.h"
#include "vm/double_conversion.h"
+#include "vm/double_internals.h"
#include "vm/exceptions.h"
#include "vm/native_entry.h"
#include "vm/object.h"
@@ -78,8 +79,63 @@
args.SetAt(0, String::Handle(String::New(error_msg)));
Exceptions::ThrowByType(Exceptions::kUnsupported, args);
}
- const Bigint& big = Bigint::Handle(BigintOperations::NewFromDouble(val));
- return big.AsValidInteger();
+ // TODO(regis): Should we implement Bigint::NewFromDouble instead?
+ if ((-1.0 < val) && (val < 1.0)) {
+ return Smi::New(0);
+ }
+ DoubleInternals internals = DoubleInternals(val);
+ if (internals.IsSpecial()) {
+ const Array& exception_arguments = Array::Handle(Array::New(1));
+ exception_arguments.SetAt(
+ 0, Object::Handle(String::New("BigintOperations::NewFromDouble")));
+ Exceptions::ThrowByType(Exceptions::kInternalError, exception_arguments);
+ }
+ uint64_t significand = internals.Significand();
+ intptr_t exponent = internals.Exponent();
+ intptr_t sign = internals.Sign();
+ if (exponent <= 0) {
+ significand >>= -exponent;
+ exponent = 0;
+ } else if (exponent <= 10) {
+ // A double significand has at most 53 bits. The following shift will
+ // hence not overflow, and yield an integer of at most 63 bits.
+ significand <<= exponent;
+ exponent = 0;
+ }
+ // A significand has at most 63 bits (after the shift above).
+ // The cast to int64_t is hence safe.
+ if (exponent == 0) {
+ // The double fits in a Smi or Mint.
+ int64_t ival = static_cast<int64_t>(significand);
+ if (sign < 0) {
+ ival = -ival;
+ }
+ return Integer::New(ival);
+ }
+ // Lookup the factory creating a Bigint from a double.
+ const Class& bigint_class =
+ Class::Handle(Library::LookupCoreClass(Symbols::_Bigint()));
+ ASSERT(!bigint_class.IsNull());
+ const Function& factory_method = Function::Handle(
+ bigint_class.LookupFactoryAllowPrivate(
+ Symbols::_BigintFromDoubleFactory()));
+ ASSERT(!factory_method.IsNull());
+
+ // Create the argument list.
+ const intptr_t kNumArgs = 4;
+ const Array& args = Array::Handle(Array::New(kNumArgs));
+ // Factories get type arguments.
+ args.SetAt(0, Object::null_type_arguments());
+ args.SetAt(1, Smi::Handle(Smi::New(sign)));
+ args.SetAt(2,
+ Integer::Handle(Integer::New(static_cast<int64_t>(significand))));
+ args.SetAt(3, Integer::Handle(Integer::New(exponent)));
+
+ // Invoke the constructor and return the new object.
+ Integer& result = Integer::Handle();
+ result ^= DartEntry::InvokeFunction(factory_method, args);
+ ASSERT(result.IsBigint());
+ return result.AsValidInteger();
}
« 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