-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Copying from the matrix:
If your fast path is guarded on IsPromise(p) && GetOwnProperty(p, 'then') == undefined && GetPrototypeOf(p) == %Promise.prototype%, that never runs user code (because the IsPromise(p) check rules out proxies, which means the other two checks are unobservable).
This is slightly different from the existing fast-path in PromiseResolve, but that could probably changed to match this; it's getting at the same concept. There should be very few things for which these two tests differ.
EDIT: Per below I think we actually want IsPromise(p) && GetPrototypeOf(p) === C.prototype, where C is the built-in %Promise% in every case except in the actual static .resolve() method (in which case it's the class on which .resolve was invoked). This has the advantage of preserving current behavior (except for the .constructor lookup) when calling PromiseSubclass.resolve(). And it's still unobservable for any actual await, and for the built-in promise resolution functions created by the Promise constructor, because in those cases C will be the native Promise, and the .prototype property of the native Promise is nonwritable/nonconfigurable.
This is very close to the current check in PromiseResolve, which is IsPromise(p) && p.constructor === C, except that it's unobservable (except in the DerivedPromise.resolve() case). So it's unlikely to break anything, even subclasses of Promise.
Specifically, this keeps the same behavior for
- regular
new Promisepromises (fast path) new Promisepromises which have been patched with a custom.then(fast path)- instances of
Promisesubclasses usingclass extends Promise(no fast path) - thenable objects which do not inherit from
Promise, unless they've manually set.constructor = Promisein which case they probably were broken (no fast path) - thenable objects which manually inherit from Promise as in
{ __proto__: Promise.prototype }(no fast path)
It changes behavior for
new Promisepromises which had their.constructormanually changed away fromPromise(previously not fast path, now fast path)- instances of
Promisesubclasses usingclass extends Promisewhich had their.constructormanually changed toPromise(previously fast path, now not fast path)
The change in behavior is just whether accessors on .constructor are triggered and whether some object gets the fast path in cases where people were manually changing the .constructor. I strongly suspect these changes would be web compatible.