From da0dd081dc173b3d595fb7558cd946d04a863e90 Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Thu, 11 Sep 2025 02:47:01 +0000 Subject: [PATCH 1/8] Normative: PromiseResolve check proto instead of constructor Co-authored-by: Kevin Gibbons --- spec.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 0ad7fc2baf..4ed520da45 100644 --- a/spec.html +++ b/spec.html @@ -49141,8 +49141,9 @@

1. If IsPromise(_x_) is *true*, then - 1. Let _xConstructor_ be ? Get(_x_, *"constructor"*). - 1. If SameValue(_xConstructor_, _C_) is *true*, return _x_. + 1. Let _xProto_ be ! _x_.[[GetPrototypeOf]](). + 1. Let _CPrototype_ be ? Get(_C_, *"prototype"*). + 1. If SameValue(_xProto_, _CPrototype_) is *true*, return _x_. 1. Let _promiseCapability_ be ? NewPromiseCapability(_C_). 1. Perform ? Call(_promiseCapability_.[[Resolve]], *undefined*, « _x_ »). 1. Return _promiseCapability_.[[Promise]]. From 53b2ab1f69b22357bd758d3b275b28ecde8256ad Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Thu, 11 Sep 2025 04:32:03 +0000 Subject: [PATCH 2/8] Normative: resolve function adopts promises --- spec.html | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/spec.html b/spec.html index 4ed520da45..b2b4d800bf 100644 --- a/spec.html +++ b/spec.html @@ -3890,6 +3890,16 @@

Well-Known Intrinsic Objects

The Promise constructor () + + + %PromiseThenAction% + + + + + An internal function object for PerformPromiseThen + + %Proxy% @@ -48472,14 +48482,19 @@

Promise Resolve Functions

1. If _resolution_ is not an Object, then 1. Perform FulfillPromise(_promise_, _resolution_). 1. Return *undefined*. - 1. Let _then_ be Completion(Get(_resolution_, *"then"*)). - 1. If _then_ is an abrupt completion, then - 1. Perform RejectPromise(_promise_, _then_.[[Value]]). - 1. Return *undefined*. - 1. Let _thenAction_ be _then_.[[Value]]. - 1. If IsCallable(_thenAction_) is *false*, then - 1. Perform FulfillPromise(_promise_, _resolution_). - 1. Return *undefined*. + 1. Let _thenAction_ be *null*. + 1. If IsPromise(_resolution_) is *true*, then + 1. Let _proto_ be ! _resolution_.[[GetPrototypeOf]](). + 1. If SameValue(_proto_, %Promise.prototype%) is *true*, set _thenAction_ to %PromiseThenAction%. + 1. If _thenAction_ is *null*, then + 1. Let _then_ be Completion(Get(_resolution_, *"then"*)). + 1. If _then_ is an abrupt completion, then + 1. Perform RejectPromise(_promise_, _then_.[[Value]]). + 1. Return *undefined*. + 1. Set _thenAction_ to _then_.[[Value]]. + 1. If IsCallable(_thenAction_) is *false*, then + 1. Perform FulfillPromise(_promise_, _resolution_). + 1. Return *undefined*. 1. Let _thenJobCallback_ be HostMakeJobCallback(_thenAction_). 1. Let _job_ be NewPromiseResolveThenableJob(_promise_, _resolution_, _thenJobCallback_). 1. Perform HostEnqueuePromiseJob(_job_.[[Job]], _job_.[[Realm]]). @@ -48487,6 +48502,22 @@

Promise Resolve Functions

The *"length"* property of a promise resolve function is *1*𝔽.

+ + +

%PromiseThenAction% ( _onFulfilled_, _onRejected_ )

+

The %PromiseThenAction% intrinsic function:

+
    +
  • is an anonymous built-in function object that is defined once for each realm.
  • +
  • is never directly accessible to ECMAScript code.
  • +
  • is used by the promise resolve functions to adopt the state of the promise passed as the receiver.
  • +
  • performs the following steps when called:
  • +
+ + 1. Let _promise_ be the *this* value. + 1. Assert: IsPromise(_promise_) is *true*. + 1. Return PerformPromiseThen(_promise_, _onFulfilled_, _onRejected_). + +
From ed27ba3e99bdfd345115624856741f86d1b7f250 Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Thu, 11 Sep 2025 17:00:31 +0000 Subject: [PATCH 3/8] fixup! Normative: PromiseResolve check proto instead of constructor Co-authored-by: Kevin Gibbons --- spec.html | 1 + 1 file changed, 1 insertion(+) diff --git a/spec.html b/spec.html index b2b4d800bf..ec030f4df3 100644 --- a/spec.html +++ b/spec.html @@ -49174,6 +49174,7 @@

1. If IsPromise(_x_) is *true*, then 1. Let _xProto_ be ! _x_.[[GetPrototypeOf]](). 1. Let _CPrototype_ be ? Get(_C_, *"prototype"*). + 1. NOTE: When _C_ is the intrinsic %Promise%, the above step cannot throw. 1. If SameValue(_xProto_, _CPrototype_) is *true*, return _x_. 1. Let _promiseCapability_ be ? NewPromiseCapability(_C_). 1. Perform ? Call(_promiseCapability_.[[Resolve]], *undefined*, « _x_ »). From 02dc66b94a53273bece4469edaa77114100f134e Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Thu, 11 Sep 2025 18:51:50 +0000 Subject: [PATCH 4/8] fixup! Normative: resolve function adopts promises Highlight that %PromiseThenAction% is not accessible to user code when calling HostMakeJobCallback --- spec.html | 1 + 1 file changed, 1 insertion(+) diff --git a/spec.html b/spec.html index ec030f4df3..ba19d30b01 100644 --- a/spec.html +++ b/spec.html @@ -48496,6 +48496,7 @@

Promise Resolve Functions

1. Perform FulfillPromise(_promise_, _resolution_). 1. Return *undefined*. 1. Let _thenJobCallback_ be HostMakeJobCallback(_thenAction_). + 1. NOTE: _thenAction_ may be %PromiseThenAction%, a value never directly accessible to ECMAScript code. 1. Let _job_ be NewPromiseResolveThenableJob(_promise_, _resolution_, _thenJobCallback_). 1. Perform HostEnqueuePromiseJob(_job_.[[Job]], _job_.[[Realm]]). 1. Return *undefined*. From 23f37119358a6e0e3315b1265085cdd316982215 Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Tue, 16 Sep 2025 19:52:01 +0000 Subject: [PATCH 5/8] fixup! Normative: PromiseResolve check proto instead of constructor Co-authored-by: Kevin Gibbons --- spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.html b/spec.html index ba19d30b01..f522816de6 100644 --- a/spec.html +++ b/spec.html @@ -49175,7 +49175,7 @@

1. If IsPromise(_x_) is *true*, then 1. Let _xProto_ be ! _x_.[[GetPrototypeOf]](). 1. Let _CPrototype_ be ? Get(_C_, *"prototype"*). - 1. NOTE: When _C_ is the intrinsic %Promise%, the above step cannot throw. + 1. NOTE: When _C_ is the intrinsic %Promise%, the above step cannot throw and always results in the intrinsic %Promise.prototype%. 1. If SameValue(_xProto_, _CPrototype_) is *true*, return _x_. 1. Let _promiseCapability_ be ? NewPromiseCapability(_C_). 1. Perform ? Call(_promiseCapability_.[[Resolve]], *undefined*, « _x_ »). From 0de5715bb104d909d845fd2a1f4ce7a0ffd35935 Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Tue, 16 Sep 2025 19:55:01 +0000 Subject: [PATCH 6/8] fixup! Normative: resolve function adopts promises Assert promise resolution is an ordinary object --- spec.html | 1 + 1 file changed, 1 insertion(+) diff --git a/spec.html b/spec.html index f522816de6..e2896ca0f8 100644 --- a/spec.html +++ b/spec.html @@ -48484,6 +48484,7 @@

Promise Resolve Functions

1. Return *undefined*. 1. Let _thenAction_ be *null*. 1. If IsPromise(_resolution_) is *true*, then + 1. Assert: _resolution_ is an ordinary object. 1. Let _proto_ be ! _resolution_.[[GetPrototypeOf]](). 1. If SameValue(_proto_, %Promise.prototype%) is *true*, set _thenAction_ to %PromiseThenAction%. 1. If _thenAction_ is *null*, then From ed3e660a47e01a83eb5b229b087ab5a70d451c16 Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Tue, 16 Sep 2025 20:01:08 +0000 Subject: [PATCH 7/8] fixup! Normative: PromiseResolve check proto instead of constructor Assert promise resolution is an ordinary object --- spec.html | 1 + 1 file changed, 1 insertion(+) diff --git a/spec.html b/spec.html index e2896ca0f8..bf86d8f0de 100644 --- a/spec.html +++ b/spec.html @@ -49174,6 +49174,7 @@

1. If IsPromise(_x_) is *true*, then + 1. Assert: _x_ is an ordinary object. 1. Let _xProto_ be ! _x_.[[GetPrototypeOf]](). 1. Let _CPrototype_ be ? Get(_C_, *"prototype"*). 1. NOTE: When _C_ is the intrinsic %Promise%, the above step cannot throw and always results in the intrinsic %Promise.prototype%. From 74c0260d88a2be01652c6084f45c3bb192bf43df Mon Sep 17 00:00:00 2001 From: Mathieu Hofman Date: Fri, 19 Sep 2025 03:50:09 +0000 Subject: [PATCH 8/8] revert Normative: resolve function adopts promises --- spec.html | 49 ++++++++----------------------------------------- 1 file changed, 8 insertions(+), 41 deletions(-) diff --git a/spec.html b/spec.html index bf86d8f0de..415f243f7a 100644 --- a/spec.html +++ b/spec.html @@ -3890,16 +3890,6 @@

Well-Known Intrinsic Objects

The Promise constructor () - - - %PromiseThenAction% - - - - - An internal function object for PerformPromiseThen - - %Proxy% @@ -48482,44 +48472,21 @@

Promise Resolve Functions

1. If _resolution_ is not an Object, then 1. Perform FulfillPromise(_promise_, _resolution_). 1. Return *undefined*. - 1. Let _thenAction_ be *null*. - 1. If IsPromise(_resolution_) is *true*, then - 1. Assert: _resolution_ is an ordinary object. - 1. Let _proto_ be ! _resolution_.[[GetPrototypeOf]](). - 1. If SameValue(_proto_, %Promise.prototype%) is *true*, set _thenAction_ to %PromiseThenAction%. - 1. If _thenAction_ is *null*, then - 1. Let _then_ be Completion(Get(_resolution_, *"then"*)). - 1. If _then_ is an abrupt completion, then - 1. Perform RejectPromise(_promise_, _then_.[[Value]]). - 1. Return *undefined*. - 1. Set _thenAction_ to _then_.[[Value]]. - 1. If IsCallable(_thenAction_) is *false*, then - 1. Perform FulfillPromise(_promise_, _resolution_). - 1. Return *undefined*. + 1. Let _then_ be Completion(Get(_resolution_, *"then"*)). + 1. If _then_ is an abrupt completion, then + 1. Perform RejectPromise(_promise_, _then_.[[Value]]). + 1. Return *undefined*. + 1. Let _thenAction_ be _then_.[[Value]]. + 1. If IsCallable(_thenAction_) is *false*, then + 1. Perform FulfillPromise(_promise_, _resolution_). + 1. Return *undefined*. 1. Let _thenJobCallback_ be HostMakeJobCallback(_thenAction_). - 1. NOTE: _thenAction_ may be %PromiseThenAction%, a value never directly accessible to ECMAScript code. 1. Let _job_ be NewPromiseResolveThenableJob(_promise_, _resolution_, _thenJobCallback_). 1. Perform HostEnqueuePromiseJob(_job_.[[Job]], _job_.[[Realm]]). 1. Return *undefined*.

The *"length"* property of a promise resolve function is *1*𝔽.

- - -

%PromiseThenAction% ( _onFulfilled_, _onRejected_ )

-

The %PromiseThenAction% intrinsic function:

-
    -
  • is an anonymous built-in function object that is defined once for each realm.
  • -
  • is never directly accessible to ECMAScript code.
  • -
  • is used by the promise resolve functions to adopt the state of the promise passed as the receiver.
  • -
  • performs the following steps when called:
  • -
- - 1. Let _promise_ be the *this* value. - 1. Assert: IsPromise(_promise_) is *true*. - 1. Return PerformPromiseThen(_promise_, _onFulfilled_, _onRejected_). - -