Index: src/js/v8natives.js |
diff --git a/src/js/v8natives.js b/src/js/v8natives.js |
index 9026cfe684596649756bc58abdc57fcd1cbd7551..6db941bffe90f6166bd2943c80e04be55a4e1703 100644 |
--- a/src/js/v8natives.js |
+++ b/src/js/v8natives.js |
@@ -222,6 +222,124 @@ |
// ---------------------------------------------------------------------------- |
// Number |
+// ES6 Number.prototype.toString([ radix ]) |
+function NumberToStringJS(radix) { |
+ // NOTE: Both Number objects and values can enter here as |
+ // 'this'. This is not as dictated by ECMA-262. |
+ var number = this; |
+ if (!IS_NUMBER(this)) { |
+ if (!IS_NUMBER_WRAPPER(this)) { |
+ throw MakeTypeError(kNotGeneric, 'Number.prototype.toString'); |
+ } |
+ // Get the value of this number in case it's an object. |
+ number = %_ValueOf(this); |
+ } |
+ // Fast case: Convert number in radix 10. |
+ if (IS_UNDEFINED(radix) || radix === 10) { |
+ return %_NumberToString(number); |
+ } |
+ |
+ // Convert the radix to an integer and check the range. |
+ radix = TO_INTEGER(radix); |
+ if (radix < 2 || radix > 36) throw MakeRangeError(kToRadixFormatRange); |
+ // Convert the number to a string in the given radix. |
+ return %NumberToRadixString(number, radix); |
+} |
+ |
+ |
+// ES6 20.1.3.4 Number.prototype.toLocaleString([reserved1 [, reserved2]]) |
+function NumberToLocaleString() { |
+ return %_Call(NumberToStringJS, this); |
+} |
+ |
+ |
+// ES6 20.1.3.7 Number.prototype.valueOf() |
+function NumberValueOf() { |
+ // NOTE: Both Number objects and values can enter here as |
+ // 'this'. This is not as dictated by ECMA-262. |
+ if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) { |
+ throw MakeTypeError(kNotGeneric, 'Number.prototype.valueOf'); |
+ } |
+ return %_ValueOf(this); |
+} |
+ |
+ |
+// ES6 20.1.3.3 Number.prototype.toFixed(fractionDigits) |
+function NumberToFixedJS(fractionDigits) { |
+ var x = this; |
+ if (!IS_NUMBER(this)) { |
+ if (!IS_NUMBER_WRAPPER(this)) { |
+ throw MakeTypeError(kIncompatibleMethodReceiver, |
+ "Number.prototype.toFixed", this); |
+ } |
+ // Get the value of this number in case it's an object. |
+ x = %_ValueOf(this); |
+ } |
+ var f = TO_INTEGER(fractionDigits); |
+ |
+ if (f < 0 || f > 20) { |
+ throw MakeRangeError(kNumberFormatRange, "toFixed() digits"); |
+ } |
+ |
+ if (NUMBER_IS_NAN(x)) return "NaN"; |
+ if (x == INFINITY) return "Infinity"; |
+ if (x == -INFINITY) return "-Infinity"; |
+ |
+ return %NumberToFixed(x, f); |
+} |
+ |
+ |
+// ES6 20.1.3.2 Number.prototype.toExponential(fractionDigits) |
+function NumberToExponentialJS(fractionDigits) { |
+ var x = this; |
+ if (!IS_NUMBER(this)) { |
+ if (!IS_NUMBER_WRAPPER(this)) { |
+ throw MakeTypeError(kIncompatibleMethodReceiver, |
+ "Number.prototype.toExponential", this); |
+ } |
+ // Get the value of this number in case it's an object. |
+ x = %_ValueOf(this); |
+ } |
+ var f = IS_UNDEFINED(fractionDigits) ? UNDEFINED : TO_INTEGER(fractionDigits); |
+ |
+ if (NUMBER_IS_NAN(x)) return "NaN"; |
+ if (x == INFINITY) return "Infinity"; |
+ if (x == -INFINITY) return "-Infinity"; |
+ |
+ if (IS_UNDEFINED(f)) { |
+ f = -1; // Signal for runtime function that f is not defined. |
+ } else if (f < 0 || f > 20) { |
+ throw MakeRangeError(kNumberFormatRange, "toExponential()"); |
+ } |
+ return %NumberToExponential(x, f); |
+} |
+ |
+ |
+// ES6 20.1.3.5 Number.prototype.toPrecision(precision) |
+function NumberToPrecisionJS(precision) { |
+ var x = this; |
+ if (!IS_NUMBER(this)) { |
+ if (!IS_NUMBER_WRAPPER(this)) { |
+ throw MakeTypeError(kIncompatibleMethodReceiver, |
+ "Number.prototype.toPrecision", this); |
+ } |
+ // Get the value of this number in case it's an object. |
+ x = %_ValueOf(this); |
+ } |
+ if (IS_UNDEFINED(precision)) return TO_STRING(x); |
+ var p = TO_INTEGER(precision); |
+ |
+ if (NUMBER_IS_NAN(x)) return "NaN"; |
+ if (x == INFINITY) return "Infinity"; |
+ if (x == -INFINITY) return "-Infinity"; |
+ |
+ if (p < 1 || p > 21) { |
+ throw MakeRangeError(kToPrecisionFormatRange); |
+ } |
+ return %NumberToPrecision(x, p); |
+} |
+ |
+ |
// Harmony isFinite. |
function NumberIsFinite(number) { |
return IS_NUMBER(number) && NUMBER_IS_FINITE(number); |
@@ -253,6 +371,13 @@ |
// ---------------------------------------------------------------------------- |
+ |
+%FunctionSetPrototype(GlobalNumber, new GlobalNumber(0)); |
+ |
+%OptimizeObjectForAddingMultipleProperties(GlobalNumber.prototype, 8); |
+// Set up the constructor property on the Number prototype object. |
+%AddNamedProperty(GlobalNumber.prototype, "constructor", GlobalNumber, |
+ DONT_ENUM); |
utils.InstallConstants(GlobalNumber, [ |
// ECMA-262 section 15.7.3.1. |
@@ -273,6 +398,16 @@ |
"EPSILON", 2.220446049250313e-16, |
]); |
+// Set up non-enumerable functions on the Number prototype object. |
+utils.InstallFunctions(GlobalNumber.prototype, DONT_ENUM, [ |
+ "toString", NumberToStringJS, |
+ "toLocaleString", NumberToLocaleString, |
+ "valueOf", NumberValueOf, |
+ "toFixed", NumberToFixedJS, |
+ "toExponential", NumberToExponentialJS, |
+ "toPrecision", NumberToPrecisionJS |
+]); |
+ |
// Harmony Number constructor additions |
utils.InstallFunctions(GlobalNumber, DONT_ENUM, [ |
"isFinite", NumberIsFinite, |