summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/builtins
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/builtins
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/builtins')
-rw-r--r--Source/JavaScriptCore/builtins/ArrayConstructor.js114
-rw-r--r--Source/JavaScriptCore/builtins/ArrayIteratorPrototype.js108
-rw-r--r--Source/JavaScriptCore/builtins/ArrayPrototype.js782
-rw-r--r--Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js58
-rw-r--r--Source/JavaScriptCore/builtins/BuiltinExecutableCreator.cpp38
-rw-r--r--Source/JavaScriptCore/builtins/BuiltinExecutableCreator.h36
-rw-r--r--Source/JavaScriptCore/builtins/BuiltinExecutables.cpp127
-rw-r--r--Source/JavaScriptCore/builtins/BuiltinExecutables.h69
-rw-r--r--Source/JavaScriptCore/builtins/BuiltinNames.h278
-rw-r--r--Source/JavaScriptCore/builtins/BuiltinUtils.h51
-rw-r--r--Source/JavaScriptCore/builtins/DatePrototype.js182
-rw-r--r--Source/JavaScriptCore/builtins/FunctionPrototype.js95
-rw-r--r--Source/JavaScriptCore/builtins/GeneratorPrototype.js86
-rw-r--r--Source/JavaScriptCore/builtins/GlobalObject.js46
-rw-r--r--Source/JavaScriptCore/builtins/GlobalOperations.js81
-rw-r--r--Source/JavaScriptCore/builtins/InspectorInstrumentationObject.js40
-rw-r--r--Source/JavaScriptCore/builtins/InternalPromiseConstructor.js86
-rw-r--r--Source/JavaScriptCore/builtins/IteratorHelpers.js46
-rw-r--r--Source/JavaScriptCore/builtins/IteratorPrototype.js31
-rw-r--r--Source/JavaScriptCore/builtins/MapPrototype.js46
-rw-r--r--Source/JavaScriptCore/builtins/ModuleLoaderPrototype.js477
-rw-r--r--Source/JavaScriptCore/builtins/NumberConstructor.js45
-rw-r--r--Source/JavaScriptCore/builtins/NumberPrototype.js45
-rw-r--r--Source/JavaScriptCore/builtins/ObjectConstructor.js93
-rw-r--r--Source/JavaScriptCore/builtins/PromiseConstructor.js131
-rw-r--r--Source/JavaScriptCore/builtins/PromiseOperations.js224
-rw-r--r--Source/JavaScriptCore/builtins/PromisePrototype.js59
-rw-r--r--Source/JavaScriptCore/builtins/ReflectObject.js61
-rw-r--r--Source/JavaScriptCore/builtins/RegExpPrototype.js529
-rw-r--r--Source/JavaScriptCore/builtins/SetPrototype.js46
-rw-r--r--Source/JavaScriptCore/builtins/StringConstructor.js60
-rw-r--r--Source/JavaScriptCore/builtins/StringIteratorPrototype.js64
-rw-r--r--Source/JavaScriptCore/builtins/StringPrototype.js300
-rw-r--r--Source/JavaScriptCore/builtins/TypedArrayConstructor.js167
-rw-r--r--Source/JavaScriptCore/builtins/TypedArrayPrototype.js413
35 files changed, 5114 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/builtins/ArrayConstructor.js b/Source/JavaScriptCore/builtins/ArrayConstructor.js
new file mode 100644
index 000000000..73add1a70
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/ArrayConstructor.js
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function of(/* items... */)
+{
+ "use strict";
+
+ var length = arguments.length;
+ var array = @isConstructor(this) ? new this(length) : @newArrayWithSize(length);
+ for (var k = 0; k < length; ++k)
+ @putByValDirect(array, k, arguments[k]);
+ array.length = length;
+ return array;
+}
+
+function from(items /*, mapFn, thisArg */)
+{
+ "use strict";
+
+ var thisObj = this;
+
+ var mapFn = @argument(1);
+
+ var thisArg;
+
+ if (mapFn !== @undefined) {
+ if (typeof mapFn !== "function")
+ @throwTypeError("Array.from requires that the second argument, when provided, be a function");
+
+ thisArg = @argument(2);
+ }
+
+ if (items == null)
+ @throwTypeError("Array.from requires an array-like object - not null or undefined");
+
+ var iteratorMethod = items.@iteratorSymbol;
+ if (iteratorMethod != null) {
+ if (typeof iteratorMethod !== "function")
+ @throwTypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
+
+ var result = @isConstructor(thisObj) ? new thisObj() : [];
+
+ var k = 0;
+ var iterator = iteratorMethod.@call(items);
+
+ // Since for-of loop once more looks up the @@iterator property of a given iterable,
+ // it could be observable if the user defines a getter for @@iterator.
+ // To avoid this situation, we define a wrapper object that @@iterator just returns a given iterator.
+ var wrapper = {}
+ wrapper.@iteratorSymbol = function() { return iterator; };
+
+ for (var value of wrapper) {
+ if (mapFn)
+ @putByValDirect(result, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
+ else
+ @putByValDirect(result, k, value);
+ k += 1;
+ }
+
+ result.length = k;
+ return result;
+ }
+
+ var arrayLike = @Object(items);
+ var arrayLikeLength = @toLength(arrayLike.length);
+
+ var result = @isConstructor(thisObj) ? new thisObj(arrayLikeLength) : @newArrayWithSize(arrayLikeLength);
+
+ var k = 0;
+ while (k < arrayLikeLength) {
+ var value = arrayLike[k];
+ if (mapFn)
+ @putByValDirect(result, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
+ else
+ @putByValDirect(result, k, value);
+ k += 1;
+ }
+
+ result.length = arrayLikeLength;
+ return result;
+}
+
+function isArray(array)
+{
+ "use strict";
+
+ if (@isJSArray(array) || @isDerivedArray(array))
+ return true;
+ if (!@isProxyObject(array))
+ return false;
+ return @isArraySlow(array);
+}
diff --git a/Source/JavaScriptCore/builtins/ArrayIteratorPrototype.js b/Source/JavaScriptCore/builtins/ArrayIteratorPrototype.js
new file mode 100644
index 000000000..92640f7c8
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/ArrayIteratorPrototype.js
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function next()
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("%ArrayIteratorPrototype%.next requires that |this| not be null or undefined");
+
+ let next = this.@arrayIteratorNext;
+ if (next === @undefined)
+ @throwTypeError("%ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance");
+
+ return next.@call(this);
+}
+
+@globalPrivate
+function arrayIteratorValueNext()
+{
+ "use strict";
+ var done = true;
+ var value;
+
+ var array = this.@iteratedObject;
+ if (!this.@arrayIteratorIsDone) {
+ var index = this.@arrayIteratorNextIndex;
+ var length = array.length >>> 0;
+ if (index >= length) {
+ this.@arrayIteratorIsDone = true;
+ } else {
+ this.@arrayIteratorNextIndex = index + 1;
+ done = false;
+ value = array[index];
+ }
+ }
+
+ return { done, value };
+}
+
+@globalPrivate
+function arrayIteratorKeyNext()
+{
+ "use strict";
+ var done = true;
+ var value;
+
+ var array = this.@iteratedObject;
+ if (!this.@arrayIteratorIsDone) {
+ var index = this.@arrayIteratorNextIndex;
+ var length = array.length >>> 0;
+ if (index >= length) {
+ this.@arrayIteratorIsDone = true;
+ } else {
+ this.@arrayIteratorNextIndex = index + 1;
+ done = false;
+ value = index;
+ }
+ }
+
+ return { done, value };
+}
+
+@globalPrivate
+function arrayIteratorKeyValueNext()
+{
+ "use strict";
+ var done = true;
+ var value;
+
+ var array = this.@iteratedObject;
+ if (!this.@arrayIteratorIsDone) {
+ var index = this.@arrayIteratorNextIndex;
+ var length = array.length >>> 0;
+ if (index >= length) {
+ this.@arrayIteratorIsDone = true;
+ } else {
+ this.@arrayIteratorNextIndex = index + 1;
+ done = false;
+ value = [ index, array[index] ];
+ }
+ }
+
+ return { done, value };
+}
diff --git a/Source/JavaScriptCore/builtins/ArrayPrototype.js b/Source/JavaScriptCore/builtins/ArrayPrototype.js
new file mode 100644
index 000000000..b9f835562
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/ArrayPrototype.js
@@ -0,0 +1,782 @@
+/*
+ * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+@constructor
+@globalPrivate
+function createArrayIterator(iteratedObject, kind, iterationFunction)
+{
+ this.@iteratedObject = iteratedObject;
+ this.@arrayIteratorKind = kind;
+ this.@arrayIteratorNextIndex = 0;
+ this.@arrayIteratorNext = iterationFunction;
+ this.@arrayIteratorIsDone = false;
+}
+
+function values()
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.values requires that |this| not be null or undefined");
+
+ return new @createArrayIterator(@Object(this), "value", @arrayIteratorValueNext);
+}
+
+function keys()
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.keys requires that |this| not be null or undefined");
+
+ return new @createArrayIterator(@Object(this), "key", @arrayIteratorKeyNext);
+}
+
+function entries()
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.entries requires that |this| not be null or undefined");
+
+ return new @createArrayIterator(@Object(this), "key+value", @arrayIteratorKeyValueNext);
+}
+
+function reduce(callback /*, initialValue */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.reduce requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.reduce callback must be a function");
+
+ var argumentCount = @argumentCount();
+ if (length === 0 && argumentCount < 2)
+ @throwTypeError("reduce of empty array with no initial value");
+
+ var accumulator, k = 0;
+ if (argumentCount > 1)
+ accumulator = @argument(1);
+ else {
+ while (k < length && !(k in array))
+ k += 1;
+ if (k >= length)
+ @throwTypeError("reduce of empty array with no initial value");
+ accumulator = array[k++];
+ }
+
+ while (k < length) {
+ if (k in array)
+ accumulator = callback.@call(@undefined, accumulator, array[k], k, array);
+ k += 1;
+ }
+ return accumulator;
+}
+
+function reduceRight(callback /*, initialValue */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.reduceRight requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.reduceRight callback must be a function");
+
+ var argumentCount = @argumentCount();
+ if (length === 0 && argumentCount < 2)
+ @throwTypeError("reduceRight of empty array with no initial value");
+
+ var accumulator, k = length - 1;
+ if (argumentCount > 1)
+ accumulator = @argument(1);
+ else {
+ while (k >= 0 && !(k in array))
+ k -= 1;
+ if (k < 0)
+ @throwTypeError("reduceRight of empty array with no initial value");
+ accumulator = array[k--];
+ }
+
+ while (k >= 0) {
+ if (k in array)
+ accumulator = callback.@call(@undefined, accumulator, array[k], k, array);
+ k -= 1;
+ }
+ return accumulator;
+}
+
+function every(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.every requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.every callback must be a function");
+
+ var thisArg = @argument(1);
+
+ for (var i = 0; i < length; i++) {
+ if (!(i in array))
+ continue;
+ if (!callback.@call(thisArg, array[i], i, array))
+ return false;
+ }
+
+ return true;
+}
+
+function forEach(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.forEach requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.forEach callback must be a function");
+
+ var thisArg = @argument(1);
+
+ for (var i = 0; i < length; i++) {
+ if (i in array)
+ callback.@call(thisArg, array[i], i, array);
+ }
+}
+
+function filter(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.filter requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.filter callback must be a function");
+
+ var thisArg = @argument(1);
+
+ // Do 9.4.2.3 ArraySpeciesCreate
+ var result;
+ var constructor;
+ if (@isArray(array)) {
+ constructor = array.constructor;
+ // We have this check so that if some array from a different global object
+ // calls this map they don't get an array with the Array.prototype of the
+ // other global object.
+ if (@isArrayConstructor(constructor) && @Array !== constructor)
+ constructor = @undefined;
+ if (@isObject(constructor)) {
+ constructor = constructor.@speciesSymbol;
+ if (constructor === null)
+ constructor = @undefined;
+ }
+ }
+ if (constructor === @Array || constructor === @undefined)
+ result = @newArrayWithSize(0);
+ else
+ result = new constructor(0);
+
+ var nextIndex = 0;
+ for (var i = 0; i < length; i++) {
+ if (!(i in array))
+ continue;
+ var current = array[i]
+ if (callback.@call(thisArg, current, i, array)) {
+ @putByValDirect(result, nextIndex, current);
+ ++nextIndex;
+ }
+ }
+ return result;
+}
+
+function map(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.map requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.map callback must be a function");
+
+ var thisArg = @argument(1);
+
+ // Do 9.4.2.3 ArraySpeciesCreate
+ var result;
+ var constructor;
+ if (@isArray(array)) {
+ constructor = array.constructor;
+ // We have this check so that if some array from a different global object
+ // calls this map they don't get an array with the Array.prototype of the
+ // other global object.
+ if (@isArrayConstructor(constructor) && @Array !== constructor)
+ constructor = @undefined;
+ if (@isObject(constructor)) {
+ constructor = constructor.@speciesSymbol;
+ if (constructor === null)
+ constructor = @undefined;
+ }
+ }
+ if (constructor === @Array || constructor === @undefined)
+ result = @newArrayWithSize(length);
+ else
+ result = new constructor(length);
+
+ var nextIndex = 0;
+ for (var i = 0; i < length; i++) {
+ if (!(i in array))
+ continue;
+ var mappedValue = callback.@call(thisArg, array[i], i, array);
+ @putByValDirect(result, i, mappedValue);
+ }
+ return result;
+}
+
+function some(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.some requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.some callback must be a function");
+
+ var thisArg = @argument(1);
+ for (var i = 0; i < length; i++) {
+ if (!(i in array))
+ continue;
+ if (callback.@call(thisArg, array[i], i, array))
+ return true;
+ }
+ return false;
+}
+
+function fill(value /* [, start [, end]] */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.fill requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ var relativeStart = @toInteger(@argument(1));
+ var k = 0;
+ if (relativeStart < 0) {
+ k = length + relativeStart;
+ if (k < 0)
+ k = 0;
+ } else {
+ k = relativeStart;
+ if (k > length)
+ k = length;
+ }
+ var relativeEnd = length;
+ var end = @argument(2);
+ if (end !== @undefined)
+ relativeEnd = @toInteger(end);
+ var final = 0;
+ if (relativeEnd < 0) {
+ final = length + relativeEnd;
+ if (final < 0)
+ final = 0;
+ } else {
+ final = relativeEnd;
+ if (final > length)
+ final = length;
+ }
+ for (; k < final; k++)
+ array[k] = value;
+ return array;
+}
+
+function find(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.find requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.find callback must be a function");
+
+ var thisArg = @argument(1);
+ for (var i = 0; i < length; i++) {
+ var kValue = array[i];
+ if (callback.@call(thisArg, kValue, i, array))
+ return kValue;
+ }
+ return @undefined;
+}
+
+function findIndex(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.findIndex requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.findIndex callback must be a function");
+
+ var thisArg = @argument(1);
+ for (var i = 0; i < length; i++) {
+ if (callback.@call(thisArg, array[i], i, array))
+ return i;
+ }
+ return -1;
+}
+
+function includes(searchElement /*, fromIndex*/)
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.includes requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ if (length === 0)
+ return false;
+
+ var fromIndex = 0;
+ var from = @argument(1);
+ if (from !== @undefined)
+ fromIndex = @toInteger(from);
+
+ var index;
+ if (fromIndex >= 0)
+ index = fromIndex;
+ else
+ index = length + fromIndex;
+
+ if (index < 0)
+ index = 0;
+
+ var currentElement;
+ for (; index < length; ++index) {
+ currentElement = array[index];
+ // Use SameValueZero comparison, rather than just StrictEquals.
+ if (searchElement === currentElement || (searchElement !== searchElement && currentElement !== currentElement))
+ return true;
+ }
+ return false;
+}
+
+function sort(comparator)
+{
+ "use strict";
+
+ function min(a, b)
+ {
+ return a < b ? a : b;
+ }
+
+ function stringComparator(a, b)
+ {
+ var aString = a.string;
+ var bString = b.string;
+
+ var aLength = aString.length;
+ var bLength = bString.length;
+ var length = min(aLength, bLength);
+
+ for (var i = 0; i < length; ++i) {
+ var aCharCode = aString.@charCodeAt(i);
+ var bCharCode = bString.@charCodeAt(i);
+
+ if (aCharCode == bCharCode)
+ continue;
+
+ return aCharCode - bCharCode;
+ }
+
+ return aLength - bLength;
+ }
+
+ // Move undefineds and holes to the end of a sparse array. Result is [values..., undefineds..., holes...].
+ function compactSparse(array, dst, src, length)
+ {
+ var values = [ ];
+ var seen = { };
+ var valueCount = 0;
+ var undefinedCount = 0;
+
+ // Clean up after the in-progress non-sparse compaction that failed.
+ for (var i = dst; i < src; ++i)
+ delete array[i];
+
+ for (var object = array; object; object = @Object.@getPrototypeOf(object)) {
+ var propertyNames = @Object.@getOwnPropertyNames(object);
+ for (var i = 0; i < propertyNames.length; ++i) {
+ var index = propertyNames[i];
+ if (index < length) { // Exclude non-numeric properties and properties past length.
+ if (seen[index]) // Exclude duplicates.
+ continue;
+ seen[index] = 1;
+
+ var value = array[index];
+ delete array[index];
+
+ if (value === @undefined) {
+ ++undefinedCount;
+ continue;
+ }
+
+ array[valueCount++] = value;
+ }
+ }
+ }
+
+ for (var i = valueCount; i < valueCount + undefinedCount; ++i)
+ array[i] = @undefined;
+
+ return valueCount;
+ }
+
+ function compactSlow(array, length)
+ {
+ var holeCount = 0;
+
+ for (var dst = 0, src = 0; src < length; ++src) {
+ if (!(src in array)) {
+ ++holeCount;
+ if (holeCount < 256)
+ continue;
+ return compactSparse(array, dst, src, length);
+ }
+
+ var value = array[src];
+ if (value === @undefined)
+ continue;
+
+ array[dst++] = value;
+ }
+
+ var valueCount = dst;
+ var undefinedCount = length - valueCount - holeCount;
+
+ for (var i = valueCount; i < valueCount + undefinedCount; ++i)
+ array[i] = @undefined;
+
+ for (var i = valueCount + undefinedCount; i < length; ++i)
+ delete array[i];
+
+ return valueCount;
+ }
+
+ // Move undefineds and holes to the end of an array. Result is [values..., undefineds..., holes...].
+ function compact(array, length)
+ {
+ for (var i = 0; i < array.length; ++i) {
+ if (array[i] === @undefined)
+ return compactSlow(array, length);
+ }
+
+ return length;
+ }
+
+ function merge(dst, src, srcIndex, srcEnd, width, comparator)
+ {
+ var left = srcIndex;
+ var leftEnd = min(left + width, srcEnd);
+ var right = leftEnd;
+ var rightEnd = min(right + width, srcEnd);
+
+ for (var dstIndex = left; dstIndex < rightEnd; ++dstIndex) {
+ if (right < rightEnd) {
+ if (left >= leftEnd || comparator(src[right], src[left]) < 0) {
+ dst[dstIndex] = src[right++];
+ continue;
+ }
+ }
+
+ dst[dstIndex] = src[left++];
+ }
+ }
+
+ function mergeSort(array, valueCount, comparator)
+ {
+ var buffer = [ ];
+ buffer.length = valueCount;
+
+ var dst = buffer;
+ var src = array;
+ for (var width = 1; width < valueCount; width *= 2) {
+ for (var srcIndex = 0; srcIndex < valueCount; srcIndex += 2 * width)
+ merge(dst, src, srcIndex, valueCount, width, comparator);
+
+ var tmp = src;
+ src = dst;
+ dst = tmp;
+ }
+
+ if (src != array) {
+ for(var i = 0; i < valueCount; i++)
+ array[i] = src[i];
+ }
+ }
+
+ function bucketSort(array, dst, bucket, depth)
+ {
+ if (bucket.length < 32 || depth > 32) {
+ mergeSort(bucket, bucket.length, stringComparator);
+ for (var i = 0; i < bucket.length; ++i)
+ array[dst++] = bucket[i].value;
+ return dst;
+ }
+
+ var buckets = [ ];
+ for (var i = 0; i < bucket.length; ++i) {
+ var entry = bucket[i];
+ var string = entry.string;
+ if (string.length == depth) {
+ array[dst++] = entry.value;
+ continue;
+ }
+
+ var c = string.@charCodeAt(depth);
+ if (!buckets[c])
+ buckets[c] = [ ];
+ buckets[c][buckets[c].length] = entry;
+ }
+
+ for (var i = 0; i < buckets.length; ++i) {
+ if (!buckets[i])
+ continue;
+ dst = bucketSort(array, dst, buckets[i], depth + 1);
+ }
+
+ return dst;
+ }
+
+ function comparatorSort(array, length, comparator)
+ {
+ var valueCount = compact(array, length);
+ mergeSort(array, valueCount, comparator);
+ }
+
+ function stringSort(array, length)
+ {
+ var valueCount = compact(array, length);
+
+ var strings = @newArrayWithSize(valueCount);
+ for (var i = 0; i < valueCount; ++i)
+ strings[i] = { string: @toString(array[i]), value: array[i] };
+
+ bucketSort(array, 0, strings, 0);
+ }
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.sort requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+
+ var length = array.length >>> 0;
+
+ // For compatibility with Firefox and Chrome, do nothing observable
+ // to the target array if it has 0 or 1 sortable properties.
+ if (length < 2)
+ return array;
+
+ if (typeof comparator == "function")
+ comparatorSort(array, length, comparator);
+ else if (comparator === @undefined)
+ stringSort(array, length);
+ else
+ @throwTypeError("Array.prototype.sort requires the comparsion function be a function or undefined");
+
+ return array;
+}
+
+function concatSlowPath()
+{
+ "use strict";
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.prototype.concat requires that |this| not be null or undefined");
+
+ var currentElement = @Object(this);
+
+ var constructor;
+ if (@isArray(currentElement)) {
+ constructor = currentElement.constructor;
+ // We have this check so that if some array from a different global object
+ // calls this map they don't get an array with the Array.prototype of the
+ // other global object.
+ if (@isArrayConstructor(constructor) && @Array !== constructor)
+ constructor = @undefined;
+ else if (@isObject(constructor)) {
+ constructor = constructor.@speciesSymbol;
+ if (constructor === null)
+ constructor = @Array;
+ }
+ }
+
+ var argCount = arguments.length;
+ var result;
+ if (constructor === @Array || constructor === @undefined)
+ result = @newArrayWithSize(0);
+ else
+ result = new constructor(0);
+ var resultIsArray = @isJSArray(result);
+
+ var resultIndex = 0;
+ var argIndex = 0;
+
+ do {
+ let spreadable = @isObject(currentElement) && currentElement.@isConcatSpreadableSymbol;
+ if ((spreadable === @undefined && @isArray(currentElement)) || spreadable) {
+ let length = @toLength(currentElement.length);
+ if (length + resultIndex > @MAX_ARRAY_INDEX)
+ @throwRangeError("Length exceeded the maximum array length");
+ if (resultIsArray && @isJSArray(currentElement)) {
+ @appendMemcpy(result, currentElement, resultIndex);
+ resultIndex += length;
+ } else {
+ for (var i = 0; i < length; i++) {
+ if (i in currentElement)
+ @putByValDirect(result, resultIndex, currentElement[i]);
+ resultIndex++;
+ }
+ }
+ } else {
+ if (resultIndex >= @MAX_ARRAY_INDEX)
+ @throwRangeError("Length exceeded the maximum array length");
+ @putByValDirect(result, resultIndex++, currentElement);
+ }
+ currentElement = arguments[argIndex];
+ } while (argIndex++ < argCount);
+
+ result.length = resultIndex;
+ return result;
+}
+
+function concat(first)
+{
+ "use strict";
+
+ if (@argumentCount() === 1
+ && @isJSArray(this)
+ && this.@isConcatSpreadableSymbol === @undefined
+ && (!@isObject(first) || first.@isConcatSpreadableSymbol === @undefined)) {
+
+ let result = @concatMemcpy(this, first);
+ if (result !== null)
+ return result;
+ }
+
+ return @tailCallForwardArguments(@concatSlowPath, this);
+}
+
+function copyWithin(target, start /*, end */)
+{
+ "use strict";
+
+ function maxWithPositives(a, b)
+ {
+ return (a < b) ? b : a;
+ }
+
+ function minWithMaybeNegativeZeroAndPositive(maybeNegativeZero, positive)
+ {
+ return (maybeNegativeZero < positive) ? maybeNegativeZero : positive;
+ }
+
+ if (this === null || this === @undefined)
+ @throwTypeError("Array.copyWithin requires that |this| not be null or undefined");
+
+ var array = @Object(this);
+ var length = @toLength(array.length);
+
+ var relativeTarget = @toInteger(target);
+ var to = (relativeTarget < 0) ? maxWithPositives(length + relativeTarget, 0) : minWithMaybeNegativeZeroAndPositive(relativeTarget, length);
+
+ var relativeStart = @toInteger(start);
+ var from = (relativeStart < 0) ? maxWithPositives(length + relativeStart, 0) : minWithMaybeNegativeZeroAndPositive(relativeStart, length);
+
+ var relativeEnd;
+ var end = @argument(2);
+ if (end === @undefined)
+ relativeEnd = length;
+ else
+ relativeEnd = @toInteger(end);
+
+ var finalValue = (relativeEnd < 0) ? maxWithPositives(length + relativeEnd, 0) : minWithMaybeNegativeZeroAndPositive(relativeEnd, length);
+
+ var count = minWithMaybeNegativeZeroAndPositive(finalValue - from, length - to);
+
+ var direction = 1;
+ if (from < to && to < from + count) {
+ direction = -1;
+ from = from + count - 1;
+ to = to + count - 1;
+ }
+
+ for (var i = 0; i < count; ++i, from += direction, to += direction) {
+ if (from in array)
+ array[to] = array[from];
+ else
+ delete array[to];
+ }
+
+ return array;
+}
diff --git a/Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js b/Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js
new file mode 100644
index 000000000..88cfb01d1
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 Caitlin Potter <caitp@igalia.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+@globalPrivate
+function asyncFunctionResume(generator, promiseCapability, sentValue, resumeMode)
+{
+ "use strict";
+ let state = generator.@generatorState;
+ let value = @undefined;
+
+ if (state === @GeneratorStateCompleted || (resumeMode !== @GeneratorResumeModeNormal && resumeMode !== @GeneratorResumeModeThrow))
+ @throwTypeError("Async function illegally resumed");
+
+ try {
+ generator.@generatorState = @GeneratorStateExecuting;
+ value = generator.@generatorNext.@call(generator.@generatorThis, generator, state, sentValue, resumeMode, generator.@generatorFrame);
+ if (generator.@generatorState === @GeneratorStateExecuting) {
+ generator.@generatorState = @GeneratorStateCompleted;
+ promiseCapability.@resolve(value);
+ return promiseCapability.@promise;
+ }
+ } catch (error) {
+ generator.@generatorState = @GeneratorStateCompleted;
+ promiseCapability.@reject(error);
+ return promiseCapability.@promise;
+ }
+
+ let wrappedValue = @newPromiseCapability(@Promise);
+ wrappedValue.@resolve.@call(@undefined, value);
+
+ wrappedValue.@promise.@then(
+ function(value) { @asyncFunctionResume(generator, promiseCapability, value, @GeneratorResumeModeNormal); },
+ function(error) { @asyncFunctionResume(generator, promiseCapability, error, @GeneratorResumeModeThrow); });
+
+ return promiseCapability.@promise;
+}
diff --git a/Source/JavaScriptCore/builtins/BuiltinExecutableCreator.cpp b/Source/JavaScriptCore/builtins/BuiltinExecutableCreator.cpp
new file mode 100644
index 000000000..2b79e7e6e
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/BuiltinExecutableCreator.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BuiltinExecutableCreator.h"
+
+#include "BuiltinExecutables.h"
+
+namespace JSC {
+
+UnlinkedFunctionExecutable* createBuiltinExecutable(VM& vm, const SourceCode& source, const Identifier& ident, ConstructorKind kind, ConstructAbility ability)
+{
+ return BuiltinExecutables::createExecutable(vm, source, ident, kind, ability);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/builtins/BuiltinExecutableCreator.h b/Source/JavaScriptCore/builtins/BuiltinExecutableCreator.h
new file mode 100644
index 000000000..19c0884b7
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/BuiltinExecutableCreator.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ConstructAbility.h"
+#include "ParserModes.h"
+#include "SourceCode.h"
+
+namespace JSC {
+
+JS_EXPORT_PRIVATE UnlinkedFunctionExecutable* createBuiltinExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility);
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp b/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
new file mode 100644
index 000000000..a5be5c995
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "BuiltinExecutables.h"
+
+#include "BuiltinNames.h"
+#include "JSCInlines.h"
+#include "Parser.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace JSC {
+
+BuiltinExecutables::BuiltinExecutables(VM& vm)
+ : m_vm(vm)
+#define INITIALIZE_BUILTIN_SOURCE_MEMBERS(name, functionName, length) , m_##name##Source(makeSource(StringImpl::createFromLiteral(s_##name, length), { }))
+ JSC_FOREACH_BUILTIN_CODE(INITIALIZE_BUILTIN_SOURCE_MEMBERS)
+#undef EXPOSE_BUILTIN_STRINGS
+{
+}
+
+UnlinkedFunctionExecutable* BuiltinExecutables::createDefaultConstructor(ConstructorKind constructorKind, const Identifier& name)
+{
+ static NeverDestroyed<const String> baseConstructorCode(ASCIILiteral("(function () { })"));
+ static NeverDestroyed<const String> derivedConstructorCode(ASCIILiteral("(function (...args) { super(...args); })"));
+
+ switch (constructorKind) {
+ case ConstructorKind::None:
+ break;
+ case ConstructorKind::Base:
+ return createExecutable(m_vm, makeSource(baseConstructorCode, { }), name, constructorKind, ConstructAbility::CanConstruct);
+ case ConstructorKind::Extends:
+ return createExecutable(m_vm, makeSource(derivedConstructorCode, { }), name, constructorKind, ConstructAbility::CanConstruct);
+ }
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+UnlinkedFunctionExecutable* BuiltinExecutables::createBuiltinExecutable(const SourceCode& code, const Identifier& name, ConstructAbility constructAbility)
+{
+ return createExecutable(m_vm, code, name, ConstructorKind::None, constructAbility);
+}
+
+UnlinkedFunctionExecutable* createBuiltinExecutable(VM& vm, const SourceCode& code, const Identifier& name, ConstructAbility constructAbility)
+{
+ return BuiltinExecutables::createExecutable(vm, code, name, ConstructorKind::None, constructAbility);
+}
+
+UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility)
+{
+ JSTextPosition positionBeforeLastNewline;
+ ParserError error;
+ bool isParsingDefaultConstructor = constructorKind != ConstructorKind::None;
+ JSParserBuiltinMode builtinMode = isParsingDefaultConstructor ? JSParserBuiltinMode::NotBuiltin : JSParserBuiltinMode::Builtin;
+ UnlinkedFunctionKind kind = isParsingDefaultConstructor ? UnlinkedNormalFunction : UnlinkedBuiltinFunction;
+ SourceCode parentSourceOverride = isParsingDefaultConstructor ? source : SourceCode();
+ std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
+ &vm, source, Identifier(), builtinMode,
+ JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error,
+ &positionBeforeLastNewline, constructorKind);
+
+ if (!program) {
+ dataLog("Fatal error compiling builtin function '", name.string(), "': ", error.message());
+ CRASH();
+ }
+
+ StatementNode* exprStatement = program->singleStatement();
+ RELEASE_ASSERT(exprStatement);
+ RELEASE_ASSERT(exprStatement->isExprStatement());
+ ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
+ RELEASE_ASSERT(funcExpr);
+ RELEASE_ASSERT(funcExpr->isFuncExprNode());
+ FunctionMetadataNode* metadata = static_cast<FuncExprNode*>(funcExpr)->metadata();
+ RELEASE_ASSERT(!program->hasCapturedVariables());
+
+ metadata->setEndPosition(positionBeforeLastNewline);
+ RELEASE_ASSERT(metadata);
+ RELEASE_ASSERT(metadata->ident().isNull());
+
+ // This function assumes an input string that would result in a single anonymous function expression.
+ metadata->setEndPosition(positionBeforeLastNewline);
+ RELEASE_ASSERT(metadata);
+ metadata->overrideName(name);
+ VariableEnvironment dummyTDZVariables;
+ UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, JSParserScriptMode::Classic, dummyTDZVariables, DerivedContextType::None, WTFMove(parentSourceOverride));
+ return functionExecutable;
+}
+
+void BuiltinExecutables::finalize(Handle<Unknown>, void* context)
+{
+ static_cast<Weak<UnlinkedFunctionExecutable>*>(context)->clear();
+}
+
+#define DEFINE_BUILTIN_EXECUTABLES(name, functionName, length) \
+UnlinkedFunctionExecutable* BuiltinExecutables::name##Executable() \
+{\
+ if (!m_##name##Executable)\
+ m_##name##Executable = Weak<UnlinkedFunctionExecutable>(createBuiltinExecutable(m_##name##Source, m_vm.propertyNames->builtinNames().functionName##PublicName(), s_##name##ConstructAbility), this, &m_##name##Executable);\
+ return m_##name##Executable.get();\
+}
+JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_EXECUTABLES)
+#undef EXPOSE_BUILTIN_SOURCES
+
+}
diff --git a/Source/JavaScriptCore/builtins/BuiltinExecutables.h b/Source/JavaScriptCore/builtins/BuiltinExecutables.h
new file mode 100644
index 000000000..ee0eaad02
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/BuiltinExecutables.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSCBuiltins.h"
+#include "ParserModes.h"
+#include "SourceCode.h"
+#include "Weak.h"
+#include "WeakHandleOwner.h"
+
+namespace JSC {
+
+class UnlinkedFunctionExecutable;
+class Identifier;
+class VM;
+
+class BuiltinExecutables final: private WeakHandleOwner {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit BuiltinExecutables(VM&);
+
+#define EXPOSE_BUILTIN_EXECUTABLES(name, functionName, length) \
+UnlinkedFunctionExecutable* name##Executable(); \
+const SourceCode& name##Source() { return m_##name##Source; }
+
+ JSC_FOREACH_BUILTIN_CODE(EXPOSE_BUILTIN_EXECUTABLES)
+#undef EXPOSE_BUILTIN_SOURCES
+
+ UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name);
+
+ static UnlinkedFunctionExecutable* createExecutable(VM&, const SourceCode&, const Identifier&, ConstructorKind, ConstructAbility);
+private:
+ void finalize(Handle<Unknown>, void* context) override;
+
+ VM& m_vm;
+
+ UnlinkedFunctionExecutable* createBuiltinExecutable(const SourceCode&, const Identifier&, ConstructAbility);
+
+#define DECLARE_BUILTIN_SOURCE_MEMBERS(name, functionName, length)\
+ SourceCode m_##name##Source; \
+ Weak<UnlinkedFunctionExecutable> m_##name##Executable;
+ JSC_FOREACH_BUILTIN_CODE(DECLARE_BUILTIN_SOURCE_MEMBERS)
+#undef DECLARE_BUILTIN_SOURCE_MEMBERS
+};
+
+}
diff --git a/Source/JavaScriptCore/builtins/BuiltinNames.h b/Source/JavaScriptCore/builtins/BuiltinNames.h
new file mode 100644
index 000000000..03aa44c68
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/BuiltinNames.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "BuiltinUtils.h"
+#include "BytecodeIntrinsicRegistry.h"
+#include "CommonIdentifiers.h"
+#include "JSCBuiltins.h"
+
+namespace JSC {
+
+#define JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
+ JSC_COMMON_BYTECODE_INTRINSIC_FUNCTIONS_EACH_NAME(macro) \
+ JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(macro) \
+ macro(arrayIteratorNextIndex) \
+ macro(arrayIterationKind) \
+ macro(arrayIteratorNext) \
+ macro(arrayIteratorIsDone) \
+ macro(arrayIteratorKind) \
+ macro(charCodeAt) \
+ macro(isView) \
+ macro(iteratedObject) \
+ macro(iteratedString) \
+ macro(stringIteratorNextIndex) \
+ macro(promise) \
+ macro(fulfillmentHandler) \
+ macro(rejectionHandler) \
+ macro(index) \
+ macro(deferred) \
+ macro(countdownHolder) \
+ macro(Object) \
+ macro(ownEnumerablePropertyKeys) \
+ macro(Number) \
+ macro(Array) \
+ macro(ArrayBuffer) \
+ macro(String) \
+ macro(RegExp) \
+ macro(Map) \
+ macro(Promise) \
+ macro(Reflect) \
+ macro(InternalPromise) \
+ macro(abs) \
+ macro(floor) \
+ macro(trunc) \
+ macro(create) \
+ macro(defineProperty) \
+ macro(getPrototypeOf) \
+ macro(getOwnPropertyDescriptor) \
+ macro(getOwnPropertyNames) \
+ macro(ownKeys) \
+ macro(Error) \
+ macro(RangeError) \
+ macro(TypeError) \
+ macro(typedArrayLength) \
+ macro(typedArraySort) \
+ macro(typedArrayGetOriginalConstructor) \
+ macro(typedArraySubarrayCreate) \
+ macro(BuiltinLog) \
+ macro(homeObject) \
+ macro(getTemplateObject) \
+ macro(templateRegistryKey) \
+ macro(enqueueJob) \
+ macro(promiseState) \
+ macro(promiseReactions) \
+ macro(promiseResult) \
+ macro(onFulfilled) \
+ macro(onRejected) \
+ macro(push) \
+ macro(repeatCharacter) \
+ macro(capabilities) \
+ macro(starDefault) \
+ macro(InspectorInstrumentation) \
+ macro(get) \
+ macro(set) \
+ macro(shift) \
+ macro(allocateTypedArray) \
+ macro(Int8Array) \
+ macro(Int16Array) \
+ macro(Int32Array) \
+ macro(Uint8Array) \
+ macro(Uint8ClampedArray) \
+ macro(Uint16Array) \
+ macro(Uint32Array) \
+ macro(Float32Array) \
+ macro(Float64Array) \
+ macro(exec) \
+ macro(generator) \
+ macro(generatorNext) \
+ macro(generatorState) \
+ macro(generatorFrame) \
+ macro(generatorValue) \
+ macro(generatorThis) \
+ macro(generatorResumeMode) \
+ macro(Collator) \
+ macro(DateTimeFormat) \
+ macro(NumberFormat) \
+ macro(intlSubstituteValue) \
+ macro(thisTimeValue) \
+ macro(thisNumberValue) \
+ macro(newTargetLocal) \
+ macro(derivedConstructor) \
+ macro(isTypedArrayView) \
+ macro(isBoundFunction) \
+ macro(hasInstanceBoundFunction) \
+ macro(instanceOf) \
+ macro(isArraySlow) \
+ macro(isArrayConstructor) \
+ macro(isConstructor) \
+ macro(isDerivedConstructor) \
+ macro(concatMemcpy) \
+ macro(appendMemcpy) \
+ macro(predictFinalLengthFromArgumunts) \
+ macro(print) \
+ macro(regExpCreate) \
+ macro(SetIterator) \
+ macro(setIteratorNext) \
+ macro(replaceUsingRegExp) \
+ macro(replaceUsingStringSearch) \
+ macro(MapIterator) \
+ macro(mapIteratorNext) \
+ macro(regExpBuiltinExec) \
+ macro(regExpMatchFast) \
+ macro(regExpProtoFlagsGetter) \
+ macro(regExpProtoGlobalGetter) \
+ macro(regExpProtoIgnoreCaseGetter) \
+ macro(regExpProtoMultilineGetter) \
+ macro(regExpProtoSourceGetter) \
+ macro(regExpProtoStickyGetter) \
+ macro(regExpProtoUnicodeGetter) \
+ macro(regExpPrototypeSymbolReplace) \
+ macro(regExpReplaceFast) \
+ macro(regExpSearchFast) \
+ macro(regExpSplitFast) \
+ macro(regExpTestFast) \
+ macro(stringIncludesInternal) \
+ macro(stringSplitFast) \
+ macro(stringSubstrInternal) \
+ macro(makeBoundFunction) \
+ macro(hasOwnLengthProperty) \
+ macro(importModule) \
+ macro(WebAssembly) \
+ macro(Module) \
+ macro(Instance) \
+ macro(Memory) \
+ macro(Table) \
+ macro(CompileError) \
+ macro(LinkError) \
+ macro(RuntimeError) \
+
+
+#define INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY(name) m_privateToPublicMap.add(m_##name##PrivateName.impl(), &m_##name);
+#define INITIALIZE_PUBLIC_TO_PRIVATE_ENTRY(name) m_publicToPrivateMap.add(m_##name.impl(), &m_##name##PrivateName);
+
+// We commandeer the publicToPrivateMap to allow us to convert private symbol names into the appropriate symbol.
+// e.g. @iteratorSymbol points to Symbol.iterator in this map rather than to a an actual private name.
+// FIXME: This is a weird hack and we shouldn't need to do this.
+#define INITIALIZE_SYMBOL_PUBLIC_TO_PRIVATE_ENTRY(name) m_publicToPrivateMap.add(m_##name##SymbolPrivateIdentifier.impl(), &m_##name##Symbol);
+
+class BuiltinNames {
+ WTF_MAKE_NONCOPYABLE(BuiltinNames); WTF_MAKE_FAST_ALLOCATED;
+
+public:
+ // We treat the dollarVM name as a special case below for $vm (because CommonIdentifiers does not
+ // yet support the $ character).
+
+ BuiltinNames(VM* vm, CommonIdentifiers* commonIdentifiers)
+ : m_emptyIdentifier(commonIdentifiers->emptyIdentifier)
+ JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALIZE_BUILTIN_NAMES)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_BUILTIN_NAMES)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_BUILTIN_SYMBOLS)
+ , m_dollarVMName(Identifier::fromString(vm, "$vm"))
+ , m_dollarVMPrivateName(Identifier::fromUid(PrivateName(PrivateName::Description, ASCIILiteral("PrivateSymbol.$vm"))))
+ {
+ JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PRIVATE_TO_PUBLIC_ENTRY)
+ JSC_FOREACH_BUILTIN_FUNCTION_NAME(INITIALIZE_PUBLIC_TO_PRIVATE_ENTRY)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PUBLIC_TO_PRIVATE_ENTRY)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_SYMBOL_PUBLIC_TO_PRIVATE_ENTRY)
+ m_privateToPublicMap.add(m_dollarVMPrivateName.impl(), &m_dollarVMName);
+ m_publicToPrivateMap.add(m_dollarVMName.impl(), &m_dollarVMPrivateName);
+ }
+
+ bool isPrivateName(SymbolImpl& uid) const;
+ bool isPrivateName(UniquedStringImpl& uid) const;
+ bool isPrivateName(const Identifier&) const;
+ const Identifier* lookUpPrivateName(const Identifier&) const;
+ const Identifier& lookUpPublicName(const Identifier&) const;
+
+ void appendExternalName(const Identifier& publicName, const Identifier& privateName);
+
+ JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_IDENTIFIER_ACCESSOR)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOL_ACCESSOR)
+ const JSC::Identifier& dollarVMPublicName() const { return m_dollarVMName; }
+ const JSC::Identifier& dollarVMPrivateName() const { return m_dollarVMPrivateName; }
+
+private:
+ Identifier m_emptyIdentifier;
+ JSC_FOREACH_BUILTIN_FUNCTION_NAME(DECLARE_BUILTIN_NAMES)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_PROPERTY_NAME(DECLARE_BUILTIN_NAMES)
+ JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(DECLARE_BUILTIN_SYMBOLS)
+ const JSC::Identifier m_dollarVMName;
+ const JSC::Identifier m_dollarVMPrivateName;
+ typedef HashMap<RefPtr<UniquedStringImpl>, const Identifier*, IdentifierRepHash> BuiltinNamesMap;
+ BuiltinNamesMap m_publicToPrivateMap;
+ BuiltinNamesMap m_privateToPublicMap;
+};
+
+inline bool BuiltinNames::isPrivateName(SymbolImpl& uid) const
+{
+ return m_privateToPublicMap.contains(&uid);
+}
+
+inline bool BuiltinNames::isPrivateName(UniquedStringImpl& uid) const
+{
+ if (!uid.isSymbol())
+ return false;
+ return m_privateToPublicMap.contains(&uid);
+}
+
+inline bool BuiltinNames::isPrivateName(const Identifier& ident) const
+{
+ if (ident.isNull())
+ return false;
+ return isPrivateName(*ident.impl());
+}
+
+inline const Identifier* BuiltinNames::lookUpPrivateName(const Identifier& ident) const
+{
+ auto iter = m_publicToPrivateMap.find(ident.impl());
+ if (iter != m_publicToPrivateMap.end())
+ return iter->value;
+ return 0;
+}
+
+inline const Identifier& BuiltinNames::lookUpPublicName(const Identifier& ident) const
+{
+ auto iter = m_privateToPublicMap.find(ident.impl());
+ if (iter != m_privateToPublicMap.end())
+ return *iter->value;
+ return m_emptyIdentifier;
+}
+
+inline void BuiltinNames::appendExternalName(const Identifier& publicName, const Identifier& privateName)
+{
+#ifndef NDEBUG
+ for (const auto& key : m_publicToPrivateMap.keys())
+ ASSERT(publicName.string() != *key);
+#endif
+
+ m_privateToPublicMap.add(privateName.impl(), &publicName);
+ m_publicToPrivateMap.add(publicName.impl(), &privateName);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/builtins/BuiltinUtils.h b/Source/JavaScriptCore/builtins/BuiltinUtils.h
new file mode 100644
index 000000000..26da2919c
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/BuiltinUtils.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2015 Canon Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ConstructAbility.h"
+
+namespace JSC {
+
+#define INITIALIZE_BUILTIN_NAMES(name) , m_##name(JSC::Identifier::fromString(vm, #name)), m_##name##PrivateName(JSC::Identifier::fromUid(JSC::PrivateName(JSC::PrivateName::Description, ASCIILiteral("PrivateSymbol." #name))))
+#define DECLARE_BUILTIN_NAMES(name) const JSC::Identifier m_##name; const JSC::Identifier m_##name##PrivateName;
+#define DECLARE_BUILTIN_IDENTIFIER_ACCESSOR(name) \
+ const JSC::Identifier& name##PublicName() const { return m_##name; } \
+ const JSC::Identifier& name##PrivateName() const { return m_##name##PrivateName; }
+
+#define INITIALIZE_BUILTIN_SYMBOLS(name) , m_##name##Symbol(JSC::Identifier::fromUid(JSC::PrivateName(JSC::PrivateName::Description, ASCIILiteral("Symbol." #name)))), m_##name##SymbolPrivateIdentifier(JSC::Identifier::fromString(vm, #name "Symbol"))
+#define DECLARE_BUILTIN_SYMBOLS(name) const JSC::Identifier m_##name##Symbol; const JSC::Identifier m_##name##SymbolPrivateIdentifier;
+#define DECLARE_BUILTIN_SYMBOL_ACCESSOR(name) \
+ const JSC::Identifier& name##Symbol() const { return m_##name##Symbol; }
+
+class Identifier;
+class SourceCode;
+class UnlinkedFunctionExecutable;
+class VM;
+
+JS_EXPORT_PRIVATE UnlinkedFunctionExecutable* createBuiltinExecutable(VM&, const SourceCode&, const Identifier&, ConstructAbility);
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/builtins/DatePrototype.js b/Source/JavaScriptCore/builtins/DatePrototype.js
new file mode 100644
index 000000000..234f18522
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/DatePrototype.js
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2015 Andy VanWagoner <thetalecrafter@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// @conditional=ENABLE(INTL)
+
+function toLocaleString(/* locales, options */)
+{
+ "use strict";
+
+ function toDateTimeOptionsAnyAll(opts)
+ {
+ // ToDateTimeOptions(options, "any", "all")
+ // http://www.ecma-international.org/ecma-402/2.0/#sec-InitializeDateTimeFormat
+
+ var options;
+ if (opts === @undefined)
+ options = null;
+ else if (opts === null)
+ @throwTypeError("null is not an object");
+ else
+ options = @Object(opts);
+
+ // Check original instead of descendant to reduce lookups up the prototype chain.
+ var needsDefaults = !options || (
+ options.weekday === @undefined &&
+ options.year === @undefined &&
+ options.month === @undefined &&
+ options.day === @undefined &&
+ options.hour === @undefined &&
+ options.minute === @undefined &&
+ options.second === @undefined
+ );
+
+ // Only create descendant if it will have own properties.
+ if (needsDefaults) {
+ options = @Object.@create(options);
+ options.year = "numeric";
+ options.month = "numeric";
+ options.day = "numeric";
+ options.hour = "numeric";
+ options.minute = "numeric";
+ options.second = "numeric";
+ }
+
+ // 9. Return options.
+ return options;
+ }
+
+ // 13.3.1 Date.prototype.toLocaleString ([locales [, options ]]) (ECMA-402 2.0)
+ // http://www.ecma-international.org/ecma-402/2.0/#sec-Date.prototype.toLocaleString
+
+ var value = @thisTimeValue.@call(this);
+ if (@isNaN(value))
+ return "Invalid Date";
+
+ var options = toDateTimeOptionsAnyAll(@argument(1));
+ var locales = @argument(0);
+
+ var dateFormat = new @DateTimeFormat(locales, options);
+ return dateFormat.format(value);
+}
+
+function toLocaleDateString(/* locales, options */)
+{
+ "use strict";
+
+ function toDateTimeOptionsDateDate(opts)
+ {
+ // ToDateTimeOptions(options, "date", "date")
+ // http://www.ecma-international.org/ecma-402/2.0/#sec-InitializeDateTimeFormat
+
+ var options;
+ if (opts === @undefined)
+ options = null;
+ else if (opts === null)
+ @throwTypeError("null is not an object");
+ else
+ options = @Object(opts);
+
+ // Check original instead of descendant to reduce lookups up the prototype chain.
+ var needsDefaults = !options || (
+ options.weekday === @undefined &&
+ options.year === @undefined &&
+ options.month === @undefined &&
+ options.day === @undefined
+ );
+
+ // Only create descendant if it will have own properties.
+ if (needsDefaults) {
+ options = @Object.@create(options);
+ options.year = "numeric";
+ options.month = "numeric";
+ options.day = "numeric";
+ }
+
+ return options;
+ }
+
+ // 13.3.2 Date.prototype.toLocaleDateString ([locales [, options ]]) (ECMA-402 2.0)
+ // http://www.ecma-international.org/ecma-402/2.0/#sec-Date.prototype.toLocaleDateString
+
+ var value = @thisTimeValue.@call(this);
+ if (@isNaN(value))
+ return "Invalid Date";
+
+ var options = toDateTimeOptionsDateDate(@argument(1));
+ var locales = @argument(0);
+
+ var dateFormat = new @DateTimeFormat(locales, options);
+ return dateFormat.format(value);
+}
+
+function toLocaleTimeString(/* locales, options */)
+{
+ "use strict";
+
+ function toDateTimeOptionsTimeTime(opts)
+ {
+ // ToDateTimeOptions(options, "time", "time")
+ // http://www.ecma-international.org/ecma-402/2.0/#sec-InitializeDateTimeFormat
+
+ var options;
+ if (opts === @undefined)
+ options = null;
+ else if (opts === null)
+ @throwTypeError("null is not an object");
+ else
+ options = @Object(opts);
+
+ // Check original instead of descendant to reduce lookups up the prototype chain.
+ var needsDefaults = !options || (
+ options.hour === @undefined &&
+ options.minute === @undefined &&
+ options.second === @undefined
+ );
+
+ // Only create descendant if it will have own properties.
+ if (needsDefaults) {
+ options = @Object.@create(options);
+ options.hour = "numeric";
+ options.minute = "numeric";
+ options.second = "numeric";
+ }
+
+ return options;
+ }
+
+ // 13.3.3 Date.prototype.toLocaleTimeString ([locales [, options ]]) (ECMA-402 2.0)
+ // http://www.ecma-international.org/ecma-402/2.0/#sec-Date.prototype.toLocaleTimeString
+
+ var value = @thisTimeValue.@call(this);
+ if (@isNaN(value))
+ return "Invalid Date";
+
+ var options = toDateTimeOptionsTimeTime(@argument(1));
+ var locales = @argument(0);
+
+ var dateFormat = new @DateTimeFormat(locales, options);
+ return dateFormat.format(value);
+}
diff --git a/Source/JavaScriptCore/builtins/FunctionPrototype.js b/Source/JavaScriptCore/builtins/FunctionPrototype.js
new file mode 100644
index 000000000..f1ee867ef
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/FunctionPrototype.js
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function call(thisArgument)
+{
+ "use strict";
+
+ let argumentValues = [];
+ // Start from 1 to ignore thisArgument
+ for (let i = 1; i < arguments.length; i++)
+ @putByValDirect(argumentValues, i-1, arguments[i]);
+
+ return this.@apply(thisArgument, argumentValues);
+}
+
+function apply(thisValue, argumentValues)
+{
+ "use strict";
+
+ return this.@apply(thisValue, argumentValues);
+}
+
+// FIXME: this should have a different name: https://bugs.webkit.org/show_bug.cgi?id=151363
+function symbolHasInstance(value)
+{
+ "use strict";
+
+ if (typeof this !== "function")
+ return false;
+
+ if (@isBoundFunction(this))
+ return @hasInstanceBoundFunction(this, value);
+
+ let target = this.prototype;
+ return @instanceOf(value, target);
+}
+
+function bind(thisValue)
+{
+ "use strict";
+
+ let target = this;
+ if (typeof target !== "function")
+ @throwTypeError("|this| is not a function inside Function.prototype.bind");
+
+ let argumentCount = arguments.length;
+ let boundArgs = null;
+ let numBoundArgs = 0;
+ if (argumentCount > 1) {
+ numBoundArgs = argumentCount - 1;
+ boundArgs = @newArrayWithSize(numBoundArgs);
+ for (let i = 0; i < numBoundArgs; i++)
+ @putByValDirect(boundArgs, i, arguments[i + 1]);
+ }
+
+ let length = 0;
+ if (@hasOwnLengthProperty(target)) {
+ let lengthValue = target.length;
+ if (typeof lengthValue === "number") {
+ lengthValue = lengthValue | 0;
+ // Note that we only care about positive lengthValues, however, this comparision
+ // against numBoundArgs suffices to prove we're not a negative number.
+ if (lengthValue > numBoundArgs)
+ length = lengthValue - numBoundArgs;
+ }
+ }
+
+ let name = target.name;
+ if (typeof name !== "string")
+ name = "";
+
+ return @makeBoundFunction(target, arguments[0], boundArgs, length, name);
+}
diff --git a/Source/JavaScriptCore/builtins/GeneratorPrototype.js b/Source/JavaScriptCore/builtins/GeneratorPrototype.js
new file mode 100644
index 000000000..4128a3532
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/GeneratorPrototype.js
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015-2016 Yusuke Suzuki <utatane.tea@gmail.com>.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// 25.3.3.3 GeneratorResume ( generator, value )
+// 25.3.3.4 GeneratorResumeAbrupt(generator, abruptCompletion)
+@globalPrivate
+function generatorResume(generator, sentValue, resumeMode)
+{
+ "use strict";
+
+ let state = generator.@generatorState;
+ let done = false;
+ let value = @undefined;
+
+ if (typeof state !== 'number')
+ @throwTypeError("|this| should be a generator");
+
+ if (state === @GeneratorStateExecuting)
+ @throwTypeError("Generator is executing");
+
+ if (state === @GeneratorStateCompleted) {
+ if (resumeMode === @GeneratorResumeModeThrow)
+ throw sentValue;
+
+ done = true;
+ if (resumeMode === @GeneratorResumeModeReturn)
+ value = sentValue;
+ } else {
+ try {
+ generator.@generatorState = @GeneratorStateExecuting;
+ value = generator.@generatorNext.@call(generator.@generatorThis, generator, state, sentValue, resumeMode, generator.@generatorFrame);
+ if (generator.@generatorState === @GeneratorStateExecuting) {
+ generator.@generatorState = @GeneratorStateCompleted;
+ done = true;
+ }
+ } catch (error) {
+ generator.@generatorState = @GeneratorStateCompleted;
+ throw error;
+ }
+ }
+ return { done, value };
+}
+
+function next(value)
+{
+ "use strict";
+
+ return @generatorResume(this, value, @GeneratorResumeModeNormal);
+}
+
+function return(value)
+{
+ "use strict";
+
+ return @generatorResume(this, value, @GeneratorResumeModeReturn);
+}
+
+function throw(exception)
+{
+ "use strict";
+
+ return @generatorResume(this, exception, @GeneratorResumeModeThrow);
+}
diff --git a/Source/JavaScriptCore/builtins/GlobalObject.js b/Source/JavaScriptCore/builtins/GlobalObject.js
new file mode 100644
index 000000000..804930c84
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/GlobalObject.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015-2016 Yusuke Suzuki <utatane.tea@gmail.com>.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+@globalPrivate
+function isFinite(value)
+{
+ "use strict";
+
+ var numberValue = @toNumber(value);
+ // Return false if numberValue is |NaN|.
+ if (numberValue !== numberValue)
+ return false;
+ return numberValue !== @Infinity && numberValue !== -@Infinity;
+}
+
+@globalPrivate
+function isNaN(value)
+{
+ "use strict";
+
+ var numberValue = @toNumber(value);
+ return numberValue !== numberValue;
+}
diff --git a/Source/JavaScriptCore/builtins/GlobalOperations.js b/Source/JavaScriptCore/builtins/GlobalOperations.js
new file mode 100644
index 000000000..22220cf2e
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/GlobalOperations.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// @internal
+
+@globalPrivate
+function toInteger(target)
+{
+ "use strict";
+
+ var numberValue = @Number(target);
+
+ // isNaN(numberValue)
+ if (numberValue !== numberValue)
+ return 0;
+ return @trunc(numberValue);
+}
+
+@globalPrivate
+function toLength(target)
+{
+ "use strict";
+
+ var length = @toInteger(target);
+ // originally Math.min(Math.max(length, 0), maxSafeInteger));
+ return length > 0 ? (length < @MAX_SAFE_INTEGER ? length : @MAX_SAFE_INTEGER) : 0;
+}
+
+@globalPrivate
+function isDictionary(object)
+{
+ "use strict";
+
+ return object == null || typeof object === "object";
+}
+
+// FIXME: this needs to have it's name changed to "get [Symbol.species]".
+// see: https://bugs.webkit.org/show_bug.cgi?id=151363
+@globalPrivate
+function speciesGetter()
+{
+ return this;
+}
+
+@globalPrivate
+function speciesConstructor(obj, defaultConstructor)
+{
+ var constructor = obj.constructor;
+ if (constructor === @undefined)
+ return defaultConstructor;
+ if (!@isObject(constructor))
+ @throwTypeError("|this|.constructor is not an Object or undefined");
+ constructor = constructor.@speciesSymbol;
+ if (constructor == null)
+ return defaultConstructor;
+ if (@isConstructor(constructor))
+ return constructor;
+ @throwTypeError("|this|.constructor[Symbol.species] is not a constructor");
+}
diff --git a/Source/JavaScriptCore/builtins/InspectorInstrumentationObject.js b/Source/JavaScriptCore/builtins/InspectorInstrumentationObject.js
new file mode 100644
index 000000000..fb7d9eae6
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/InspectorInstrumentationObject.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function promiseFulfilled(promise, value, reactions)
+{
+ "use strict";
+
+ if (!this.isEnabled)
+ return;
+}
+
+function promiseRejected(promise, reason, reactions)
+{
+ "use strict";
+
+ if (!this.isEnabled)
+ return;
+}
diff --git a/Source/JavaScriptCore/builtins/InternalPromiseConstructor.js b/Source/JavaScriptCore/builtins/InternalPromiseConstructor.js
new file mode 100644
index 000000000..d01f5f7e5
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/InternalPromiseConstructor.js
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function internalAll(array)
+{
+ // This function is intended to be used in the JSC internals.
+ // The implementation should take care not to perform the user
+ // observable / trappable operations.
+ //
+ // 1. Don't use for-of and iterables. This function only accepts
+ // the dense array of the promises.
+ // 2. Don't look up this.constructor / @@species. Always construct
+ // the plain Promise object.
+
+ "use strict";
+
+ var promiseCapability = @newPromiseCapability(@InternalPromise);
+
+ var values = [];
+ var index = 0;
+ var remainingElementsCount = 0;
+
+ function newResolveElement(index)
+ {
+ var alreadyCalled = false;
+ return function (argument)
+ {
+ if (alreadyCalled)
+ return @undefined;
+ alreadyCalled = true;
+
+ @putByValDirect(values, index, argument);
+
+ --remainingElementsCount;
+ if (remainingElementsCount === 0)
+ return promiseCapability.@resolve.@call(@undefined, values);
+
+ return @undefined;
+ }
+ }
+
+ try {
+ if (array.length === 0)
+ promiseCapability.@resolve.@call(@undefined, values);
+ else {
+ for (var index = 0, length = array.length; index < length; ++index) {
+ var value = array[index];
+ @putByValDirect(values, index, @undefined);
+
+ var nextPromiseCapability = @newPromiseCapability(@InternalPromise);
+ nextPromiseCapability.@resolve.@call(@undefined, value);
+ var nextPromise = nextPromiseCapability.@promise;
+
+ var resolveElement = newResolveElement(index);
+ ++remainingElementsCount;
+ nextPromise.then(resolveElement, promiseCapability.@reject);
+ }
+ }
+ } catch (error) {
+ promiseCapability.@reject.@call(@undefined, error);
+ }
+
+ return promiseCapability.@promise;
+}
diff --git a/Source/JavaScriptCore/builtins/IteratorHelpers.js b/Source/JavaScriptCore/builtins/IteratorHelpers.js
new file mode 100644
index 000000000..f565d4464
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/IteratorHelpers.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function performIteration(iterable)
+{
+ "use strict";
+ // This is performing a spread operation on the iterable passed in,
+ // and returning the result in an array.
+ // https://tc39.github.io/ecma262/#sec-runtime-semantics-arrayaccumulation
+
+ let result = [];
+
+ let iterator = iterable.@iteratorSymbol();
+ let item;
+ let index = 0;
+ while (true) {
+ item = iterator.next();
+ if (!@isObject(item))
+ @throwTypeError("Iterator result interface is not an object");
+ if (item.done)
+ return result;
+ @putByValDirect(result, index++, item.value);
+ }
+}
diff --git a/Source/JavaScriptCore/builtins/IteratorPrototype.js b/Source/JavaScriptCore/builtins/IteratorPrototype.js
new file mode 100644
index 000000000..5c1691a3d
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/IteratorPrototype.js
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function symbolIteratorGetter()
+{
+ "use strict";
+
+ return this;
+}
diff --git a/Source/JavaScriptCore/builtins/MapPrototype.js b/Source/JavaScriptCore/builtins/MapPrototype.js
new file mode 100644
index 000000000..830260269
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/MapPrototype.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function forEach(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (!@isMap(this))
+ @throwTypeError("Map operation called on non-Map object");
+
+ if (typeof callback !== 'function')
+ @throwTypeError("Map.prototype.forEach callback must be a function");
+
+ var thisArg = @argument(1);
+ var iterator = @MapIterator(this);
+
+ // To avoid object allocations for iterator result objects, we pass the placeholder to the special "next" function in order to fill the results.
+ var value = [ @undefined, @undefined ];
+ for (;;) {
+ if (@mapIteratorNext.@call(iterator, value))
+ break;
+ callback.@call(thisArg, value[1], value[0], this);
+ }
+}
diff --git a/Source/JavaScriptCore/builtins/ModuleLoaderPrototype.js b/Source/JavaScriptCore/builtins/ModuleLoaderPrototype.js
new file mode 100644
index 000000000..29556ea3d
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/ModuleLoaderPrototype.js
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// https://whatwg.github.io/loader/#loader-object
+// Module Loader has several hooks that can be customized by the platform.
+// For example, the [[Fetch]] hook can be provided by the JavaScriptCore shell
+// as fetching the payload from the local file system.
+// Currently, there are 4 hooks.
+// 1. Loader.resolve
+// 2. Loader.fetch
+// 3. Loader.instantiate
+
+@globalPrivate
+function setStateToMax(entry, newState)
+{
+ // https://whatwg.github.io/loader/#set-state-to-max
+
+ "use strict";
+
+ if (entry.state < newState)
+ entry.state = newState;
+}
+
+@globalPrivate
+function newRegistryEntry(key)
+{
+ // https://whatwg.github.io/loader/#registry
+ //
+ // Each registry entry becomes one of the 5 states.
+ // 1. Fetch
+ // Ready to fetch (or now fetching) the resource of this module.
+ // Typically, we fetch the source code over the network or from the file system.
+ // a. If the status is Fetch and there is no entry.fetch promise, the entry is ready to fetch.
+ // b. If the status is Fetch and there is the entry.fetch promise, the entry is just fetching the resource.
+ //
+ // 2. Instantiate (AnalyzeModule)
+ // Ready to instantiate (or now instantiating) the module record from the fetched
+ // source code.
+ // Typically, we parse the module code, extract the dependencies and binding information.
+ // a. If the status is Instantiate and there is no entry.instantiate promise, the entry is ready to instantiate.
+ // b. If the status is Instantiate and there is the entry.fetch promise, the entry is just instantiating
+ // the module record.
+ //
+ // 3. Satisfy
+ // Ready to request the dependent modules (or now requesting & resolving).
+ // Without this state, the current draft causes infinite recursion when there is circular dependency.
+ // a. If the status is Satisfy and there is no entry.satisfy promise, the entry is ready to resolve the dependencies.
+ // b. If the status is Satisfy and there is the entry.satisfy promise, the entry is just resolving
+ // the dependencies.
+ //
+ // 4. Link
+ // Ready to link the module with the other modules.
+ // Linking means that the module imports and exports the bindings from/to the other modules.
+ //
+ // 5. Ready
+ // The module is linked, so the module is ready to be executed.
+ //
+ // Each registry entry has the 4 promises; "fetch", "instantiate" and "satisfy".
+ // They are assigned when starting the each phase. And they are fulfilled when the each phase is completed.
+ //
+ // In the current module draft, linking will be performed after the whole modules are instantiated and the dependencies are resolved.
+ // And execution is also done after the all modules are linked.
+ //
+ // TODO: We need to exploit the way to execute the module while fetching non-related modules.
+ // One solution; introducing the ready promise chain to execute the modules concurrently while keeping
+ // the execution order.
+
+ "use strict";
+
+ return {
+ key: key,
+ state: @ModuleFetch,
+ fetch: @undefined,
+ instantiate: @undefined,
+ satisfy: @undefined,
+ dependencies: [], // To keep the module order, we store the module keys in the array.
+ dependenciesMap: @undefined,
+ module: @undefined, // JSModuleRecord
+ linkError: @undefined,
+ linkSucceeded: true,
+ };
+}
+
+function ensureRegistered(key)
+{
+ // https://whatwg.github.io/loader/#ensure-registered
+
+ "use strict";
+
+ var entry = this.registry.@get(key);
+ if (entry)
+ return entry;
+
+ entry = @newRegistryEntry(key);
+ this.registry.@set(key, entry);
+
+ return entry;
+}
+
+function forceFulfillPromise(promise, value)
+{
+ "use strict";
+
+ if (promise.@promiseState === @promiseStatePending)
+ @fulfillPromise(promise, value);
+}
+
+function fulfillFetch(entry, source)
+{
+ // https://whatwg.github.io/loader/#fulfill-fetch
+
+ "use strict";
+
+ if (!entry.fetch)
+ entry.fetch = @newPromiseCapability(@InternalPromise).@promise;
+ this.forceFulfillPromise(entry.fetch, source);
+ @setStateToMax(entry, @ModuleInstantiate);
+}
+
+function fulfillInstantiate(entry, optionalInstance, source)
+{
+ // https://whatwg.github.io/loader/#fulfill-instantiate
+
+ "use strict";
+
+ if (!entry.instantiate)
+ entry.instantiate = @newPromiseCapability(@InternalPromise).@promise;
+ this.commitInstantiated(entry, optionalInstance, source);
+
+ // FIXME: The draft fulfills the promise in the CommitInstantiated operation.
+ // But it CommitInstantiated is also used in the requestInstantiate and
+ // we should not "force fulfill" there.
+ // So we separate "force fulfill" operation from the CommitInstantiated operation.
+ // https://github.com/whatwg/loader/pull/67
+ this.forceFulfillPromise(entry.instantiate, entry);
+}
+
+function commitInstantiated(entry, optionalInstance, source)
+{
+ // https://whatwg.github.io/loader/#commit-instantiated
+
+ "use strict";
+
+ var moduleRecord = this.instantiation(optionalInstance, source, entry);
+
+ // FIXME: Described in the draft,
+ // 4. Fulfill entry.[[Instantiate]] with instance.
+ // But, instantiate promise should be fulfilled with the entry.
+ // We remove this statement because instantiate promise will be
+ // fulfilled without this "force fulfill" operation.
+ // https://github.com/whatwg/loader/pull/67
+
+ var dependencies = [];
+ var dependenciesMap = moduleRecord.dependenciesMap;
+ moduleRecord.registryEntry = entry;
+ var requestedModules = this.requestedModules(moduleRecord);
+ for (var i = 0, length = requestedModules.length; i < length; ++i) {
+ var depKey = requestedModules[i];
+ var pair = {
+ key: depKey,
+ value: @undefined
+ };
+ @putByValDirect(dependencies, dependencies.length, pair);
+ dependenciesMap.@set(depKey, pair);
+ }
+ entry.dependencies = dependencies;
+ entry.dependenciesMap = dependenciesMap;
+ entry.module = moduleRecord;
+ @setStateToMax(entry, @ModuleSatisfy);
+}
+
+function instantiation(result, source, entry)
+{
+ // https://whatwg.github.io/loader/#instantiation
+ // FIXME: Current implementation does not support optionalInstance.
+ // https://bugs.webkit.org/show_bug.cgi?id=148171
+
+ "use strict";
+
+ return this.parseModule(entry.key, source);
+}
+
+// Loader.
+
+function requestFetch(key, fetcher)
+{
+ // https://whatwg.github.io/loader/#request-fetch
+
+ "use strict";
+
+ var entry = this.ensureRegistered(key);
+ if (entry.fetch)
+ return entry.fetch;
+
+ // Hook point.
+ // 2. Loader.fetch
+ // https://whatwg.github.io/loader/#browser-fetch
+ // Take the key and fetch the resource actually.
+ // For example, JavaScriptCore shell can provide the hook fetching the resource
+ // from the local file system.
+ var fetchPromise = this.fetch(key, fetcher).then((source) => {
+ @setStateToMax(entry, @ModuleInstantiate);
+ return source;
+ });
+ entry.fetch = fetchPromise;
+ return fetchPromise;
+}
+
+function requestInstantiate(key, fetcher)
+{
+ // https://whatwg.github.io/loader/#request-instantiate
+
+ "use strict";
+
+ var entry = this.ensureRegistered(key);
+ if (entry.instantiate)
+ return entry.instantiate;
+
+ var instantiatePromise = this.requestFetch(key, fetcher).then((source) => {
+ // Hook point.
+ // 3. Loader.instantiate
+ // https://whatwg.github.io/loader/#browser-instantiate
+ // Take the key and the fetched source code, and instantiate the module record
+ // by parsing the module source code.
+ // It has the chance to provide the optional module instance that is different from
+ // the ordinary one.
+ return this.instantiate(key, source, fetcher).then((optionalInstance) => {
+ this.commitInstantiated(entry, optionalInstance, source);
+ return entry;
+ });
+ });
+ entry.instantiate = instantiatePromise;
+ return instantiatePromise;
+}
+
+function requestSatisfy(key, fetcher)
+{
+ // https://whatwg.github.io/loader/#satisfy-instance
+
+ "use strict";
+
+ var entry = this.ensureRegistered(key);
+ if (entry.satisfy)
+ return entry.satisfy;
+
+ var satisfyPromise = this.requestInstantiate(key, fetcher).then((entry) => {
+ var depLoads = [];
+ for (var i = 0, length = entry.dependencies.length; i < length; ++i) {
+ let pair = entry.dependencies[i];
+
+ // Hook point.
+ // 1. Loader.resolve.
+ // https://whatwg.github.io/loader/#browser-resolve
+ // Take the name and resolve it to the unique identifier for the resource location.
+ // For example, take the "jquery" and return the URL for the resource.
+ var promise = this.resolve(pair.key, key, fetcher).then((depKey) => {
+ var depEntry = this.ensureRegistered(depKey);
+
+ // Recursive resolving. The dependencies of this entry is being resolved or already resolved.
+ // Stop tracing the circular dependencies.
+ // But to retrieve the instantiated module record correctly,
+ // we need to wait for the instantiation for the dependent module.
+ // For example, reaching here, the module is starting resolving the dependencies.
+ // But the module may or may not reach the instantiation phase in the loader's pipeline.
+ // If we wait for the Satisfy for this module, it construct the circular promise chain and
+ // rejected by the Promises runtime. Since only we need is the instantiated module, instead of waiting
+ // the Satisfy for this module, we just wait Instantiate for this.
+ if (depEntry.satisfy) {
+ return depEntry.instantiate.then((entry) => {
+ pair.value = entry.module;
+ return entry;
+ });
+ }
+
+ return this.requestSatisfy(depKey, fetcher).then((entry) => {
+ pair.value = entry.module;
+ return entry;
+ });
+ });
+ @putByValDirect(depLoads, depLoads.length, promise);
+ }
+
+ return @InternalPromise.internalAll(depLoads).then((modules) => {
+ @setStateToMax(entry, @ModuleLink);
+ return entry;
+ });
+ });
+
+ entry.satisfy = satisfyPromise;
+ return satisfyPromise;
+}
+
+function requestLink(key, fetcher)
+{
+ // https://whatwg.github.io/loader/#request-link
+
+ "use strict";
+
+ var entry = this.ensureRegistered(key);
+ if (entry.state > @ModuleLink) {
+ var deferred = @newPromiseCapability(@InternalPromise);
+ deferred.@resolve.@call(@undefined, entry);
+ return deferred.@promise;
+ }
+
+ return this.requestSatisfy(key, fetcher).then((entry) => {
+ this.link(entry, fetcher);
+ return entry;
+ });
+}
+
+function requestReady(key, fetcher)
+{
+ // https://whatwg.github.io/loader/#request-ready
+
+ "use strict";
+
+ return this.requestLink(key, fetcher).then((entry) => {
+ this.moduleEvaluation(entry.module, fetcher);
+ });
+}
+
+// Linking semantics.
+
+function link(entry, fetcher)
+{
+ // https://whatwg.github.io/loader/#link
+
+ "use strict";
+
+ if (!entry.linkSucceeded)
+ throw entry.linkError;
+ if (entry.state === @ModuleReady)
+ return;
+ @setStateToMax(entry, @ModuleReady);
+
+ try {
+ // Since we already have the "dependencies" field,
+ // we can call moduleDeclarationInstantiation with the correct order
+ // without constructing the dependency graph by calling dependencyGraph.
+ var dependencies = entry.dependencies;
+ for (var i = 0, length = dependencies.length; i < length; ++i) {
+ var pair = dependencies[i];
+ this.link(pair.value.registryEntry, fetcher);
+ }
+
+ this.moduleDeclarationInstantiation(entry.module, fetcher);
+ } catch (error) {
+ entry.linkSucceeded = false;
+ entry.linkError = error;
+ throw error;
+ }
+}
+
+// Module semantics.
+
+function moduleEvaluation(moduleRecord, fetcher)
+{
+ // http://www.ecma-international.org/ecma-262/6.0/#sec-moduleevaluation
+
+ "use strict";
+
+ if (moduleRecord.evaluated)
+ return;
+ moduleRecord.evaluated = true;
+
+ var entry = moduleRecord.registryEntry;
+
+ // The contents of the [[RequestedModules]] is cloned into entry.dependencies.
+ var dependencies = entry.dependencies;
+ for (var i = 0, length = dependencies.length; i < length; ++i) {
+ var pair = dependencies[i];
+ var requiredModuleRecord = pair.value;
+ this.moduleEvaluation(requiredModuleRecord, fetcher);
+ }
+ this.evaluate(entry.key, moduleRecord, fetcher);
+}
+
+// APIs to control the module loader.
+
+function provide(key, stage, value)
+{
+ "use strict";
+
+ var entry = this.ensureRegistered(key);
+
+ if (stage === @ModuleFetch) {
+ if (entry.state > @ModuleFetch)
+ @throwTypeError("Requested module is already fetched.");
+ this.fulfillFetch(entry, value);
+ return;
+ }
+
+ if (stage === @ModuleInstantiate) {
+ if (entry.state > @ModuleInstantiate)
+ @throwTypeError("Requested module is already instantiated.");
+ this.fulfillFetch(entry, @undefined);
+ entry.fetch.then((source) => {
+ this.fulfillInstantiate(entry, value, source);
+ });
+ return;
+ }
+
+ @throwTypeError("Requested module is already ready to be executed.");
+}
+
+function loadAndEvaluateModule(moduleName, referrer, fetcher)
+{
+ "use strict";
+
+ // Loader.resolve hook point.
+ // resolve: moduleName => Promise(moduleKey)
+ // Take the name and resolve it to the unique identifier for the resource location.
+ // For example, take the "jquery" and return the URL for the resource.
+ return this.resolve(moduleName, referrer, fetcher).then((key) => {
+ return this.requestReady(key, fetcher);
+ });
+}
+
+function loadModule(moduleName, referrer, fetcher)
+{
+ "use strict";
+
+ // Loader.resolve hook point.
+ // resolve: moduleName => Promise(moduleKey)
+ // Take the name and resolve it to the unique identifier for the resource location.
+ // For example, take the "jquery" and return the URL for the resource.
+ return this.resolve(moduleName, referrer, fetcher).then((key) => {
+ return this.requestSatisfy(key, fetcher);
+ }).then((entry) => {
+ return entry.key;
+ });
+}
+
+function linkAndEvaluateModule(key, fetcher)
+{
+ "use strict";
+
+ var entry = this.ensureRegistered(key);
+ if (entry.state < @ModuleLink)
+ @throwTypeError("Requested module is not instantiated yet.");
+
+ this.link(entry, fetcher);
+ return this.moduleEvaluation(entry.module, fetcher);
+}
+
+function requestImportModule(key, fetcher)
+{
+ "use strict";
+
+ return this.requestSatisfy(key, fetcher).then((entry) => {
+ this.linkAndEvaluateModule(entry.key, fetcher);
+ return this.getModuleNamespaceObject(entry.module);
+ });
+}
diff --git a/Source/JavaScriptCore/builtins/NumberConstructor.js b/Source/JavaScriptCore/builtins/NumberConstructor.js
new file mode 100644
index 000000000..2c0e4c868
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/NumberConstructor.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function isFinite(value)
+{
+ "use strict";
+
+ if (typeof value !== "number")
+ return false;
+
+ // Return false if value is |NaN|.
+ if (value !== value)
+ return false;
+
+ return value !== @Infinity && value !== -@Infinity;
+}
+
+function isNaN(value)
+{
+ "use strict";
+
+ return value !== value;
+}
diff --git a/Source/JavaScriptCore/builtins/NumberPrototype.js b/Source/JavaScriptCore/builtins/NumberPrototype.js
new file mode 100644
index 000000000..435ea789b
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/NumberPrototype.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Andy VanWagoner <thetalecrafter@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// @conditional=ENABLE(INTL)
+
+function toLocaleString(/* locales, options */)
+{
+ "use strict";
+
+ // 13.2.1 Number.prototype.toLocaleString ([locales [, options ]]) (ECMA-402 2.0)
+ // http://ecma-international.org/publications/standards/Ecma-402.htm
+
+ // 1. Let x be thisNumberValue(this value).
+ // 2. ReturnIfAbrupt(x).
+ var number = @thisNumberValue.@call(this);
+
+ // 3. Let numberFormat be Construct(%NumberFormat%, «locales, options»).
+ // 4. ReturnIfAbrupt(numberFormat).
+ var numberFormat = new @NumberFormat(@argument(0), @argument(1));
+
+ // 5. Return FormatNumber(numberFormat, x).
+ return numberFormat.format(number);
+}
diff --git a/Source/JavaScriptCore/builtins/ObjectConstructor.js b/Source/JavaScriptCore/builtins/ObjectConstructor.js
new file mode 100644
index 000000000..d855beb2a
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/ObjectConstructor.js
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 Oleksandr Skachkov <gskachkov@gmail.com>.
+ * Copyright (C) 2015 Jordan Harband. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+@globalPrivate
+function enumerableOwnProperties(object, kind)
+{
+ "use strict";
+
+ const obj = @Object(object);
+ const ownKeys = @Reflect.@ownKeys(obj);
+ const properties = [];
+ for (let i = 0, keysLength = ownKeys.length; i < keysLength; ++i) {
+ let nextKey = ownKeys[i];
+ if (typeof nextKey === 'string') {
+ let descriptor = @Reflect.@getOwnPropertyDescriptor(obj, nextKey);
+ if (descriptor !== @undefined && descriptor.enumerable) {
+ if (kind === @iterationKindValue)
+ properties.@push(obj[nextKey]);
+ else if (kind === @iterationKindKeyValue)
+ properties.@push([nextKey, obj[nextKey]]);
+ }
+ }
+ }
+
+ return properties;
+}
+
+function values(object)
+{
+ "use strict";
+
+ if (object == null)
+ @throwTypeError("Object.values requires that input parameter not be null or undefined");
+
+ return @enumerableOwnProperties(object, @iterationKindValue);
+}
+
+function entries(object)
+{
+ "use strict";
+
+ if (object == null)
+ @throwTypeError("Object.entries requires that input parameter not be null or undefined");
+
+ return @enumerableOwnProperties(object, @iterationKindKeyValue);
+}
+
+function assign(target/*[*/, /*...*/sources/*] */)
+{
+ "use strict";
+
+ if (target == null)
+ @throwTypeError("Object.assign requires that input parameter not be null or undefined");
+
+ let objTarget = @Object(target);
+ for (let s = 1, argumentsLength = arguments.length; s < argumentsLength; ++s) {
+ let nextSource = arguments[s];
+ if (nextSource != null) {
+ let from = @Object(nextSource);
+ let keys = @Reflect.@ownKeys(from);
+ for (let i = 0, keysLength = keys.length; i < keysLength; ++i) {
+ let nextKey = keys[i];
+ let descriptor = @Reflect.@getOwnPropertyDescriptor(from, nextKey);
+ if (descriptor !== @undefined && descriptor.enumerable)
+ objTarget[nextKey] = from[nextKey];
+ }
+ }
+ }
+ return objTarget;
+}
diff --git a/Source/JavaScriptCore/builtins/PromiseConstructor.js b/Source/JavaScriptCore/builtins/PromiseConstructor.js
new file mode 100644
index 000000000..3f0848dfa
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/PromiseConstructor.js
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function all(iterable)
+{
+ "use strict";
+
+ if (!@isObject(this))
+ @throwTypeError("|this| is not a object");
+
+ var promiseCapability = @newPromiseCapability(this);
+
+ var values = [];
+ var index = 0;
+ var remainingElementsCount = 1;
+
+ function newResolveElement(index)
+ {
+ var alreadyCalled = false;
+ return function (argument)
+ {
+ if (alreadyCalled)
+ return @undefined;
+ alreadyCalled = true;
+
+ @putByValDirect(values, index, argument);
+
+ --remainingElementsCount;
+ if (remainingElementsCount === 0)
+ return promiseCapability.@resolve.@call(@undefined, values);
+
+ return @undefined;
+ }
+ }
+
+ try {
+ for (var value of iterable) {
+ @putByValDirect(values, index, @undefined);
+ var nextPromise = this.resolve(value);
+ var resolveElement = newResolveElement(index);
+ ++remainingElementsCount;
+ nextPromise.then(resolveElement, promiseCapability.@reject);
+ ++index;
+ }
+
+ --remainingElementsCount;
+ if (remainingElementsCount === 0)
+ promiseCapability.@resolve.@call(@undefined, values);
+ } catch (error) {
+ promiseCapability.@reject.@call(@undefined, error);
+ }
+
+ return promiseCapability.@promise;
+}
+
+function race(iterable)
+{
+ "use strict";
+
+ if (!@isObject(this))
+ @throwTypeError("|this| is not a object");
+
+ var promiseCapability = @newPromiseCapability(this);
+
+ try {
+ for (var value of iterable) {
+ var nextPromise = this.resolve(value);
+ nextPromise.then(promiseCapability.@resolve, promiseCapability.@reject);
+ }
+ } catch (error) {
+ promiseCapability.@reject.@call(@undefined, error);
+ }
+
+ return promiseCapability.@promise;
+}
+
+function reject(reason)
+{
+ "use strict";
+
+ if (!@isObject(this))
+ @throwTypeError("|this| is not a object");
+
+ var promiseCapability = @newPromiseCapability(this);
+
+ promiseCapability.@reject.@call(@undefined, reason);
+
+ return promiseCapability.@promise;
+}
+
+function resolve(value)
+{
+ "use strict";
+
+ if (!@isObject(this))
+ @throwTypeError("|this| is not a object");
+
+ if (@isPromise(value)) {
+ var valueConstructor = value.constructor;
+ if (valueConstructor === this)
+ return value;
+ }
+
+ var promiseCapability = @newPromiseCapability(this);
+
+ promiseCapability.@resolve.@call(@undefined, value);
+
+ return promiseCapability.@promise;
+}
diff --git a/Source/JavaScriptCore/builtins/PromiseOperations.js b/Source/JavaScriptCore/builtins/PromiseOperations.js
new file mode 100644
index 000000000..61564e7cd
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/PromiseOperations.js
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// @internal
+
+@globalPrivate
+function isPromise(promise)
+{
+ "use strict";
+
+ return @isObject(promise) && !!promise.@promiseState;
+}
+
+@globalPrivate
+function newPromiseReaction(capability, onFulfilled, onRejected)
+{
+ "use strict";
+
+ return {
+ @capabilities: capability,
+ @onFulfilled: onFulfilled,
+ @onRejected: onRejected,
+ };
+}
+
+@globalPrivate
+function newPromiseCapability(constructor)
+{
+ "use strict";
+
+ if (!@isConstructor(constructor))
+ @throwTypeError("promise capability requires a constructor function");
+
+ var promiseCapability = {
+ @promise: @undefined,
+ @resolve: @undefined,
+ @reject: @undefined
+ };
+
+ function executor(resolve, reject)
+ {
+ if (promiseCapability.@resolve !== @undefined)
+ @throwTypeError("resolve function is already set");
+ if (promiseCapability.@reject !== @undefined)
+ @throwTypeError("reject function is already set");
+
+ promiseCapability.@resolve = resolve;
+ promiseCapability.@reject = reject;
+ }
+
+ var promise = new constructor(executor);
+
+ if (typeof promiseCapability.@resolve !== "function")
+ @throwTypeError("executor did not take a resolve function");
+
+ if (typeof promiseCapability.@reject !== "function")
+ @throwTypeError("executor did not take a reject function");
+
+ promiseCapability.@promise = promise;
+
+ return promiseCapability;
+}
+
+@globalPrivate
+function triggerPromiseReactions(state, reactions, argument)
+{
+ "use strict";
+
+ for (var index = 0, length = reactions.length; index < length; ++index)
+ @enqueueJob(@promiseReactionJob, [state, reactions[index], argument]);
+}
+
+@globalPrivate
+function rejectPromise(promise, reason)
+{
+ "use strict";
+
+ var reactions = promise.@promiseReactions;
+ promise.@promiseResult = reason;
+ promise.@promiseReactions = @undefined;
+ promise.@promiseState = @promiseStateRejected;
+
+ @InspectorInstrumentation.promiseRejected(promise, reason, reactions);
+
+ @triggerPromiseReactions(@promiseStateRejected, reactions, reason);
+}
+
+@globalPrivate
+function fulfillPromise(promise, value)
+{
+ "use strict";
+
+ var reactions = promise.@promiseReactions;
+ promise.@promiseResult = value;
+ promise.@promiseReactions = @undefined;
+ promise.@promiseState = @promiseStateFulfilled;
+
+ @InspectorInstrumentation.promiseFulfilled(promise, value, reactions);
+
+ @triggerPromiseReactions(@promiseStateFulfilled, reactions, value);
+}
+
+@globalPrivate
+function createResolvingFunctions(promise)
+{
+ "use strict";
+
+ var alreadyResolved = false;
+
+ var resolve = function (resolution) {
+ if (alreadyResolved)
+ return @undefined;
+ alreadyResolved = true;
+
+ if (resolution === promise)
+ return @rejectPromise(promise, new @TypeError("Resolve a promise with itself"));
+
+ if (!@isObject(resolution))
+ return @fulfillPromise(promise, resolution);
+
+ var then;
+ try {
+ then = resolution.then;
+ } catch (error) {
+ return @rejectPromise(promise, error);
+ }
+
+ if (typeof then !== 'function')
+ return @fulfillPromise(promise, resolution);
+
+ @enqueueJob(@promiseResolveThenableJob, [promise, resolution, then]);
+
+ return @undefined;
+ };
+
+ var reject = function (reason) {
+ if (alreadyResolved)
+ return @undefined;
+ alreadyResolved = true;
+
+ return @rejectPromise(promise, reason);
+ };
+
+ return {
+ @resolve: resolve,
+ @reject: reject
+ };
+}
+
+@globalPrivate
+function promiseReactionJob(state, reaction, argument)
+{
+ "use strict";
+
+ var promiseCapability = reaction.@capabilities;
+
+ var result;
+ var handler = (state === @promiseStateFulfilled) ? reaction.@onFulfilled: reaction.@onRejected;
+ try {
+ result = handler(argument);
+ } catch (error) {
+ return promiseCapability.@reject.@call(@undefined, error);
+ }
+
+ return promiseCapability.@resolve.@call(@undefined, result);
+}
+
+@globalPrivate
+function promiseResolveThenableJob(promiseToResolve, thenable, then)
+{
+ "use strict";
+
+ var resolvingFunctions = @createResolvingFunctions(promiseToResolve);
+
+ try {
+ return then.@call(thenable, resolvingFunctions.@resolve, resolvingFunctions.@reject);
+ } catch (error) {
+ return resolvingFunctions.@reject.@call(@undefined, error);
+ }
+}
+
+@globalPrivate
+function initializePromise(executor)
+{
+ "use strict";
+
+ if (typeof executor !== 'function')
+ @throwTypeError("Promise constructor takes a function argument");
+
+ this.@promiseState = @promiseStatePending;
+ this.@promiseReactions = [];
+
+ var resolvingFunctions = @createResolvingFunctions(this);
+ try {
+ executor(resolvingFunctions.@resolve, resolvingFunctions.@reject);
+ } catch (error) {
+ return resolvingFunctions.@reject.@call(@undefined, error);
+ }
+
+ return this;
+}
diff --git a/Source/JavaScriptCore/builtins/PromisePrototype.js b/Source/JavaScriptCore/builtins/PromisePrototype.js
new file mode 100644
index 000000000..6065ad837
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/PromisePrototype.js
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function catch(onRejected)
+{
+ "use strict";
+
+ return this.then(@undefined, onRejected);
+}
+
+function then(onFulfilled, onRejected)
+{
+ "use strict";
+
+ if (!@isPromise(this))
+ @throwTypeError("|this| is not a object");
+
+ var constructor = @speciesConstructor(this, @Promise);
+
+ var resultCapability = @newPromiseCapability(constructor);
+
+ if (typeof onFulfilled !== "function")
+ onFulfilled = function (argument) { return argument; };
+
+ if (typeof onRejected !== "function")
+ onRejected = function (argument) { throw argument; };
+
+ var reaction = @newPromiseReaction(resultCapability, onFulfilled, onRejected);
+
+ var state = this.@promiseState;
+ if (state === @promiseStatePending)
+ @putByValDirect(this.@promiseReactions, this.@promiseReactions.length, reaction);
+ else
+ @enqueueJob(@promiseReactionJob, [state, reaction, this.@promiseResult]);
+
+ return resultCapability.@promise;
+}
diff --git a/Source/JavaScriptCore/builtins/ReflectObject.js b/Source/JavaScriptCore/builtins/ReflectObject.js
new file mode 100644
index 000000000..1aaa1f407
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/ReflectObject.js
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// https://tc39.github.io/ecma262/#sec-reflect.apply
+function apply(target, thisArgument, argumentsList)
+{
+ "use strict";
+
+ if (typeof target !== "function")
+ @throwTypeError("Reflect.apply requires the first argument be a function");
+
+ if (!@isObject(argumentsList))
+ @throwTypeError("Reflect.apply requires the third argument be an object");
+
+ return target.@apply(thisArgument, argumentsList);
+}
+
+// https://tc39.github.io/ecma262/#sec-reflect.deleteproperty
+function deleteProperty(target, propertyKey)
+{
+ // Intentionally keep the code the sloppy mode to suppress the TypeError
+ // raised by the delete operator under the strict mode.
+
+ if (!@isObject(target))
+ @throwTypeError("Reflect.deleteProperty requires the first argument be an object");
+
+ return delete target[propertyKey];
+}
+
+// https://tc39.github.io/ecma262/#sec-reflect.has
+function has(target, propertyKey)
+{
+ "use strict";
+
+ if (!@isObject(target))
+ @throwTypeError("Reflect.has requires the first argument be an object");
+
+ return propertyKey in target;
+}
diff --git a/Source/JavaScriptCore/builtins/RegExpPrototype.js b/Source/JavaScriptCore/builtins/RegExpPrototype.js
new file mode 100644
index 000000000..017a81cd1
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/RegExpPrototype.js
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+@globalPrivate
+function advanceStringIndex(string, index, unicode)
+{
+ // This function implements AdvanceStringIndex described in ES6 21.2.5.2.3.
+ "use strict";
+
+ if (!unicode)
+ return index + 1;
+
+ if (index + 1 >= string.length)
+ return index + 1;
+
+ let first = string.@charCodeAt(index);
+ if (first < 0xD800 || first > 0xDBFF)
+ return index + 1;
+
+ let second = string.@charCodeAt(index + 1);
+ if (second < 0xDC00 || second > 0xDFFF)
+ return index + 1;
+
+ return index + 2;
+}
+
+@globalPrivate
+function regExpExec(regexp, str)
+{
+ "use strict";
+
+ let exec = regexp.exec;
+ let builtinExec = @regExpBuiltinExec;
+ if (exec !== builtinExec && typeof exec === "function") {
+ let result = exec.@call(regexp, str);
+ if (result !== null && !@isObject(result))
+ @throwTypeError("The result of a RegExp exec must be null or an object");
+ return result;
+ }
+ return builtinExec.@call(regexp, str);
+}
+
+@globalPrivate
+function hasObservableSideEffectsForRegExpMatch(regexp) {
+ // This is accessed by the RegExpExec internal function.
+ let regexpExec = @tryGetById(regexp, "exec");
+ if (regexpExec !== @regExpBuiltinExec)
+ return true;
+
+ let regexpGlobal = @tryGetById(regexp, "global");
+ if (regexpGlobal !== @regExpProtoGlobalGetter)
+ return true;
+ let regexpUnicode = @tryGetById(regexp, "unicode");
+ if (regexpUnicode !== @regExpProtoUnicodeGetter)
+ return true;
+
+ return !@isRegExpObject(regexp);
+}
+
+function match(strArg)
+{
+ "use strict";
+
+ if (!@isObject(this))
+ @throwTypeError("RegExp.prototype.@@match requires that |this| be an Object");
+
+ let regexp = this;
+
+ // Check for observable side effects and call the fast path if there aren't any.
+ if (!@hasObservableSideEffectsForRegExpMatch(regexp))
+ return @regExpMatchFast.@call(regexp, strArg);
+
+ let str = @toString(strArg);
+
+ if (!regexp.global)
+ return @regExpExec(regexp, str);
+
+ let unicode = regexp.unicode;
+ regexp.lastIndex = 0;
+ let resultList = [];
+
+ // FIXME: It would be great to implement a solution similar to what we do in
+ // RegExpObject::matchGlobal(). It's not clear if this is possible, since this loop has
+ // effects. https://bugs.webkit.org/show_bug.cgi?id=158145
+ const maximumReasonableMatchSize = 100000000;
+
+ while (true) {
+ let result = @regExpExec(regexp, str);
+
+ if (result === null) {
+ if (resultList.length === 0)
+ return null;
+ return resultList;
+ }
+
+ if (resultList.length > maximumReasonableMatchSize)
+ @throwOutOfMemoryError();
+
+ if (!@isObject(result))
+ @throwTypeError("RegExp.prototype.@@match call to RegExp.exec didn't return null or an object");
+
+ let resultString = @toString(result[0]);
+
+ if (!resultString.length)
+ regexp.lastIndex = @advanceStringIndex(str, regexp.lastIndex, unicode);
+
+ resultList.@push(resultString);
+ }
+}
+
+function replace(strArg, replace)
+{
+ "use strict";
+
+ function getSubstitution(matched, str, position, captures, replacement)
+ {
+ "use strict";
+
+ let matchLength = matched.length;
+ let stringLength = str.length;
+ let tailPos = position + matchLength;
+ let m = captures.length;
+ let replacementLength = replacement.length;
+ let result = "";
+ let lastStart = 0;
+
+ for (let start = 0; start = replacement.indexOf("$", lastStart), start !== -1; lastStart = start) {
+ if (start - lastStart > 0)
+ result = result + replacement.substring(lastStart, start);
+ start++;
+ let ch = replacement.charAt(start);
+ if (ch === "")
+ result = result + "$";
+ else {
+ switch (ch)
+ {
+ case "$":
+ result = result + "$";
+ start++;
+ break;
+ case "&":
+ result = result + matched;
+ start++;
+ break;
+ case "`":
+ if (position > 0)
+ result = result + str.substring(0, position);
+ start++;
+ break;
+ case "'":
+ if (tailPos < stringLength)
+ result = result + str.substring(tailPos);
+ start++;
+ break;
+ default:
+ let chCode = ch.charCodeAt(0);
+ if (chCode >= 0x30 && chCode <= 0x39) {
+ start++;
+ let n = chCode - 0x30;
+ if (n > m)
+ break;
+ if (start < replacementLength) {
+ let nextChCode = replacement.charCodeAt(start);
+ if (nextChCode >= 0x30 && nextChCode <= 0x39) {
+ let nn = 10 * n + nextChCode - 0x30;
+ if (nn <= m) {
+ n = nn;
+ start++;
+ }
+ }
+ }
+
+ if (n == 0)
+ break;
+
+ if (captures[n] != @undefined)
+ result = result + captures[n];
+ } else
+ result = result + "$";
+ break;
+ }
+ }
+ }
+
+ return result + replacement.substring(lastStart);
+ }
+
+ if (!@isObject(this))
+ @throwTypeError("RegExp.prototype.@@replace requires that |this| be an Object");
+
+ let regexp = this;
+
+ let str = @toString(strArg);
+ let stringLength = str.length;
+ let functionalReplace = typeof replace === 'function';
+
+ if (!functionalReplace)
+ replace = @toString(replace);
+
+ let global = regexp.global;
+ let unicode = false;
+
+ if (global) {
+ unicode = regexp.unicode;
+ regexp.lastIndex = 0;
+ }
+
+ let resultList = [];
+ let result;
+ let done = false;
+ while (!done) {
+ result = @regExpExec(regexp, str);
+
+ if (result === null)
+ done = true;
+ else {
+ resultList.@push(result);
+ if (!global)
+ done = true;
+ else {
+ let matchStr = @toString(result[0]);
+
+ if (!matchStr.length)
+ regexp.lastIndex = @advanceStringIndex(str, regexp.lastIndex, unicode);
+ }
+ }
+ }
+
+ let accumulatedResult = "";
+ let nextSourcePosition = 0;
+ let lastPosition = 0;
+
+ for (result of resultList) {
+ let nCaptures = result.length - 1;
+ if (nCaptures < 0)
+ nCaptures = 0;
+ let matched = @toString(result[0]);
+ let matchLength = matched.length;
+ let position = result.index;
+ position = (position > stringLength) ? stringLength : position;
+ position = (position < 0) ? 0 : position;
+
+ let captures = [];
+ for (let n = 1; n <= nCaptures; n++) {
+ let capN = result[n];
+ if (capN !== @undefined)
+ capN = @toString(capN);
+ captures[n] = capN;
+ }
+
+ let replacement;
+
+ if (functionalReplace) {
+ let replacerArgs = [ matched ].concat(captures.slice(1));
+ replacerArgs.@push(position);
+ replacerArgs.@push(str);
+
+ let replValue = replace.@apply(@undefined, replacerArgs);
+ replacement = @toString(replValue);
+ } else
+ replacement = getSubstitution(matched, str, position, captures, replace);
+
+ if (position >= nextSourcePosition && position >= lastPosition) {
+ accumulatedResult = accumulatedResult + str.substring(nextSourcePosition, position) + replacement;
+ nextSourcePosition = position + matchLength;
+ lastPosition = position;
+ }
+ }
+
+ if (nextSourcePosition >= stringLength)
+ return accumulatedResult;
+
+ return accumulatedResult + str.substring(nextSourcePosition);
+}
+
+// 21.2.5.9 RegExp.prototype[@@search] (string)
+function search(strArg)
+{
+ "use strict";
+
+ let regexp = this;
+
+ // Check for observable side effects and call the fast path if there aren't any.
+ if (@isRegExpObject(regexp) && @tryGetById(regexp, "exec") === @regExpBuiltinExec)
+ return @regExpSearchFast.@call(regexp, strArg);
+
+ // 1. Let rx be the this value.
+ // 2. If Type(rx) is not Object, throw a TypeError exception.
+ if (!@isObject(this))
+ @throwTypeError("RegExp.prototype.@@search requires that |this| be an Object");
+
+ // 3. Let S be ? ToString(string).
+ let str = @toString(strArg)
+
+ // 4. Let previousLastIndex be ? Get(rx, "lastIndex").
+ let previousLastIndex = regexp.lastIndex;
+ // 5. Perform ? Set(rx, "lastIndex", 0, true).
+ regexp.lastIndex = 0;
+ // 6. Let result be ? RegExpExec(rx, S).
+ let result = @regExpExec(regexp, str);
+ // 7. Perform ? Set(rx, "lastIndex", previousLastIndex, true).
+ regexp.lastIndex = previousLastIndex;
+ // 8. If result is null, return -1.
+ if (result === null)
+ return -1;
+ // 9. Return ? Get(result, "index").
+ return result.index;
+}
+
+@globalPrivate
+function hasObservableSideEffectsForRegExpSplit(regexp) {
+ // This is accessed by the RegExpExec internal function.
+ let regexpExec = @tryGetById(regexp, "exec");
+ if (regexpExec !== @regExpBuiltinExec)
+ return true;
+
+ // This is accessed by step 5 below.
+ let regexpFlags = @tryGetById(regexp, "flags");
+ if (regexpFlags !== @regExpProtoFlagsGetter)
+ return true;
+
+ // These are accessed by the builtin flags getter.
+ let regexpGlobal = @tryGetById(regexp, "global");
+ if (regexpGlobal !== @regExpProtoGlobalGetter)
+ return true;
+ let regexpIgnoreCase = @tryGetById(regexp, "ignoreCase");
+ if (regexpIgnoreCase !== @regExpProtoIgnoreCaseGetter)
+ return true;
+ let regexpMultiline = @tryGetById(regexp, "multiline");
+ if (regexpMultiline !== @regExpProtoMultilineGetter)
+ return true;
+ let regexpSticky = @tryGetById(regexp, "sticky");
+ if (regexpSticky !== @regExpProtoStickyGetter)
+ return true;
+ let regexpUnicode = @tryGetById(regexp, "unicode");
+ if (regexpUnicode !== @regExpProtoUnicodeGetter)
+ return true;
+
+ // This is accessed by the RegExp species constructor.
+ let regexpSource = @tryGetById(regexp, "source");
+ if (regexpSource !== @regExpProtoSourceGetter)
+ return true;
+
+ return !@isRegExpObject(regexp);
+}
+
+// ES 21.2.5.11 RegExp.prototype[@@split](string, limit)
+function split(string, limit)
+{
+ "use strict";
+
+ // 1. Let rx be the this value.
+ // 2. If Type(rx) is not Object, throw a TypeError exception.
+ if (!@isObject(this))
+ @throwTypeError("RegExp.prototype.@@split requires that |this| be an Object");
+ let regexp = this;
+
+ // 3. Let S be ? ToString(string).
+ let str = @toString(string);
+
+ // 4. Let C be ? SpeciesConstructor(rx, %RegExp%).
+ let speciesConstructor = @speciesConstructor(regexp, @RegExp);
+
+ if (speciesConstructor === @RegExp && !@hasObservableSideEffectsForRegExpSplit(regexp))
+ return @regExpSplitFast.@call(regexp, str, limit);
+
+ // 5. Let flags be ? ToString(? Get(rx, "flags")).
+ let flags = @toString(regexp.flags);
+
+ // 6. If flags contains "u", let unicodeMatching be true.
+ // 7. Else, let unicodeMatching be false.
+ let unicodeMatching = @stringIncludesInternal.@call(flags, "u");
+ // 8. If flags contains "y", let newFlags be flags.
+ // 9. Else, let newFlags be the string that is the concatenation of flags and "y".
+ let newFlags = @stringIncludesInternal.@call(flags, "y") ? flags : flags + "y";
+
+ // 10. Let splitter be ? Construct(C, « rx, newFlags »).
+ let splitter = new speciesConstructor(regexp, newFlags);
+
+ // We need to check again for RegExp subclasses that will fail the speciesConstructor test
+ // but can still use the fast path after we invoke the constructor above.
+ if (!@hasObservableSideEffectsForRegExpSplit(splitter))
+ return @regExpSplitFast.@call(splitter, str, limit);
+
+ // 11. Let A be ArrayCreate(0).
+ // 12. Let lengthA be 0.
+ let result = [];
+
+ // 13. If limit is undefined, let lim be 2^32-1; else let lim be ? ToUint32(limit).
+ limit = (limit === @undefined) ? 0xffffffff : limit >>> 0;
+
+ // 16. If lim = 0, return A.
+ if (!limit)
+ return result;
+
+ // 14. [Defered from above] Let size be the number of elements in S.
+ let size = str.length;
+
+ // 17. If size = 0, then
+ if (!size) {
+ // a. Let z be ? RegExpExec(splitter, S).
+ let z = @regExpExec(splitter, str);
+ // b. If z is not null, return A.
+ if (z != null)
+ return result;
+ // c. Perform ! CreateDataProperty(A, "0", S).
+ @putByValDirect(result, 0, str);
+ // d. Return A.
+ return result;
+ }
+
+ // 15. [Defered from above] Let p be 0.
+ let position = 0;
+ // 18. Let q be p.
+ let matchPosition = 0;
+
+ // 19. Repeat, while q < size
+ while (matchPosition < size) {
+ // a. Perform ? Set(splitter, "lastIndex", q, true).
+ splitter.lastIndex = matchPosition;
+ // b. Let z be ? RegExpExec(splitter, S).
+ let matches = @regExpExec(splitter, str);
+ // c. If z is null, let q be AdvanceStringIndex(S, q, unicodeMatching).
+ if (matches === null)
+ matchPosition = @advanceStringIndex(str, matchPosition, unicodeMatching);
+ // d. Else z is not null,
+ else {
+ // i. Let e be ? ToLength(? Get(splitter, "lastIndex")).
+ let endPosition = @toLength(splitter.lastIndex);
+ // ii. Let e be min(e, size).
+ endPosition = (endPosition <= size) ? endPosition : size;
+ // iii. If e = p, let q be AdvanceStringIndex(S, q, unicodeMatching).
+ if (endPosition === position)
+ matchPosition = @advanceStringIndex(str, matchPosition, unicodeMatching);
+ // iv. Else e != p,
+ else {
+ // 1. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through q (exclusive).
+ let subStr = @stringSubstrInternal.@call(str, position, matchPosition - position);
+ // 2. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
+ // 3. Let lengthA be lengthA + 1.
+ @putByValDirect(result, result.length, subStr);
+ // 4. If lengthA = lim, return A.
+ if (result.length == limit)
+ return result;
+
+ // 5. Let p be e.
+ position = endPosition;
+ // 6. Let numberOfCaptures be ? ToLength(? Get(z, "length")).
+ // 7. Let numberOfCaptures be max(numberOfCaptures-1, 0).
+ let numberOfCaptures = matches.length > 1 ? matches.length - 1 : 0;
+
+ // 8. Let i be 1.
+ let i = 1;
+ // 9. Repeat, while i <= numberOfCaptures,
+ while (i <= numberOfCaptures) {
+ // a. Let nextCapture be ? Get(z, ! ToString(i)).
+ let nextCapture = matches[i];
+ // b. Perform ! CreateDataProperty(A, ! ToString(lengthA), nextCapture).
+ // d. Let lengthA be lengthA + 1.
+ @putByValDirect(result, result.length, nextCapture);
+ // e. If lengthA = lim, return A.
+ if (result.length == limit)
+ return result;
+ // c. Let i be i + 1.
+ i++;
+ }
+ // 10. Let q be p.
+ matchPosition = position;
+ }
+ }
+ }
+ // 20. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through size (exclusive).
+ let remainingStr = @stringSubstrInternal.@call(str, position, size);
+ // 21. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
+ @putByValDirect(result, result.length, remainingStr);
+ // 22. Return A.
+ return result;
+}
+
+// ES 21.2.5.13 RegExp.prototype.test(string)
+@intrinsic=RegExpTestIntrinsic
+function test(strArg)
+{
+ "use strict";
+
+ let regexp = this;
+
+ // Check for observable side effects and call the fast path if there aren't any.
+ if (@isRegExpObject(regexp) && @tryGetById(regexp, "exec") === @regExpBuiltinExec)
+ return @regExpTestFast.@call(regexp, strArg);
+
+ // 1. Let R be the this value.
+ // 2. If Type(R) is not Object, throw a TypeError exception.
+ if (!@isObject(regexp))
+ @throwTypeError("RegExp.prototype.test requires that |this| be an Object");
+
+ // 3. Let string be ? ToString(S).
+ let str = @toString(strArg);
+
+ // 4. Let match be ? RegExpExec(R, string).
+ let match = @regExpExec(regexp, str);
+
+ // 5. If match is not null, return true; else return false.
+ if (match !== null)
+ return true;
+ return false;
+}
diff --git a/Source/JavaScriptCore/builtins/SetPrototype.js b/Source/JavaScriptCore/builtins/SetPrototype.js
new file mode 100644
index 000000000..e9b6626e9
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/SetPrototype.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function forEach(callback /*, thisArg */)
+{
+ "use strict";
+
+ if (!@isSet(this))
+ @throwTypeError("Set operation called on non-Set object");
+
+ if (typeof callback !== 'function')
+ @throwTypeError("Set.prototype.forEach callback must be a function");
+
+ var thisArg = @argument(1);
+ var iterator = @SetIterator(this);
+
+ // To avoid object allocations for iterator result objects, we pass the placeholder to the special "next" function in order to fill the results.
+ var value = [ @undefined ];
+ for (;;) {
+ if (@setIteratorNext.@call(iterator, value))
+ break;
+ callback.@call(thisArg, value[0], value[0], this);
+ }
+}
diff --git a/Source/JavaScriptCore/builtins/StringConstructor.js b/Source/JavaScriptCore/builtins/StringConstructor.js
new file mode 100644
index 000000000..a3293328b
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/StringConstructor.js
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function raw(template)
+{
+ "use strict";
+
+ if (template === null || template === @undefined)
+ @throwTypeError("String.raw requires template not be null or undefined");
+ var cookedSegments = @Object(template);
+
+ var rawValue = cookedSegments.raw;
+ if (rawValue === null || rawValue === @undefined)
+ @throwTypeError("String.raw requires template.raw not be null or undefined");
+ var rawSegments = @Object(rawValue);
+
+ var numberOfSubstitutions = arguments.length - 1;
+
+ var segmentCount = @toLength(rawSegments.length);
+
+ if (segmentCount <= 0)
+ return '';
+
+ var stringElements = '';
+ for (var i = 0; ; ++i) {
+ var segment = @toString(rawSegments[i]);
+ stringElements += segment;
+
+ if ((i + 1) === segmentCount)
+ return stringElements;
+
+ if (i < numberOfSubstitutions) {
+ var substitutionIndexInArguments = i + 1;
+ var next = @toString(arguments[substitutionIndexInArguments]);
+ stringElements += next;
+ }
+ }
+}
diff --git a/Source/JavaScriptCore/builtins/StringIteratorPrototype.js b/Source/JavaScriptCore/builtins/StringIteratorPrototype.js
new file mode 100644
index 000000000..52762dbf3
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/StringIteratorPrototype.js
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function next()
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("%StringIteratorPrototype%.next requires that |this| not be null or undefined");
+
+ var position = this.@stringIteratorNextIndex;
+ if (position === @undefined)
+ @throwTypeError("%StringIteratorPrototype%.next requires that |this| be a String Iterator instance");
+
+ var done = true;
+ var value = @undefined;
+
+ var string = this.@iteratedString;
+ if (string !== @undefined) {
+ var length = string.length >>> 0;
+ if (position >= length) {
+ this.@iteratedString = @undefined;
+ } else {
+ done = false;
+
+ var first = string.@charCodeAt(position);
+ if (first < 0xD800 || first > 0xDBFF || position + 1 === length)
+ value = string[position];
+ else {
+ var second = string.@charCodeAt(position + 1);
+ if (second < 0xDC00 || second > 0xDFFF)
+ value = string[position];
+ else
+ value = string[position] + string[position + 1];
+ }
+
+ this.@stringIteratorNextIndex = position + value.length;
+ }
+ }
+
+ return {done, value};
+}
diff --git a/Source/JavaScriptCore/builtins/StringPrototype.js b/Source/JavaScriptCore/builtins/StringPrototype.js
new file mode 100644
index 000000000..c9cdfcf02
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/StringPrototype.js
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2015 Andy VanWagoner <thetalecrafter@gmail.com>.
+ * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+function match(regexp)
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("String.prototype.match requires that |this| not be null or undefined");
+
+ if (regexp != null) {
+ var matcher = regexp.@matchSymbol;
+ if (matcher != @undefined)
+ return matcher.@call(regexp, this);
+ }
+
+ let thisString = @toString(this);
+ let createdRegExp = @regExpCreate(regexp, @undefined);
+ return createdRegExp.@matchSymbol(thisString);
+}
+
+@globalPrivate
+function repeatSlowPath(string, count)
+{
+ "use strict";
+
+ // Return an empty string.
+ if (count === 0 || string.length === 0)
+ return "";
+
+ // Return the original string.
+ if (count === 1)
+ return string;
+
+ if (string.length * count > @MAX_STRING_LENGTH)
+ @throwOutOfMemoryError();
+
+ // Bit operation onto |count| is safe because |count| should be within Int32 range,
+ // Repeat log N times to generate the repeated string rope.
+ var result = "";
+ var operand = string;
+ while (true) {
+ if (count & 1)
+ result += operand;
+ count >>= 1;
+ if (!count)
+ return result;
+ operand += operand;
+ }
+}
+
+@globalPrivate
+function repeatCharactersSlowPath(string, count)
+{
+ "use strict";
+ var repeatCount = (count / string.length) | 0;
+ var remainingCharacters = count - repeatCount * string.length;
+ var result = "";
+ var operand = string;
+ // Bit operation onto |repeatCount| is safe because |repeatCount| should be within Int32 range,
+ // Repeat log N times to generate the repeated string rope.
+ while (true) {
+ if (repeatCount & 1)
+ result += operand;
+ repeatCount >>= 1;
+ if (!repeatCount)
+ break;
+ operand += operand;
+ }
+ if (remainingCharacters)
+ result += @stringSubstrInternal.@call(string, 0, remainingCharacters);
+ return result;
+}
+
+
+function repeat(count)
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("String.prototype.repeat requires that |this| not be null or undefined");
+
+ var string = @toString(this);
+ count = @toInteger(count);
+
+ if (count < 0 || count === @Infinity)
+ @throwRangeError("String.prototype.repeat argument must be greater than or equal to 0 and not be Infinity");
+
+ if (string.length === 1)
+ return @repeatCharacter(string, count);
+
+ return @repeatSlowPath(string, count);
+}
+
+function padStart(maxLength/*, fillString*/)
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("String.prototype.padStart requires that |this| not be null or undefined");
+
+ var string = @toString(this);
+ maxLength = @toLength(maxLength);
+
+ var stringLength = string.length;
+ if (maxLength <= stringLength)
+ return string;
+
+ var filler;
+ var fillString = @argument(1);
+ if (fillString === @undefined)
+ filler = " ";
+ else {
+ filler = @toString(fillString);
+ if (filler === "")
+ return string;
+ }
+
+ if (maxLength > @MAX_STRING_LENGTH)
+ @throwOutOfMemoryError();
+
+ var fillLength = maxLength - stringLength;
+ var truncatedStringFiller;
+
+ if (filler.length === 1)
+ truncatedStringFiller = @repeatCharacter(filler, fillLength);
+ else
+ truncatedStringFiller = @repeatCharactersSlowPath(filler, fillLength);
+ return truncatedStringFiller + string;
+}
+
+function padEnd(maxLength/*, fillString*/)
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("String.prototype.padEnd requires that |this| not be null or undefined");
+
+ var string = @toString(this);
+ maxLength = @toLength(maxLength);
+
+ var stringLength = string.length;
+ if (maxLength <= stringLength)
+ return string;
+
+ var filler;
+ var fillString = @argument(1);
+ if (fillString === @undefined)
+ filler = " ";
+ else {
+ filler = @toString(fillString);
+ if (filler === "")
+ return string;
+ }
+
+ if (maxLength > @MAX_STRING_LENGTH)
+ @throwOutOfMemoryError();
+
+ var fillLength = maxLength - stringLength;
+ var truncatedStringFiller;
+
+ if (filler.length === 1)
+ truncatedStringFiller = @repeatCharacter(filler, fillLength);
+ else
+ truncatedStringFiller = @repeatCharactersSlowPath(filler, fillLength);
+ return string + truncatedStringFiller;
+}
+
+@globalPrivate
+function hasObservableSideEffectsForStringReplace(regexp, replacer) {
+ if (replacer !== @regExpPrototypeSymbolReplace)
+ return true;
+
+ let regexpExec = @tryGetById(regexp, "exec");
+ if (regexpExec !== @regExpBuiltinExec)
+ return true;
+
+ let regexpGlobal = @tryGetById(regexp, "global");
+ if (regexpGlobal !== @regExpProtoGlobalGetter)
+ return true;
+
+ let regexpUnicode = @tryGetById(regexp, "unicode");
+ if (regexpUnicode !== @regExpProtoUnicodeGetter)
+ return true;
+
+ return !@isRegExpObject(regexp);
+}
+
+@intrinsic=StringPrototypeReplaceIntrinsic
+function replace(search, replace)
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("String.prototype.replace requires that |this| not be null or undefined");
+
+ if (search != null) {
+ let replacer = search.@replaceSymbol;
+ if (replacer !== @undefined) {
+ if (!@hasObservableSideEffectsForStringReplace(search, replacer))
+ return @toString(this).@replaceUsingRegExp(search, replace);
+ return replacer.@call(search, this, replace);
+ }
+ }
+
+ let thisString = @toString(this);
+ let searchString = @toString(search);
+ return thisString.@replaceUsingStringSearch(searchString, replace);
+}
+
+function localeCompare(that/*, locales, options */)
+{
+ "use strict";
+
+ // 13.1.1 String.prototype.localeCompare (that [, locales [, options ]]) (ECMA-402 2.0)
+ // http://ecma-international.org/publications/standards/Ecma-402.htm
+
+ // 1. Let O be RequireObjectCoercible(this value).
+ if (this == null)
+ @throwTypeError("String.prototype.localeCompare requires that |this| not be null or undefined");
+
+ // 2. Let S be ToString(O).
+ // 3. ReturnIfAbrupt(S).
+ var thisString = @toString(this);
+
+ // 4. Let That be ToString(that).
+ // 5. ReturnIfAbrupt(That).
+ var thatString = @toString(that);
+
+ // Avoid creating a collator for defaults.
+ var locales = @argument(1);
+ var options = @argument(2);
+ if (locales === @undefined && options === @undefined)
+ return @Collator.prototype.compare(thisString, thatString);
+
+ // 6. Let collator be Construct(%Collator%, «locales, options»).
+ // 7. ReturnIfAbrupt(collator).
+ var collator = new @Collator(locales, options);
+
+ // 8. Return CompareStrings(collator, S, That).
+ return collator.compare(thisString, thatString);
+}
+
+function search(regexp)
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("String.prototype.search requires that |this| not be null or undefined");
+
+ if (regexp != null) {
+ var searcher = regexp.@searchSymbol;
+ if (searcher != @undefined)
+ return searcher.@call(regexp, this);
+ }
+
+ var thisString = @toString(this);
+ var createdRegExp = @regExpCreate(regexp, @undefined);
+ return createdRegExp.@searchSymbol(thisString);
+}
+
+function split(separator, limit)
+{
+ "use strict";
+
+ if (this == null)
+ @throwTypeError("String.prototype.split requires that |this| not be null or undefined");
+
+ if (separator != null) {
+ var splitter = separator.@splitSymbol;
+ if (splitter != @undefined)
+ return splitter.@call(separator, this, limit);
+ }
+
+ return @stringSplitFast.@call(this, separator, limit);
+}
diff --git a/Source/JavaScriptCore/builtins/TypedArrayConstructor.js b/Source/JavaScriptCore/builtins/TypedArrayConstructor.js
new file mode 100644
index 000000000..54a957b23
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/TypedArrayConstructor.js
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// According to the spec we are supposed to crawl the prototype chain looking
+// for the a TypedArray constructor. The way we implement this is with a
+// private function, @alloctateTypedArray, on each of the prototypes.
+// This enables us to optimize this lookup in the inline cache.
+
+function of(/* items... */)
+{
+ "use strict";
+ let len = arguments.length;
+ let constructFunction = this.@allocateTypedArray;
+ if (constructFunction === @undefined)
+ @throwTypeError("TypedArray.of requires its this argument to subclass a TypedArray constructor");
+
+ let result = constructFunction(len);
+
+ for (let i = 0; i < len; i++)
+ result[i] = arguments[i];
+
+ return result;
+}
+
+function from(items /* [ , mapfn [ , thisArg ] ] */)
+{
+ "use strict";
+
+ let mapFn = @argument(1);
+
+ let thisArg;
+
+ if (mapFn !== @undefined) {
+ if (typeof mapFn !== "function")
+ @throwTypeError("TypedArray.from requires that the second argument, when provided, be a function");
+
+ thisArg = @argument(2);
+ }
+
+ if (items == null)
+ @throwTypeError("TypedArray.from requires an array-like object - not null or undefined");
+
+ let iteratorMethod = items.@iteratorSymbol;
+ if (iteratorMethod != null) {
+ if (typeof iteratorMethod !== "function")
+ @throwTypeError("TypedArray.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
+
+ let accumulator = [];
+
+ let k = 0;
+ let iterator = iteratorMethod.@call(items);
+
+ // Since for-of loop once more looks up the @@iterator property of a given iterable,
+ // it could be observable if the user defines a getter for @@iterator.
+ // To avoid this situation, we define a wrapper object that @@iterator just returns a given iterator.
+ let wrapper = {};
+ wrapper.@iteratorSymbol = function() { return iterator; }
+
+ for (let value of wrapper) {
+ if (mapFn)
+ @putByValDirect(accumulator, k, thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k));
+ else
+ @putByValDirect(accumulator, k, value);
+ k++;
+ }
+
+ let constructFunction = this.@allocateTypedArray;
+ if (constructFunction === @undefined)
+ @throwTypeError("TypedArray.from requires its this argument subclass a TypedArray constructor");
+
+ let result = constructFunction(k);
+
+ for (let i = 0; i < k; i++)
+ result[i] = accumulator[i];
+
+
+ return result;
+ }
+
+ let arrayLike = @Object(items);
+ let arrayLikeLength = @toLength(arrayLike.length);
+
+ let constructFunction = this.@allocateTypedArray;
+ if (constructFunction === @undefined)
+ @throwTypeError("this does not subclass a TypedArray constructor");
+
+ let result = constructFunction(arrayLikeLength);
+
+ let k = 0;
+ while (k < arrayLikeLength) {
+ let value = arrayLike[k];
+ if (mapFn)
+ result[k] = thisArg === @undefined ? mapFn(value, k) : mapFn.@call(thisArg, value, k);
+ else
+ result[k] = value;
+ k++;
+ }
+
+ return result;
+}
+
+function allocateInt8Array(length)
+{
+ return new @Int8Array(length);
+}
+
+function allocateInt16Array(length)
+{
+ return new @Int16Array(length);
+}
+
+function allocateInt32Array(length)
+{
+ return new @Int32Array(length);
+}
+
+function allocateUint32Array(length)
+{
+ return new @Uint32Array(length);
+}
+
+function allocateUint16Array(length)
+{
+ return new @Uint16Array(length);
+}
+
+function allocateUint8Array(length)
+{
+ return new @Uint8Array(length);
+}
+
+function allocateUint8ClampedArray(length)
+{
+ return new @Uint8ClampedArray(length);
+}
+
+function allocateFloat32Array(length)
+{
+ return new @Float32Array(length);
+}
+
+function allocateFloat64Array(length)
+{
+ return new @Float64Array(length);
+}
diff --git a/Source/JavaScriptCore/builtins/TypedArrayPrototype.js b/Source/JavaScriptCore/builtins/TypedArrayPrototype.js
new file mode 100644
index 000000000..53674bf7b
--- /dev/null
+++ b/Source/JavaScriptCore/builtins/TypedArrayPrototype.js
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Note that the intrisic @typedArrayLength checks that the argument passed is a typed array
+// and throws if it is not.
+
+
+// Typed Arrays have their own species constructor function since they need
+// to look up their default constructor, which is expensive. If we used the
+// normal speciesConstructor helper we would need to look up the default
+// constructor every time.
+@globalPrivate
+function typedArraySpeciesConstructor(value)
+{
+ "use strict";
+ let constructor = value.constructor;
+ if (constructor === @undefined)
+ return @typedArrayGetOriginalConstructor(value);
+
+ if (!@isObject(constructor))
+ @throwTypeError("|this|.constructor is not an Object or undefined");
+
+ constructor = constructor.@speciesSymbol;
+ if (constructor == null)
+ return @typedArrayGetOriginalConstructor(value);
+ // The lack of an @isConstructor(constructor) check here is not observable because
+ // the first thing we will do with the value is attempt to construct the result with it.
+ // If any user of this function does not immediately construct the result they need to
+ // verify that the result is a constructor.
+ return constructor;
+}
+
+@globalPrivate
+function typedArrayClampArgumentToStartOrEnd(value, length, undefinedValue)
+{
+ "use strict";
+
+ if (value === @undefined)
+ return undefinedValue;
+
+ let int = @toInteger(value);
+ if (int < 0) {
+ int += length;
+ return int < 0 ? 0 : int;
+ }
+ return int > length ? length : int;
+}
+
+function values()
+{
+ "use strict";
+ @typedArrayLength(this);
+ return new @createArrayIterator(this, "value", @arrayIteratorValueNext);
+}
+
+function keys()
+{
+ "use strict";
+ @typedArrayLength(this);
+ return new @createArrayIterator(this, "key", @arrayIteratorKeyNext);
+}
+
+function entries()
+{
+ "use strict";
+ @typedArrayLength(this);
+ return new @createArrayIterator(this, "key+value", @arrayIteratorKeyValueNext);
+}
+
+function every(callback /*, thisArg */)
+{
+ "use strict";
+ var length = @typedArrayLength(this);
+ var thisArg = @argument(1);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.every callback must be a function");
+
+ for (var i = 0; i < length; i++) {
+ if (!callback.@call(thisArg, this[i], i, this))
+ return false;
+ }
+
+ return true;
+}
+
+function fill(value /* [, start [, end]] */)
+{
+ "use strict";
+
+ let length = @typedArrayLength(this);
+
+ let start = @argument(1);
+ let end = @argument(2);
+
+ start = @typedArrayClampArgumentToStartOrEnd(start, length, 0);
+ end = @typedArrayClampArgumentToStartOrEnd(end, length, length);
+
+ for (let i = start; i < end; i++)
+ this[i] = value;
+ return this;
+}
+
+function find(callback /* [, thisArg] */)
+{
+ "use strict";
+ var length = @typedArrayLength(this);
+ var thisArg = @argument(1);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.find callback must be a function");
+
+ for (var i = 0; i < length; i++) {
+ let elem = this[i];
+ if (callback.@call(thisArg, elem, i, this))
+ return elem;
+ }
+ return @undefined;
+}
+
+function findIndex(callback /* [, thisArg] */)
+{
+ "use strict";
+ var length = @typedArrayLength(this);
+ var thisArg = @argument(1);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.findIndex callback must be a function");
+
+ for (var i = 0; i < length; i++) {
+ if (callback.@call(thisArg, this[i], i, this))
+ return i;
+ }
+ return -1;
+}
+
+function forEach(callback /* [, thisArg] */)
+{
+ "use strict";
+ var length = @typedArrayLength(this);
+ var thisArg = @argument(1);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.forEach callback must be a function");
+
+ for (var i = 0; i < length; i++)
+ callback.@call(thisArg, this[i], i, this);
+}
+
+function some(callback /* [, thisArg] */)
+{
+ // 22.2.3.24
+ "use strict";
+ var length = @typedArrayLength(this);
+ var thisArg = @argument(1);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.some callback must be a function");
+
+ for (var i = 0; i < length; i++) {
+ if (callback.@call(thisArg, this[i], i, this))
+ return true;
+ }
+
+ return false;
+}
+
+function sort(comparator)
+{
+ // 22.2.3.25
+ "use strict";
+
+ function min(a, b)
+ {
+ return a < b ? a : b;
+ }
+
+ function merge(dst, src, srcIndex, srcEnd, width, comparator)
+ {
+ var left = srcIndex;
+ var leftEnd = min(left + width, srcEnd);
+ var right = leftEnd;
+ var rightEnd = min(right + width, srcEnd);
+
+ for (var dstIndex = left; dstIndex < rightEnd; ++dstIndex) {
+ if (right < rightEnd) {
+ if (left >= leftEnd || comparator(src[right], src[left]) < 0) {
+ dst[dstIndex] = src[right++];
+ continue;
+ }
+ }
+
+ dst[dstIndex] = src[left++];
+ }
+ }
+
+ function mergeSort(array, valueCount, comparator)
+ {
+ var buffer = [ ];
+ buffer.length = valueCount;
+
+ var dst = buffer;
+ var src = array;
+
+ for (var width = 1; width < valueCount; width *= 2) {
+ for (var srcIndex = 0; srcIndex < valueCount; srcIndex += 2 * width)
+ merge(dst, src, srcIndex, valueCount, width, comparator);
+
+ var tmp = src;
+ src = dst;
+ dst = tmp;
+ }
+
+ if (src != array) {
+ for(var i = 0; i < valueCount; i++)
+ array[i] = src[i];
+ }
+ }
+
+ var length = @typedArrayLength(this);
+
+ if (length < 2)
+ return;
+
+ if (typeof comparator == "function")
+ mergeSort(this, length, comparator);
+ else
+ @typedArraySort(this);
+
+ return this;
+}
+
+function subarray(begin, end)
+{
+ "use strict";
+
+ if (!@isTypedArrayView(this))
+ @throwTypeError("|this| should be a typed array view");
+
+ let start = @toInteger(begin);
+ let finish;
+ if (end !== @undefined)
+ finish = @toInteger(end);
+
+ let constructor = @typedArraySpeciesConstructor(this);
+
+ return @typedArraySubarrayCreate.@call(this, start, finish, constructor);
+}
+
+function reduce(callback /* [, initialValue] */)
+{
+ // 22.2.3.19
+ "use strict";
+
+ var length = @typedArrayLength(this);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.reduce callback must be a function");
+
+ var argumentCount = @argumentCount();
+ if (length === 0 && argumentCount < 2)
+ @throwTypeError("TypedArray.prototype.reduce of empty array with no initial value");
+
+ var accumulator, k = 0;
+ if (argumentCount > 1)
+ accumulator = @argument(1);
+ else
+ accumulator = this[k++];
+
+ for (; k < length; k++)
+ accumulator = callback.@call(@undefined, accumulator, this[k], k, this);
+
+ return accumulator;
+}
+
+function reduceRight(callback /* [, initialValue] */)
+{
+ // 22.2.3.20
+ "use strict";
+
+ var length = @typedArrayLength(this);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.reduceRight callback must be a function");
+
+ var argumentCount = @argumentCount();
+ if (length === 0 && argumentCount < 2)
+ @throwTypeError("TypedArray.prototype.reduceRight of empty array with no initial value");
+
+ var accumulator, k = length - 1;
+ if (argumentCount > 1)
+ accumulator = @argument(1);
+ else
+ accumulator = this[k--];
+
+ for (; k >= 0; k--)
+ accumulator = callback.@call(@undefined, accumulator, this[k], k, this);
+
+ return accumulator;
+}
+
+function map(callback /*, thisArg */)
+{
+ // 22.2.3.18
+ "use strict";
+
+ var length = @typedArrayLength(this);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.map callback must be a function");
+
+ var thisArg = @argument(1);
+
+ // Do species construction
+ var constructor = this.constructor;
+ var result;
+ if (constructor === @undefined)
+ result = new (@typedArrayGetOriginalConstructor(this))(length);
+ else {
+ var speciesConstructor = @Object(constructor).@speciesSymbol;
+ if (speciesConstructor === null || speciesConstructor === @undefined)
+ result = new (@typedArrayGetOriginalConstructor(this))(length);
+ else {
+ result = new speciesConstructor(length);
+ // typedArrayLength throws if it doesn't get a view.
+ @typedArrayLength(result);
+ }
+ }
+
+ for (var i = 0; i < length; i++) {
+ var mappedValue = callback.@call(thisArg, this[i], i, this);
+ result[i] = mappedValue;
+ }
+ return result;
+}
+
+function filter(callback /*, thisArg */)
+{
+ "use strict";
+
+ var length = @typedArrayLength(this);
+
+ if (typeof callback !== "function")
+ @throwTypeError("TypedArray.prototype.filter callback must be a function");
+
+ var thisArg = @argument(1);
+ var kept = [];
+
+ for (var i = 0; i < length; i++) {
+ var value = this[i];
+ if (callback.@call(thisArg, value, i, this))
+ kept.@push(value);
+ }
+
+ var constructor = this.constructor;
+ var result;
+ var resultLength = kept.length;
+ if (constructor === @undefined)
+ result = new (@typedArrayGetOriginalConstructor(this))(resultLength);
+ else {
+ var speciesConstructor = @Object(constructor).@speciesSymbol;
+ if (speciesConstructor === null || speciesConstructor === @undefined)
+ result = new (@typedArrayGetOriginalConstructor(this))(resultLength);
+ else {
+ result = new speciesConstructor(resultLength);
+ // typedArrayLength throws if it doesn't get a view.
+ @typedArrayLength(result);
+ }
+ }
+
+ for (var i = 0; i < kept.length; i++)
+ result[i] = kept[i];
+
+ return result;
+}
+
+function toLocaleString()
+{
+ "use strict";
+
+ var length = @typedArrayLength(this);
+
+ if (length == 0)
+ return "";
+
+ var string = this[0].toLocaleString();
+ for (var i = 1; i < length; i++)
+ string += "," + this[i].toLocaleString();
+
+ return string;
+}