Title: [197428] trunk/Source/_javascript_Core
Revision
197428
Author
[email protected]
Date
2016-03-01 17:08:53 -0800 (Tue, 01 Mar 2016)

Log Message

Promise.prototype.then should use Symbol.species to construct the return Promise
https://bugs.webkit.org/show_bug.cgi?id=154862

Reviewed by Saam Barati.

* builtins/PromisePrototype.js:
* tests/stress/promise-species-functions.js: Added.
(Symbol.species):
(id):
(funcThrows):
(makeC):
(test.species):
(test.speciesThrows):
(test):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (197427 => 197428)


--- trunk/Source/_javascript_Core/ChangeLog	2016-03-02 01:02:13 UTC (rev 197427)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-03-02 01:08:53 UTC (rev 197428)
@@ -1,3 +1,20 @@
+2016-03-01  Keith Miller  <[email protected]>
+
+        Promise.prototype.then should use Symbol.species to construct the return Promise
+        https://bugs.webkit.org/show_bug.cgi?id=154862
+
+        Reviewed by Saam Barati.
+
+        * builtins/PromisePrototype.js:
+        * tests/stress/promise-species-functions.js: Added.
+        (Symbol.species):
+        (id):
+        (funcThrows):
+        (makeC):
+        (test.species):
+        (test.speciesThrows):
+        (test):
+
 2016-03-01  Michael Saboff  <[email protected]>
 
         [ES6] Add support for Unicode regular expressions

Modified: trunk/Source/_javascript_Core/builtins/PromisePrototype.js (197427 => 197428)


--- trunk/Source/_javascript_Core/builtins/PromisePrototype.js	2016-03-02 01:02:13 UTC (rev 197427)
+++ trunk/Source/_javascript_Core/builtins/PromisePrototype.js	2016-03-02 01:08:53 UTC (rev 197428)
@@ -37,9 +37,16 @@
     if (!@isPromise(this))
         throw new @TypeError("|this| is not a object");
 
-    // FIXME: Fix this code when @@species well-known symbol is landed.
-    // https://bugs.webkit.org/show_bug.cgi?id=146624
     var constructor = this.constructor;
+    if (constructor === @undefined)
+        constructor = @Promise;
+    else if (!@isObject(constructor))
+        throw new @TypeError("|this|.constructor is not an Object or undefined");
+    else {
+        constructor = constructor[@symbolSpecies];
+        if (constructor == null)
+            constructor = @Promise;
+    }
 
     var resultCapability = @newPromiseCapability(constructor);
 

Added: trunk/Source/_javascript_Core/tests/stress/promise-species-functions.js (0 => 197428)


--- trunk/Source/_javascript_Core/tests/stress/promise-species-functions.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/promise-species-functions.js	2016-03-02 01:08:53 UTC (rev 197428)
@@ -0,0 +1,72 @@
+C = class extends Promise { }
+N = class { }
+N[Symbol.species] = function() { throw "this should never be called"; }
+
+function id(x) { return x; }
+
+testFunctions = [
+    [Promise.prototype.then, [id]]
+];
+
+objProp = Object.defineProperty;
+
+function funcThrows(func, args) {
+    try {
+        func.call(...args)
+        return false;
+    } catch (e) {
+        return true;
+    }
+}
+
+function makeC() {
+    return new C(function(resolve) { resolve(1); });
+}
+
+function test(testData) {
+    "use strict";
+    let [protoFunction, args] = testData;
+    let foo = makeC()
+    let n = new N();
+
+    // Test promise defaults cases.
+    foo = makeC();
+
+    objProp(C, Symbol.species, { value: undefined, writable: true});
+    let bar = protoFunction.call(foo, ...args);
+    if (!(bar instanceof Promise) || bar instanceof C)
+        throw Error();
+
+    C[Symbol.species] = null;
+    bar = protoFunction.call(foo, ...args);
+    if (!(bar instanceof Promise) || bar instanceof C)
+        throw Error();
+
+    // Test species is custom constructor.
+    let called = false;
+    function species() {
+        called = true;
+        return new C(...arguments);
+    }
+
+    C[Symbol.species] = species;
+    bar = protoFunction.call(foo, ...args);
+
+    if (!(bar instanceof Promise) || !(bar instanceof C) || !called)
+        throw Error("failed on " + protoFunction);
+
+    function speciesThrows() {
+        throw Error();
+    }
+
+    C[Symbol.species] = speciesThrows;
+    if (!funcThrows(protoFunction, [foo, ...args]))
+        throw "didn't throw";
+
+    C[Symbol.species] = true;
+    if (!funcThrows(protoFunction, [foo, ...args]))
+        throw "didn't throw";
+
+}
+
+testFunctions.forEach(test);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to