Upgrade Number constructor to ES6.
Add missing constants, predicates and functions to the Number constructor to have it offer what ES6 now specifies. That is, extend it with: * isInteger(), isSafeInteger() * parseInt(), parseFloat() * EPSILON, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER LOG=N R=mstarzinger@chromium.org BUG=v8:3082 Review URL: https://codereview.chromium.org/124573002 Patch from Sigbjorn Finne <sigbjornf@opera.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18480 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b712779479
commit
127c660eab
@ -79,6 +79,21 @@ function InstallGetterSetter(object, name, getter, setter) {
|
||||
}
|
||||
|
||||
|
||||
// Helper function for installing constant properties on objects.
|
||||
function InstallConstants(object, constants) {
|
||||
if (constants.length >= 4) {
|
||||
%OptimizeObjectForAddingMultipleProperties(object, constants.length >> 1);
|
||||
}
|
||||
var attributes = DONT_ENUM | DONT_DELETE | READ_ONLY;
|
||||
for (var i = 0; i < constants.length; i += 2) {
|
||||
var name = constants[i];
|
||||
var k = constants[i + 1];
|
||||
%SetProperty(object, name, k, attributes);
|
||||
}
|
||||
%ToFastProperties(object);
|
||||
}
|
||||
|
||||
|
||||
// Prevents changes to the prototype of a built-in function.
|
||||
// The "prototype" property of the function object is made non-configurable,
|
||||
// and the prototype object is made non-extensible. The latter prevents
|
||||
@ -1624,12 +1639,29 @@ function NumberIsFinite(number) {
|
||||
}
|
||||
|
||||
|
||||
// Harmony isInteger
|
||||
function NumberIsInteger(number) {
|
||||
return NumberIsFinite(number) && TO_INTEGER(number) == number;
|
||||
}
|
||||
|
||||
|
||||
// Harmony isNaN.
|
||||
function NumberIsNaN(number) {
|
||||
return IS_NUMBER(number) && NUMBER_IS_NAN(number);
|
||||
}
|
||||
|
||||
|
||||
// Harmony isSafeInteger
|
||||
function NumberIsSafeInteger(number) {
|
||||
if (NumberIsFinite(number)) {
|
||||
var integral = TO_INTEGER(number);
|
||||
if (integral == number)
|
||||
return MathAbs(integral) <= $Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
function SetUpNumber() {
|
||||
@ -1642,32 +1674,24 @@ function SetUpNumber() {
|
||||
// Set up the constructor property on the Number prototype object.
|
||||
%SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
|
||||
|
||||
%OptimizeObjectForAddingMultipleProperties($Number, 5);
|
||||
// ECMA-262 section 15.7.3.1.
|
||||
%SetProperty($Number,
|
||||
"MAX_VALUE",
|
||||
1.7976931348623157e+308,
|
||||
DONT_ENUM | DONT_DELETE | READ_ONLY);
|
||||
InstallConstants($Number, $Array(
|
||||
// ECMA-262 section 15.7.3.1.
|
||||
"MAX_VALUE", 1.7976931348623157e+308,
|
||||
// ECMA-262 section 15.7.3.2.
|
||||
"MIN_VALUE", 5e-324,
|
||||
// ECMA-262 section 15.7.3.3.
|
||||
"NaN", NAN,
|
||||
// ECMA-262 section 15.7.3.4.
|
||||
"NEGATIVE_INFINITY", -INFINITY,
|
||||
// ECMA-262 section 15.7.3.5.
|
||||
"POSITIVE_INFINITY", INFINITY,
|
||||
|
||||
// ECMA-262 section 15.7.3.2.
|
||||
%SetProperty($Number, "MIN_VALUE", 5e-324,
|
||||
DONT_ENUM | DONT_DELETE | READ_ONLY);
|
||||
// --- Harmony constants (no spec refs until settled.)
|
||||
|
||||
// ECMA-262 section 15.7.3.3.
|
||||
%SetProperty($Number, "NaN", NAN, DONT_ENUM | DONT_DELETE | READ_ONLY);
|
||||
|
||||
// ECMA-262 section 15.7.3.4.
|
||||
%SetProperty($Number,
|
||||
"NEGATIVE_INFINITY",
|
||||
-INFINITY,
|
||||
DONT_ENUM | DONT_DELETE | READ_ONLY);
|
||||
|
||||
// ECMA-262 section 15.7.3.5.
|
||||
%SetProperty($Number,
|
||||
"POSITIVE_INFINITY",
|
||||
INFINITY,
|
||||
DONT_ENUM | DONT_DELETE | READ_ONLY);
|
||||
%ToFastProperties($Number);
|
||||
"MAX_SAFE_INTEGER", %_MathPow(2, 53) - 1,
|
||||
"MIN_SAFE_INTEGER", -%_MathPow(2, 53) + 1,
|
||||
"EPSILON", %_MathPow(2, -52)
|
||||
));
|
||||
|
||||
// Set up non-enumerable functions on the Number prototype object.
|
||||
InstallFunctions($Number.prototype, DONT_ENUM, $Array(
|
||||
@ -1678,9 +1702,15 @@ function SetUpNumber() {
|
||||
"toExponential", NumberToExponential,
|
||||
"toPrecision", NumberToPrecision
|
||||
));
|
||||
|
||||
// Harmony Number constructor additions
|
||||
InstallFunctions($Number, DONT_ENUM, $Array(
|
||||
"isFinite", NumberIsFinite,
|
||||
"isNaN", NumberIsNaN
|
||||
"isInteger", NumberIsInteger,
|
||||
"isNaN", NumberIsNaN,
|
||||
"isSafeInteger", NumberIsSafeInteger,
|
||||
"parseInt", GlobalParseInt,
|
||||
"parseFloat", GlobalParseFloat
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -60,15 +60,19 @@ function test() {
|
||||
testFloor(0, 0.49999999999999994);
|
||||
testFloor(0, 0.5);
|
||||
testFloor(0, 0.7);
|
||||
testFloor(0, 1.0 - Number.EPSILON);
|
||||
testFloor(-1, -0.1);
|
||||
testFloor(-1, -0.49999999999999994);
|
||||
testFloor(-1, -0.5);
|
||||
testFloor(-1, -0.7);
|
||||
testFloor(1, 1);
|
||||
testFloor(1, 1.1);
|
||||
testFloor(1, 1.0 + Number.EPSILON);
|
||||
testFloor(1, 1.5);
|
||||
testFloor(1, 1.7);
|
||||
testFloor(-1, -1);
|
||||
testFloor(-1, -1 + Number.EPSILON);
|
||||
testFloor(-2, -1 - Number.EPSILON);
|
||||
testFloor(-2, -1.1);
|
||||
testFloor(-2, -1.5);
|
||||
testFloor(-2, -1.7);
|
||||
|
@ -80,6 +80,15 @@ testRound(-9007199254740990, -9007199254740990);
|
||||
testRound(-9007199254740991, -9007199254740991);
|
||||
testRound(Number.MAX_VALUE, Number.MAX_VALUE);
|
||||
testRound(-Number.MAX_VALUE, -Number.MAX_VALUE);
|
||||
testRound(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
|
||||
testRound(Number.MAX_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER + 1);
|
||||
testRound(Number.MAX_SAFE_INTEGER + 2, Number.MAX_SAFE_INTEGER + 2);
|
||||
testRound(Number.MAX_SAFE_INTEGER + 3, Number.MAX_SAFE_INTEGER + 3);
|
||||
testRound(Number.MAX_SAFE_INTEGER + 4, Number.MAX_SAFE_INTEGER + 4);
|
||||
testRound(Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
|
||||
testRound(Number.MIN_SAFE_INTEGER - 1, Number.MIN_SAFE_INTEGER - 1);
|
||||
testRound(Number.MIN_SAFE_INTEGER - 2, Number.MIN_SAFE_INTEGER - 2);
|
||||
testRound(Number.MIN_SAFE_INTEGER - 3, Number.MIN_SAFE_INTEGER - 3);
|
||||
|
||||
testRound(536870911, 536870910.5);
|
||||
testRound(536870911, 536870911);
|
||||
|
@ -25,11 +25,16 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Test Harmony Number.isFinite() and Number.isNaN() functions.
|
||||
// Test number predicates that Harmony adds to the Number constructor:
|
||||
// isFinite(), isNaN(), isInteger(), isSafeInteger().
|
||||
|
||||
assertTrue(Number.isFinite(0));
|
||||
assertTrue(Number.isFinite(Number.MIN_VALUE));
|
||||
assertTrue(Number.isFinite(Number.MAX_VALUE));
|
||||
assertTrue(Number.isFinite(Number.MIN_SAFE_INTEGER));
|
||||
assertTrue(Number.isFinite(Number.MIN_SAFE_INTEGER - 13));
|
||||
assertTrue(Number.isFinite(Number.MAX_SAFE_INTEGER));
|
||||
assertTrue(Number.isFinite(Number.MAX_SAFE_INTEGER + 23));
|
||||
assertFalse(Number.isFinite(Number.NaN));
|
||||
assertFalse(Number.isFinite(Number.POSITIVE_INFINITY));
|
||||
assertFalse(Number.isFinite(Number.NEGATIVE_INFINITY));
|
||||
@ -45,9 +50,12 @@ assertFalse(Number.isFinite(undefined));
|
||||
assertFalse(Number.isNaN(0));
|
||||
assertFalse(Number.isNaN(Number.MIN_VALUE));
|
||||
assertFalse(Number.isNaN(Number.MAX_VALUE));
|
||||
assertFalse(Number.isNaN(Number.MIN_SAFE_INTEGER - 13));
|
||||
assertFalse(Number.isNaN(Number.MAX_SAFE_INTEGER + 23));
|
||||
assertTrue(Number.isNaN(Number.NaN));
|
||||
assertFalse(Number.isNaN(Number.POSITIVE_INFINITY));
|
||||
assertFalse(Number.isNaN(Number.NEGATIVE_INFINITY));
|
||||
assertFalse(Number.isNaN(Number.EPSILON));
|
||||
assertFalse(Number.isNaN(new Number(0)));
|
||||
assertFalse(Number.isNaN(1/0));
|
||||
assertFalse(Number.isNaN(-1/0));
|
||||
@ -56,3 +64,63 @@ assertFalse(Number.isNaN([]));
|
||||
assertFalse(Number.isNaN("s"));
|
||||
assertFalse(Number.isNaN(null));
|
||||
assertFalse(Number.isNaN(undefined));
|
||||
|
||||
assertFalse(Number.isInteger({}));
|
||||
assertFalse(Number.isInteger([]));
|
||||
assertFalse(Number.isInteger("s"));
|
||||
assertFalse(Number.isInteger(null));
|
||||
assertFalse(Number.isInteger(undefined));
|
||||
assertFalse(Number.isInteger(new Number(2)));
|
||||
assertTrue(Number.isInteger(0));
|
||||
assertFalse(Number.isInteger(Number.MIN_VALUE));
|
||||
assertTrue(Number.isInteger(Number.MAX_VALUE));
|
||||
assertTrue(Number.isInteger(Number.MIN_SAFE_INTEGER));
|
||||
assertTrue(Number.isInteger(Number.MIN_SAFE_INTEGER - 13));
|
||||
assertTrue(Number.isInteger(Number.MAX_SAFE_INTEGER));
|
||||
assertTrue(Number.isInteger(Number.MAX_SAFE_INTEGER + 23));
|
||||
assertFalse(Number.isInteger(Number.NaN));
|
||||
assertFalse(Number.isInteger(Number.POSITIVE_INFINITY));
|
||||
assertFalse(Number.isInteger(Number.NEGATIVE_INFINITY));
|
||||
assertFalse(Number.isInteger(1/0));
|
||||
assertFalse(Number.isInteger(-1/0));
|
||||
assertFalse(Number.isInteger(Number.EPSILON));
|
||||
|
||||
assertFalse(Number.isSafeInteger({}));
|
||||
assertFalse(Number.isSafeInteger([]));
|
||||
assertFalse(Number.isSafeInteger("s"));
|
||||
assertFalse(Number.isSafeInteger(null));
|
||||
assertFalse(Number.isSafeInteger(undefined));
|
||||
assertFalse(Number.isSafeInteger(new Number(2)));
|
||||
assertTrue(Number.isSafeInteger(0));
|
||||
assertTrue(Number.isSafeInteger(Number.MIN_SAFE_INTEGER));
|
||||
assertFalse(Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 13));
|
||||
assertTrue(Number.isSafeInteger(Number.MIN_SAFE_INTEGER + 13));
|
||||
assertTrue(Number.isSafeInteger(Number.MAX_SAFE_INTEGER));
|
||||
assertFalse(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 23));
|
||||
assertTrue(Number.isSafeInteger(Number.MAX_SAFE_INTEGER - 23));
|
||||
assertFalse(Number.isSafeInteger(Number.MIN_VALUE));
|
||||
assertFalse(Number.isSafeInteger(Number.MAX_VALUE));
|
||||
assertFalse(Number.isSafeInteger(Number.NaN));
|
||||
assertFalse(Number.isSafeInteger(Number.POSITIVE_INFINITY));
|
||||
assertFalse(Number.isSafeInteger(Number.NEGATIVE_INFINITY));
|
||||
assertFalse(Number.isSafeInteger(1/0));
|
||||
assertFalse(Number.isSafeInteger(-1/0));
|
||||
assertFalse(Number.isSafeInteger(Number.EPSILON));
|
||||
|
||||
var near_upper = Math.pow(2, 52);
|
||||
assertTrue(Number.isSafeInteger(near_upper));
|
||||
assertFalse(Number.isSafeInteger(2 * near_upper));
|
||||
assertTrue(Number.isSafeInteger(2 * near_upper - 1));
|
||||
assertTrue(Number.isSafeInteger(2 * near_upper - 2));
|
||||
assertFalse(Number.isSafeInteger(2 * near_upper + 1));
|
||||
assertFalse(Number.isSafeInteger(2 * near_upper + 2));
|
||||
assertFalse(Number.isSafeInteger(2 * near_upper + 7));
|
||||
|
||||
var near_lower = -near_upper;
|
||||
assertTrue(Number.isSafeInteger(near_lower));
|
||||
assertFalse(Number.isSafeInteger(2 * near_lower));
|
||||
assertTrue(Number.isSafeInteger(2 * near_lower + 1));
|
||||
assertTrue(Number.isSafeInteger(2 * near_lower + 2));
|
||||
assertFalse(Number.isSafeInteger(2 * near_lower - 1));
|
||||
assertFalse(Number.isSafeInteger(2 * near_lower - 2));
|
||||
assertFalse(Number.isSafeInteger(2 * near_lower - 7));
|
||||
|
@ -114,3 +114,12 @@ assertEquals(state, "throwingString");
|
||||
state = null;
|
||||
try { parseInt(throwingString, throwingRadix); } catch (e) {}
|
||||
assertEquals(state, "throwingString");
|
||||
|
||||
// And finally, check that the Harmony additions to the Number
|
||||
// constructor is available:
|
||||
assertTrue("parseInt" in Number);
|
||||
assertTrue("parseFloat" in Number);
|
||||
assertSame( Number.parseInt, parseInt);
|
||||
assertSame(Number.parseFloat, parseFloat);
|
||||
assertEquals(Number.parseFloat('0.1'), parseFloat('0.1'));
|
||||
assertEquals(Number.parseInt('0xea'), parseInt('0xEA'));
|
||||
|
Loading…
Reference in New Issue
Block a user