Simple ES6 feature: Number constructor extras
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Sep 2014 01:52:42 +0000 (01:52 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 29 Sep 2014 01:52:42 +0000 (01:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=131707

Patch by Diego Pino Garcia <dpino@igalia.com> on 2014-09-28
Reviewed by Darin Adler.

Source/JavaScriptCore:

* runtime/CommonIdentifiers.h:
* runtime/NumberConstructor.cpp:
(JSC::NumberConstructor::finishCreation): Setup constants and
functions.
(JSC::numberConstructorFuncIsFinite): Added.
(JSC::numberConstructorFuncIsInteger): Added.
(JSC::numberConstructorFuncIsNaN): Added.
(JSC::numberConstructorFuncIsSafeInteger): Added.
(JSC::NumberConstructor::getOwnPropertySlot): Deleted.
(JSC::numberConstructorNaNValue): Deleted.
(JSC::numberConstructorNegInfinity): Deleted.
(JSC::numberConstructorPosInfinity): Deleted.
(JSC::numberConstructorMaxValue): Deleted.
(JSC::numberConstructorMinValue): Deleted.
* runtime/NumberConstructor.h:

LayoutTests:

* js/Object-getOwnPropertyNames-expected.txt:
* js/number-constructor-expected.txt: Added.
* js/number-constructor.html: Added.
* js/script-tests/Object-getOwnPropertyNames.js:
* js/script-tests/number-constructor.js: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@174049 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/js/Object-getOwnPropertyNames-expected.txt
LayoutTests/js/number-constructor-expected.txt [new file with mode: 0644]
LayoutTests/js/number-constructor.html [new file with mode: 0644]
LayoutTests/js/script-tests/Object-getOwnPropertyNames.js
LayoutTests/js/script-tests/number-constructor.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/CommonIdentifiers.h
Source/JavaScriptCore/runtime/NumberConstructor.cpp
Source/JavaScriptCore/runtime/NumberConstructor.h

index ae0762b..611e334 100644 (file)
@@ -1,3 +1,16 @@
+2014-09-28  Diego Pino Garcia  <dpino@igalia.com>
+
+        Simple ES6 feature: Number constructor extras
+        https://bugs.webkit.org/show_bug.cgi?id=131707
+
+        Reviewed by Darin Adler.
+
+        * js/Object-getOwnPropertyNames-expected.txt:
+        * js/number-constructor-expected.txt: Added.
+        * js/number-constructor.html: Added.
+        * js/script-tests/Object-getOwnPropertyNames.js:
+        * js/script-tests/number-constructor.js: Added.
+
 2014-09-28  Sungmann Cho  <sungmann.cho@navercorp.com>
 
         Fix some minor typos: psuedo -> pseudo
index 23b7ea9..d093ee4 100644 (file)
@@ -50,7 +50,7 @@ PASS getSortedOwnPropertyNames(String) is ['fromCharCode', 'length', 'name', 'pr
 PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'contains', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']
 PASS getSortedOwnPropertyNames(Boolean) is ['length', 'name', 'prototype']
 PASS getSortedOwnPropertyNames(Boolean.prototype) is ['constructor', 'toString', 'valueOf']
-PASS getSortedOwnPropertyNames(Number) is ['MAX_VALUE', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'length', 'name', 'prototype']
+PASS getSortedOwnPropertyNames(Number) is ['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']
 PASS getSortedOwnPropertyNames(Number.prototype) is ['clz', 'constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']
 PASS getSortedOwnPropertyNames(Date) is ['UTC', 'length', 'name', 'now', 'parse', 'prototype']
 PASS getSortedOwnPropertyNames(Date.prototype) is ['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']
diff --git a/LayoutTests/js/number-constructor-expected.txt b/LayoutTests/js/number-constructor-expected.txt
new file mode 100644 (file)
index 0000000..5b7e814
--- /dev/null
@@ -0,0 +1,156 @@
+This test case tests the Number constructor.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Number.isFinite(0) is true
+PASS Number.isFinite(-0) is true
+PASS Number.isFinite(1) is true
+PASS Number.isFinite(-1) is true
+PASS Number.isFinite(1.0) is true
+PASS Number.isFinite(1.1) is true
+PASS Number.isFinite(-1.0) is true
+PASS Number.isFinite(-1.1) is true
+PASS Number.isFinite(Number.MAX_SAFE_INTEGER) is true
+PASS Number.isFinite(Number.MIN_SAFE_INTEGER) is true
+PASS Number.isFinite(Number.MAX_VALUE) is true
+PASS Number.isFinite(Number.MIN_VALUE) is true
+PASS Number.isFinite() is false
+PASS Number.isFinite({}) is false
+PASS Number.isFinite([]) is false
+PASS Number.isFinite(true) is false
+PASS Number.isFinite(false) is false
+PASS Number.isFinite(null) is false
+PASS Number.isFinite(Number.NaN) is false
+PASS Number.isFinite(Number.POSITIVE_INFINITY) is false
+PASS Number.isFinite(Number.NEGATIVE_INFINITY) is false
+PASS Number.isFinite(foo) threw exception ReferenceError: Can't find variable: foo.
+PASS Number.isInteger(0) is true
+PASS Number.isInteger(-0) is true
+PASS Number.isInteger(1) is true
+PASS Number.isInteger(-1) is true
+PASS Number.isInteger(1.0) is true
+PASS Number.isInteger(-1.0) is true
+PASS Number.isInteger(Number.MAX_SAFE_INTEGER) is true
+PASS Number.isInteger(Number.MIN_SAFE_INTEGER) is true
+PASS Number.isInteger(Number.MAX_VALUE) is true
+PASS Number.isInteger(Number.MIN_VALUE) is false
+PASS Number.isInteger(1.1) is false
+PASS Number.isInteger(-1.1) is false
+PASS Number.isInteger() is false
+PASS Number.isInteger({}) is false
+PASS Number.isInteger([]) is false
+PASS Number.isInteger(true) is false
+PASS Number.isInteger(false) is false
+PASS Number.isInteger(null) is false
+PASS Number.isInteger(Number.NaN) is false
+PASS Number.isInteger(Number.POSITIVE_INFINITY) is false
+PASS Number.isInteger(Number.NEGATIVE_INFINITY) is false
+PASS Number.isInteger(foo) threw exception ReferenceError: Can't find variable: foo.
+PASS Number.isNaN(Number.NaN) is true
+PASS Number.isNaN(0) is false
+PASS Number.isNaN(-0) is false
+PASS Number.isNaN(1) is false
+PASS Number.isNaN(-1) is false
+PASS Number.isNaN(1.0) is false
+PASS Number.isNaN(1.1) is false
+PASS Number.isNaN(-1.0) is false
+PASS Number.isNaN(-1.1) is false
+PASS Number.isNaN() is false
+PASS Number.isNaN({}) is false
+PASS Number.isNaN([]) is false
+PASS Number.isNaN(true) is false
+PASS Number.isNaN(false) is false
+PASS Number.isNaN(null) is false
+PASS Number.isNaN(Number.POSITIVE_INFINITY) is false
+PASS Number.isNaN(Number.NEGATIVE_INFINITY) is false
+PASS Number.isNaN(Number.MAX_SAFE_INTEGER) is false
+PASS Number.isNaN(Number.MIN_SAFE_INTEGER) is false
+PASS Number.isNaN(Number.MAX_VALUE) is false
+PASS Number.isNaN(Number.MIN_VALUE) is false
+PASS Number.isNaN(foo) threw exception ReferenceError: Can't find variable: foo.
+PASS Number.isSafeInteger(0) is true
+PASS Number.isSafeInteger(-0) is true
+PASS Number.isSafeInteger(1) is true
+PASS Number.isSafeInteger(-1) is true
+PASS Number.isSafeInteger(1.0) is true
+PASS Number.isSafeInteger(-1.0) is true
+PASS Number.isSafeInteger(Number.MAX_SAFE_INTEGER) is true
+PASS Number.isSafeInteger(Number.MAX_SAFE_INTEGER - 1) is true
+PASS Number.isSafeInteger(Number.MIN_SAFE_INTEGER) is true
+PASS Number.isSafeInteger(Number.MIN_SAFE_INTEGER + 1) is true
+PASS Number.isSafeInteger(1.1) is false
+PASS Number.isSafeInteger(-1.1) is false
+PASS Number.isSafeInteger() is false
+PASS Number.isSafeInteger({}) is false
+PASS Number.isSafeInteger([]) is false
+PASS Number.isSafeInteger(true) is false
+PASS Number.isSafeInteger(false) is false
+PASS Number.isSafeInteger(null) is false
+PASS Number.isSafeInteger(Number.NaN) is false
+PASS Number.isSafeInteger(Number.MAX_VALUE) is false
+PASS Number.isSafeInteger(Number.MIN_VALUE) is false
+PASS Number.isSafeInteger(Number.POSITIVE_INFINITY) is false
+PASS Number.isSafeInteger(Number.NEGATIVE_INFINITY) is false
+PASS Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) is false
+PASS Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) is false
+PASS Number.isSafeInteger(foo) threw exception ReferenceError: Can't find variable: foo.
+PASS Number.parseFloat("0") is 0
+PASS Number.parseFloat("-0") is -0
+PASS Number.parseFloat("1") is 1
+PASS Number.parseFloat("-1") is -1
+PASS Number.parseFloat("1.1") is 1.1
+PASS Number.parseFloat("-1.1") is -1.1
+PASS Number.parseFloat("10E6") is 10E6
+PASS Number.parseFloat("0xA") is 0
+PASS Number.parseFloat("050") is 50
+PASS Number.parseFloat(050) is 40
+PASS Number.parseFloat("0x20") is 0
+PASS Number.parseFloat(0x20) is 32
+PASS Number.parseFloat() is NaN
+PASS Number.parseFloat({}) is NaN
+PASS Number.parseFloat([]) is NaN
+PASS Number.parseFloat(true) is NaN
+PASS Number.parseFloat(false) is NaN
+PASS Number.parseFloat(null) is NaN
+PASS Number.parseFloat(Number.NaN) is NaN
+PASS Number.parseFloat("1.7976931348623157E308") is 1.7976931348623157e+308
+PASS Number.parseFloat("1.80E308") is Infinity
+PASS Number.parseFloat("5E-324") is 5e-324
+PASS Number.parseFloat("5E-325") is 0
+PASS Number.parseFloat("20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") is 2e+307
+PASS Number.parseFloat("200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") is Infinity
+PASS Number.parseFloat(foo) threw exception ReferenceError: Can't find variable: foo.
+PASS Number.parseInt("0") is 0
+PASS Number.parseInt("-0") is -0
+PASS Number.parseInt("1") is 1
+PASS Number.parseInt("-1") is -1
+PASS Number.parseInt("1.1") is 1
+PASS Number.parseInt("-1.1") is -1
+PASS Number.parseInt("10E6") is 10
+PASS Number.parseInt("0xA") is 10
+PASS Number.parseInt("050") is 50
+PASS Number.parseInt("050", 8) is 40
+PASS Number.parseInt(050) is 40
+PASS Number.parseInt("0x20") is 32
+PASS Number.parseInt("0x20", 16) is 32
+PASS Number.parseInt("20", 16) is 32
+PASS Number.parseInt(0x20) is 32
+PASS Number.parseInt() is NaN
+PASS Number.parseInt({}) is NaN
+PASS Number.parseInt([]) is NaN
+PASS Number.parseInt(true) is NaN
+PASS Number.parseInt(false) is NaN
+PASS Number.parseInt(null) is NaN
+PASS Number.parseInt(Number.NaN) is NaN
+PASS Number.parseInt("1.7976931348623157E308") is 1
+PASS Number.parseInt("1.80E308") is 1
+PASS Number.parseInt("5E-324") is 5
+PASS Number.parseInt("5E-325") is 5
+PASS Number.parseInt("20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") is 2e+307
+PASS Number.parseInt("200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") is Infinity
+PASS Number.parseInt(foo) threw exception ReferenceError: Can't find variable: foo.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/js/number-constructor.html b/LayoutTests/js/number-constructor.html
new file mode 100644 (file)
index 0000000..e47a8dc
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="UTF-8">
+  <script src="../resources/js-test-pre.js"></script>
+</head>
+<body>
+  <script src="script-tests/number-constructor.js"></script>
+  <script src="../resources/js-test-post.js"></script>
+</body>
+</html>
index 375330d..3315808 100644 (file)
@@ -58,7 +58,7 @@ var expectedPropertyNamesSet = {
     "String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'contains', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']",
     "Boolean": "['length', 'name', 'prototype']",
     "Boolean.prototype": "['constructor', 'toString', 'valueOf']",
-    "Number": "['MAX_VALUE', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'length', 'name', 'prototype']",
+    "Number": "['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']",
     "Number.prototype": "['clz', 'constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']",
     "Date": "['UTC', 'length', 'name', 'now', 'parse', 'prototype']",
     "Date.prototype": "['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']",
diff --git a/LayoutTests/js/script-tests/number-constructor.js b/LayoutTests/js/script-tests/number-constructor.js
new file mode 100644 (file)
index 0000000..a13782d
--- /dev/null
@@ -0,0 +1,160 @@
+description('This test case tests the Number constructor.');
+
+// isFinite
+shouldBeTrue('Number.isFinite(0)');
+shouldBeTrue('Number.isFinite(-0)');
+shouldBeTrue('Number.isFinite(1)');
+shouldBeTrue('Number.isFinite(-1)');
+shouldBeTrue('Number.isFinite(1.0)');
+shouldBeTrue('Number.isFinite(1.1)');
+shouldBeTrue('Number.isFinite(-1.0)');
+shouldBeTrue('Number.isFinite(-1.1)');
+shouldBeTrue('Number.isFinite(Number.MAX_SAFE_INTEGER)');
+shouldBeTrue('Number.isFinite(Number.MIN_SAFE_INTEGER)');
+shouldBeTrue('Number.isFinite(Number.MAX_VALUE)');
+shouldBeTrue('Number.isFinite(Number.MIN_VALUE)');
+shouldBeFalse('Number.isFinite()');
+shouldBeFalse('Number.isFinite({})');
+shouldBeFalse('Number.isFinite([])');
+shouldBeFalse('Number.isFinite(true)');
+shouldBeFalse('Number.isFinite(false)');
+shouldBeFalse('Number.isFinite(null)');
+shouldBeFalse('Number.isFinite(Number.NaN)');
+shouldBeFalse('Number.isFinite(Number.POSITIVE_INFINITY)');
+shouldBeFalse('Number.isFinite(Number.NEGATIVE_INFINITY)');
+shouldThrow('Number.isFinite(foo)');
+
+// isInteger
+shouldBeTrue('Number.isInteger(0)');
+shouldBeTrue('Number.isInteger(-0)');
+shouldBeTrue('Number.isInteger(1)');
+shouldBeTrue('Number.isInteger(-1)');
+shouldBeTrue('Number.isInteger(1.0)');
+shouldBeTrue('Number.isInteger(-1.0)');
+shouldBeTrue('Number.isInteger(Number.MAX_SAFE_INTEGER)');
+shouldBeTrue('Number.isInteger(Number.MIN_SAFE_INTEGER)');
+shouldBeTrue('Number.isInteger(Number.MAX_VALUE)');
+shouldBeFalse('Number.isInteger(Number.MIN_VALUE)');
+shouldBeFalse('Number.isInteger(1.1)');
+shouldBeFalse('Number.isInteger(-1.1)');
+shouldBeFalse('Number.isInteger()');
+shouldBeFalse('Number.isInteger({})');
+shouldBeFalse('Number.isInteger([])');
+shouldBeFalse('Number.isInteger(true)');
+shouldBeFalse('Number.isInteger(false)');
+shouldBeFalse('Number.isInteger(null)');
+shouldBeFalse('Number.isInteger(Number.NaN)');
+shouldBeFalse('Number.isInteger(Number.POSITIVE_INFINITY)');
+shouldBeFalse('Number.isInteger(Number.NEGATIVE_INFINITY)');
+shouldThrow('Number.isInteger(foo)');
+
+// isNaN
+shouldBeTrue('Number.isNaN(Number.NaN)');
+shouldBeFalse('Number.isNaN(0)');
+shouldBeFalse('Number.isNaN(-0)');
+shouldBeFalse('Number.isNaN(1)');
+shouldBeFalse('Number.isNaN(-1)');
+shouldBeFalse('Number.isNaN(1.0)');
+shouldBeFalse('Number.isNaN(1.1)');
+shouldBeFalse('Number.isNaN(-1.0)');
+shouldBeFalse('Number.isNaN(-1.1)');
+shouldBeFalse('Number.isNaN()');
+shouldBeFalse('Number.isNaN({})');
+shouldBeFalse('Number.isNaN([])');
+shouldBeFalse('Number.isNaN(true)');
+shouldBeFalse('Number.isNaN(false)');
+shouldBeFalse('Number.isNaN(null)');
+shouldBeFalse('Number.isNaN(Number.POSITIVE_INFINITY)');
+shouldBeFalse('Number.isNaN(Number.NEGATIVE_INFINITY)');
+shouldBeFalse('Number.isNaN(Number.MAX_SAFE_INTEGER)');
+shouldBeFalse('Number.isNaN(Number.MIN_SAFE_INTEGER)');
+shouldBeFalse('Number.isNaN(Number.MAX_VALUE)');
+shouldBeFalse('Number.isNaN(Number.MIN_VALUE)');
+shouldThrow('Number.isNaN(foo)');
+
+// isSafeInteger
+shouldBeTrue('Number.isSafeInteger(0)');
+shouldBeTrue('Number.isSafeInteger(-0)');
+shouldBeTrue('Number.isSafeInteger(1)');
+shouldBeTrue('Number.isSafeInteger(-1)');
+shouldBeTrue('Number.isSafeInteger(1.0)');
+shouldBeTrue('Number.isSafeInteger(-1.0)');
+shouldBeTrue('Number.isSafeInteger(Number.MAX_SAFE_INTEGER)');
+shouldBeTrue('Number.isSafeInteger(Number.MAX_SAFE_INTEGER - 1)');
+shouldBeTrue('Number.isSafeInteger(Number.MIN_SAFE_INTEGER)');
+shouldBeTrue('Number.isSafeInteger(Number.MIN_SAFE_INTEGER + 1)');
+shouldBeFalse('Number.isSafeInteger(1.1)');
+shouldBeFalse('Number.isSafeInteger(-1.1)');
+shouldBeFalse('Number.isSafeInteger()');
+shouldBeFalse('Number.isSafeInteger({})');
+shouldBeFalse('Number.isSafeInteger([])');
+shouldBeFalse('Number.isSafeInteger(true)');
+shouldBeFalse('Number.isSafeInteger(false)');
+shouldBeFalse('Number.isSafeInteger(null)');
+shouldBeFalse('Number.isSafeInteger(Number.NaN)');
+shouldBeFalse('Number.isSafeInteger(Number.MAX_VALUE)');
+shouldBeFalse('Number.isSafeInteger(Number.MIN_VALUE)');
+shouldBeFalse('Number.isSafeInteger(Number.POSITIVE_INFINITY)');
+shouldBeFalse('Number.isSafeInteger(Number.NEGATIVE_INFINITY)');
+shouldBeFalse('Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)');
+shouldBeFalse('Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1)');
+shouldThrow('Number.isSafeInteger(foo)');
+
+// parseFloat
+shouldBe('Number.parseFloat("0")', '0');
+shouldBe('Number.parseFloat("-0")', '-0');
+shouldBe('Number.parseFloat("1")', '1');
+shouldBe('Number.parseFloat("-1")', '-1');
+shouldBe('Number.parseFloat("1.1")', '1.1');
+shouldBe('Number.parseFloat("-1.1")', '-1.1');
+shouldBe('Number.parseFloat("10E6")', '10E6');
+shouldBe('Number.parseFloat("0xA")', '0');
+shouldBe('Number.parseFloat("050")', '50');
+shouldBe('Number.parseFloat(050)', '40');
+shouldBe('Number.parseFloat("0x20")', '0');
+shouldBe('Number.parseFloat(0x20)', '32');
+shouldBe('Number.parseFloat()', 'NaN');
+shouldBe('Number.parseFloat({})', 'NaN');
+shouldBe('Number.parseFloat([])', 'NaN');
+shouldBe('Number.parseFloat(true)', 'NaN');
+shouldBe('Number.parseFloat(false)', 'NaN');
+shouldBe('Number.parseFloat(null)', 'NaN');
+shouldBe('Number.parseFloat(Number.NaN)', 'NaN');
+shouldBe('Number.parseFloat("1.7976931348623157E308")', '1.7976931348623157e+308');
+shouldBe('Number.parseFloat("1.80E308")', "Infinity");
+shouldBe('Number.parseFloat("5E-324")', '5e-324');
+shouldBe('Number.parseFloat("5E-325")', '0');
+shouldBe('Number.parseFloat("20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")', '2e+307');
+shouldBe('Number.parseFloat("200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")', 'Infinity');
+shouldThrow('Number.parseFloat(foo)');
+
+// parseInt
+shouldBe('Number.parseInt("0")', '0');
+shouldBe('Number.parseInt("-0")', '-0');
+shouldBe('Number.parseInt("1")', '1');
+shouldBe('Number.parseInt("-1")', '-1');
+shouldBe('Number.parseInt("1.1")', '1');
+shouldBe('Number.parseInt("-1.1")', '-1');
+shouldBe('Number.parseInt("10E6")', '10');
+shouldBe('Number.parseInt("0xA")', '10');
+shouldBe('Number.parseInt("050")', '50');
+shouldBe('Number.parseInt("050", 8)', '40');
+shouldBe('Number.parseInt(050)', '40');
+shouldBe('Number.parseInt("0x20")', '32');
+shouldBe('Number.parseInt("0x20", 16)', '32');
+shouldBe('Number.parseInt("20", 16)', '32');
+shouldBe('Number.parseInt(0x20)', '32');
+shouldBe('Number.parseInt()', 'NaN');
+shouldBe('Number.parseInt({})', 'NaN');
+shouldBe('Number.parseInt([])', 'NaN');
+shouldBe('Number.parseInt(true)', 'NaN');
+shouldBe('Number.parseInt(false)', 'NaN');
+shouldBe('Number.parseInt(null)', 'NaN');
+shouldBe('Number.parseInt(Number.NaN)', 'NaN');
+shouldBe('Number.parseInt("1.7976931348623157E308")', '1');
+shouldBe('Number.parseInt("1.80E308")', '1');
+shouldBe('Number.parseInt("5E-324")', '5');
+shouldBe('Number.parseInt("5E-325")', '5');
+shouldBe('Number.parseInt("20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")', '2e+307');
+shouldBe('Number.parseInt("200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")', 'Infinity');
+shouldThrow('Number.parseInt(foo)');
index a715868..49e8eb3 100644 (file)
@@ -1,3 +1,26 @@
+2014-09-28  Diego Pino Garcia  <dpino@igalia.com>
+
+        Simple ES6 feature: Number constructor extras
+        https://bugs.webkit.org/show_bug.cgi?id=131707
+
+        Reviewed by Darin Adler.
+
+        * runtime/CommonIdentifiers.h:
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::finishCreation): Setup constants and
+        functions.
+        (JSC::numberConstructorFuncIsFinite): Added.
+        (JSC::numberConstructorFuncIsInteger): Added.
+        (JSC::numberConstructorFuncIsNaN): Added.
+        (JSC::numberConstructorFuncIsSafeInteger): Added.
+        (JSC::NumberConstructor::getOwnPropertySlot): Deleted.
+        (JSC::numberConstructorNaNValue): Deleted.
+        (JSC::numberConstructorNegInfinity): Deleted.
+        (JSC::numberConstructorPosInfinity): Deleted.
+        (JSC::numberConstructorMaxValue): Deleted.
+        (JSC::numberConstructorMinValue): Deleted.
+        * runtime/NumberConstructor.h:
+
 2014-09-26  Filip Pizlo  <fpizlo@apple.com>
 
         Disable function.arguments
index 569ee4f..174dc1a 100644 (file)
     macro(input) \
     macro(instructionCount) \
     macro(isArray) \
+    macro(isFinite) \
+    macro(isInteger) \
+    macro(isNaN) \
     macro(isPrototypeOf) \
+    macro(isSafeInteger) \
     macro(isView) \
     macro(isWatchpoint) \
     macro(jettisonReason) \
     macro(osrExitSites) \
     macro(osrExits) \
     macro(parse) \
+    macro(parseFloat) \
+    macro(parseInt) \
     macro(postMessage) \
     macro(profiledBytecodes) \
     macro(propertyIsEnumerable) \
index f4eaedd..3cfe941 100644 (file)
 #include "NumberObject.h"
 #include "NumberPrototype.h"
 #include "JSCInlines.h"
+#include "JSGlobalObjectFunctions.h"
 
 namespace JSC {
 
-static EncodedJSValue numberConstructorNaNValue(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue numberConstructorNegInfinity(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue numberConstructorPosInfinity(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue numberConstructorMaxValue(ExecState*, JSObject*, EncodedJSValue, PropertyName);
-static EncodedJSValue numberConstructorMinValue(ExecState*, JSObject*, EncodedJSValue, PropertyName);
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsFinite(ExecState*);
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsInteger(ExecState*);
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsNaN(ExecState*);
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsSafeInteger(ExecState*);
 
 } // namespace JSC
 
-#include "NumberConstructor.lut.h"
-
 namespace JSC {
 
 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(NumberConstructor);
 
-const ClassInfo NumberConstructor::s_info = { "Function", &InternalFunction::s_info, &numberConstructorTable, CREATE_METHOD_TABLE(NumberConstructor) };
-
-/* Source for NumberConstructor.lut.h
-@begin numberConstructorTable
-   NaN                   numberConstructorNaNValue       DontEnum|DontDelete|ReadOnly
-   NEGATIVE_INFINITY     numberConstructorNegInfinity    DontEnum|DontDelete|ReadOnly
-   POSITIVE_INFINITY     numberConstructorPosInfinity    DontEnum|DontDelete|ReadOnly
-   MAX_VALUE             numberConstructorMaxValue       DontEnum|DontDelete|ReadOnly
-   MIN_VALUE             numberConstructorMinValue       DontEnum|DontDelete|ReadOnly
-@end
-*/
+const ClassInfo NumberConstructor::s_info = { "Function", &InternalFunction::s_info, 0, CREATE_METHOD_TABLE(NumberConstructor) };
 
 NumberConstructor::NumberConstructor(VM& vm, Structure* structure)
     : InternalFunction(vm, structure)
@@ -70,36 +58,22 @@ void NumberConstructor::finishCreation(VM& vm, NumberPrototype* numberPrototype)
 
     // no. of arguments for constructor
     putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
-}
-
-bool NumberConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
-{
-    return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, numberConstructorTable, jsCast<NumberConstructor*>(object), propertyName, slot);
-}
-
-static EncodedJSValue numberConstructorNaNValue(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNaN());
-}
-
-static EncodedJSValue numberConstructorNegInfinity(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNumber(-std::numeric_limits<double>::infinity()));
-}
 
-static EncodedJSValue numberConstructorPosInfinity(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNumber(std::numeric_limits<double>::infinity()));
-}
-
-static EncodedJSValue numberConstructorMaxValue(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNumber(1.7976931348623157E+308));
-}
-
-static EncodedJSValue numberConstructorMinValue(ExecState*, JSObject*, EncodedJSValue, PropertyName)
-{
-    return JSValue::encode(jsNumber(5E-324));
+    putDirectWithoutTransition(vm, Identifier(&vm, "EPSILON"), jsDoubleNumber(std::numeric_limits<double>::epsilon()), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier(&vm, "MAX_VALUE"), jsDoubleNumber(1.7976931348623157E+308), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier(&vm, "MIN_VALUE"), jsDoubleNumber(5E-324), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier(&vm, "MAX_SAFE_INTEGER"), jsDoubleNumber(9007199254740991.0), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier(&vm, "MIN_SAFE_INTEGER"), jsDoubleNumber(-9007199254740991.0), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier(&vm, "NEGATIVE_INFINITY"), jsDoubleNumber(-std::numeric_limits<double>::infinity()), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier(&vm, "POSITIVE_INFINITY"), jsDoubleNumber(std::numeric_limits<double>::infinity()), DontDelete | DontEnum | ReadOnly);
+    putDirectWithoutTransition(vm, Identifier(&vm, "NaN"), jsNaN(), DontDelete | DontEnum | ReadOnly);
+
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier(&vm, "isFinite"), 1, numberConstructorFuncIsFinite, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier(&vm, "isInteger"), 1, numberConstructorFuncIsInteger, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier(&vm, "isNaN"), 1, numberConstructorFuncIsNaN, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier(&vm, "isSafeInteger"), 1, numberConstructorFuncIsSafeInteger, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier(&vm, "parseFloat"), 1, globalFuncParseFloat, NoIntrinsic, DontEnum | Function);
+    putDirectNativeFunctionWithoutTransition(vm, numberPrototype->globalObject(), Identifier(&vm, "parseInt"), 1, globalFuncParseInt, NoIntrinsic, DontEnum | Function);
 }
 
 // ECMA 15.7.1
@@ -129,4 +103,50 @@ CallType NumberConstructor::getCallData(JSCell*, CallData& callData)
     return CallTypeHost;
 }
 
+// ECMA-262 20.1.2.2
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsFinite(ExecState* exec)
+{
+    JSValue argument = exec->argument(0);
+    return JSValue::encode(jsBoolean(argument.isNumber() && (argument.isInt32() || std::isfinite(argument.asDouble()))));
+}
+
+// ECMA-262 20.1.2.3
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsInteger(ExecState* exec)
+{
+    JSValue argument = exec->argument(0);
+    bool isInteger;
+    if (argument.isInt32())
+        isInteger = true;
+    else if (!argument.isDouble())
+        isInteger = false;
+    else {
+        double number = argument.asDouble();
+        isInteger = std::isfinite(number) && trunc(number) == number;
+    }
+    return JSValue::encode(jsBoolean(isInteger));
+}
+
+// ECMA-262 20.1.2.4
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsNaN(ExecState* exec)
+{
+    JSValue argument = exec->argument(0);
+    return JSValue::encode(jsBoolean(argument.isDouble() && std::isnan(argument.asDouble())));
+}
+
+// ECMA-262 20.1.2.5
+static EncodedJSValue JSC_HOST_CALL numberConstructorFuncIsSafeInteger(ExecState* exec)
+{
+    JSValue argument = exec->argument(0);
+    bool isInteger;
+    if (argument.isInt32())
+        isInteger = true;
+    else if (!argument.isDouble())
+        isInteger = false;
+    else {
+        double number = argument.asDouble();
+        isInteger = trunc(number) == number && std::abs(number) <= 9007199254740991.0;
+    }
+    return JSValue::encode(jsBoolean(isInteger));
+}
+
 } // namespace JSC
index 8826e9c..630f5e5 100644 (file)
@@ -38,9 +38,6 @@ public:
         return constructor;
     }
 
-    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
-    JSValue getValueProperty(ExecState*, int token) const;
-
     DECLARE_INFO;
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 
@@ -48,8 +45,6 @@ public:
         return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info()); 
     }
 
-    enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
-
 protected:
     void finishCreation(VM&, NumberPrototype*);
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;