diff --git a/runtime/lib/double.cc b/runtime/lib/double.cc index 04006e5178b..f69e96328fa 100644 --- a/runtime/lib/double.cc +++ b/runtime/lib/double.cc @@ -172,16 +172,6 @@ DEFINE_NATIVE_ENTRY(Double_truncate, 1) { } -DEFINE_NATIVE_ENTRY(Double_pow, 2) { - const double operand = - Double::CheckedHandle(arguments->NativeArgAt(0)).value(); - GET_NON_NULL_NATIVE_ARGUMENT( - Double, exponent_object, arguments->NativeArgAt(1)); - const double exponent = exponent_object.value(); - return Double::New(pow(operand, exponent)); -} - - #if defined(TARGET_OS_MACOS) // MAC OSX math library produces old style cast warning. #pragma GCC diagnostic ignored "-Wold-style-cast" diff --git a/runtime/lib/double.dart b/runtime/lib/double.dart index 29247adb02c..166d7311799 100644 --- a/runtime/lib/double.dart +++ b/runtime/lib/double.dart @@ -126,21 +126,6 @@ class _Double implements double { int toInt() native "Double_toInt"; double toDouble() { return this; } - double pow(num exponent) { - if (exponent == 0) { - return 1.0; // ECMA-262 15.8.2.13 - } - if (exponent is! num) { - throw new ArgumentError(null); - } - double doubleExponent = exponent.toDouble(); - if (isNaN || exponent.isNaN) { - return double.NAN; - } - return _pow(doubleExponent); - } - double _pow(double exponent) native "Double_pow"; - String toStringAsFixed(int fractionDigits) { // See ECMAScript-262, 15.7.4.5 for details. diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart index aaf57126ec1..dca7ef84346 100644 --- a/runtime/lib/integers.dart +++ b/runtime/lib/integers.dart @@ -163,23 +163,6 @@ class _IntegerImplementation { int toInt() { return this; } double toDouble() { return new _Double.fromInteger(this); } - int pow(int exponent) { - // Exponentiation by squaring. - int base = this; - int result = 1; - while (exponent != 0) { - if ((exponent & 1) == 1) { - result *= base; - } - exponent >>= 1; - // Skip unnecessary operation (can overflow to Mint or Bigint). - if (exponent != 0) { - base *= base; - } - } - return result; - } - String toStringAsFixed(int fractionDigits) { return this.toDouble().toStringAsFixed(fractionDigits); } diff --git a/runtime/lib/math.cc b/runtime/lib/math.cc index 317045dce5b..ca7c7e6da90 100644 --- a/runtime/lib/math.cc +++ b/runtime/lib/math.cc @@ -66,6 +66,15 @@ DEFINE_NATIVE_ENTRY(Math_log, 1) { return Double::New(log(operand.value())); } +DEFINE_NATIVE_ENTRY(Math_doublePow, 2) { + const double operand = + Double::CheckedHandle(arguments->NativeArgAt(0)).value(); + GET_NON_NULL_NATIVE_ARGUMENT( + Double, exponent_object, arguments->NativeArgAt(1)); + const double exponent = exponent_object.value(); + return Double::New(pow(operand, exponent)); +} + // Returns the typed-data array store in '_Random._state' field. static RawTypedData* GetRandomStateArray(const Instance& receiver) { diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart index 1bf701d0750..89460cc394a 100644 --- a/runtime/lib/math_patch.dart +++ b/runtime/lib/math_patch.dart @@ -10,10 +10,42 @@ import "dart:typed_data"; // an [int], otherwise the result is a [double]. patch num pow(num x, num exponent) { if ((x is int) && (exponent is int) && (exponent >= 0)) { - return x.pow(exponent); + return _intPow(x, exponent); } - // Double.pow will call exponent.toDouble(). - return x.toDouble().pow(exponent); + // doublePow will call exponent.toDouble(). + return _doublePow(x.toDouble(), exponent); +} + +double _doublePow(double base, num exponent) { + if (exponent == 0) { + return 1.0; // ECMA-262 15.8.2.13 + } + if (exponent is! num) { + throw new ArgumentError(null); + } + double doubleExponent = exponent.toDouble(); + if (base.isNaN || exponent.isNaN) { + return double.NAN; + } + return _pow(base, doubleExponent); +} + +double _pow(double base, double exponent) native "Math_doublePow"; + +int _intPow(int base, int exponent) { + // Exponentiation by squaring. + int result = 1; + while (exponent != 0) { + if ((exponent & 1) == 1) { + result *= base; + } + exponent >>= 1; + // Skip unnecessary operation (can overflow to Mint or Bigint). + if (exponent != 0) { + base *= base; + } + } + return result; } patch double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble()); diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h index 60c4f54a3f2..2e1e19cdea5 100644 --- a/runtime/vm/bootstrap_natives.h +++ b/runtime/vm/bootstrap_natives.h @@ -73,7 +73,6 @@ namespace dart { V(Double_toStringAsFixed, 2) \ V(Double_toStringAsExponential, 2) \ V(Double_toStringAsPrecision, 2) \ - V(Double_pow, 2) \ V(JSSyntaxRegExp_factory, 4) \ V(JSSyntaxRegExp_getPattern, 1) \ V(JSSyntaxRegExp_getIsMultiLine, 1) \ @@ -110,6 +109,7 @@ namespace dart { V(Math_atan2, 2) \ V(Math_exp, 1) \ V(Math_log, 1) \ + V(Math_doublePow, 2) \ V(Random_nextState, 1) \ V(Random_setupSeed, 2) \ V(DateNatives_currentTimeMillis, 0) \