From 509e889c64207540fc579ce580bcd6cf4f04f4b6 Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Thu, 2 Oct 2025 16:13:38 -0400 Subject: [PATCH 01/10] Allow implementation-defined choice of property or accessor --- spec.emu | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec.emu b/spec.emu index b15c600..6f54354 100644 --- a/spec.emu +++ b/spec.emu @@ -34,7 +34,13 @@ markEffects: true 1. NOTE: This can be used to hide implementation details on the stack trace that aren't useful to user. 1. Else, 1. Let _string_ be an implementation-defined string that represents the current stack trace. - 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_). + 1. Perform an implementation-defined choice of either: + 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_).. + 1. Or: + 1. If ? IsExtensible( _error_ ) is *false*, throw a *TypeError* exception. + 1. Let _name_ be an implementation-defined name. + 1. ! PrivateFieldAdd( _error_, _name_, _string_). + 1. Perform ! OrdinaryDefineOwnProperty(_error_, *"stack"*, PropertyDescriptor { [[Get]]: ? PrivateGet( _error_, _name_ ), [[Set]]: ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_)., [[Enumerable]]: true, [[Configurable]]: true }). 1. Return *undefined*. From f349e12b917bf20a75225a8a51e44d1c5eb2b0f4 Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Fri, 3 Oct 2025 12:10:47 -0400 Subject: [PATCH 02/10] Make non-enumerable --- spec.emu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.emu b/spec.emu index 6f54354..06a08b3 100644 --- a/spec.emu +++ b/spec.emu @@ -40,7 +40,7 @@ markEffects: true 1. If ? IsExtensible( _error_ ) is *false*, throw a *TypeError* exception. 1. Let _name_ be an implementation-defined name. 1. ! PrivateFieldAdd( _error_, _name_, _string_). - 1. Perform ! OrdinaryDefineOwnProperty(_error_, *"stack"*, PropertyDescriptor { [[Get]]: ? PrivateGet( _error_, _name_ ), [[Set]]: ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_)., [[Enumerable]]: true, [[Configurable]]: true }). + 1. Perform ! OrdinaryDefineOwnProperty(_error_, *"stack"*, PropertyDescriptor { [[Get]]: ? PrivateGet( _error_, _name_ ), [[Set]]: ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_)., [[Enumerable]]: false, [[Configurable]]: true }). 1. Return *undefined*. From a83ae6359293802238fe467d72c7fd114397f3db Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Tue, 7 Oct 2025 13:25:18 -0400 Subject: [PATCH 03/10] Use field in Agent Record to control data/accessor behaviour --- spec.emu | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/spec.emu b/spec.emu index 06a08b3..fa384f1 100644 --- a/spec.emu +++ b/spec.emu @@ -15,6 +15,35 @@ markEffects: true

+ +

Agents

+ + + + + + + + + + + + + + + +
Field NameValueMeaning
[[UseErrorCaptureStackTraceDataProperty]]a BooleanWhether to use a data property or an accessor property for the "stack" property installed by Error.captureStackTrace.
+
+ +

Once the values of [[Signifier]], [[IsLockFree1]], [[IsLockFree2]], and [[UseErrorCaptureStackTraceDataProperty]] have been observed by any agent in the agent cluster they cannot change.

+
+ + +

Agent Clusters

+ +

All agents within a cluster must have the same value for the [[UseErrorCaptureStackTraceDataProperty]] field in their respective Agent Records.

+
+

Fundamental Objects

@@ -34,9 +63,10 @@ markEffects: true 1. NOTE: This can be used to hide implementation details on the stack trace that aren't useful to user. 1. Else, 1. Let _string_ be an implementation-defined string that represents the current stack trace. - 1. Perform an implementation-defined choice of either: + 1. Let _useErrorCaptureStackTraceDataProperty_ be the value of the [[UseErrorCaptureStackTraceDataProperty]] field of the surrounding agent's Agent Record. + 1. If _useErrorCaptureStackTraceDataProperty_ is *true*, then 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_).. - 1. Or: + 1. Else, 1. If ? IsExtensible( _error_ ) is *false*, throw a *TypeError* exception. 1. Let _name_ be an implementation-defined name. 1. ! PrivateFieldAdd( _error_, _name_, _string_). From 950072ce2dcb026916f57dc9608c803ae9f9018e Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Tue, 7 Oct 2025 13:54:38 -0400 Subject: [PATCH 04/10] Use closures for getter and setter --- spec.emu | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec.emu b/spec.emu index fa384f1..bba6841 100644 --- a/spec.emu +++ b/spec.emu @@ -68,9 +68,13 @@ markEffects: true 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_).. 1. Else, 1. If ? IsExtensible( _error_ ) is *false*, throw a *TypeError* exception. - 1. Let _name_ be an implementation-defined name. - 1. ! PrivateFieldAdd( _error_, _name_, _string_). - 1. Perform ! OrdinaryDefineOwnProperty(_error_, *"stack"*, PropertyDescriptor { [[Get]]: ? PrivateGet( _error_, _name_ ), [[Set]]: ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_)., [[Enumerable]]: false, [[Configurable]]: true }). + 1. Let getterClosure be a new Abstract Closure with no parameters that captures _string_ and performs the following steps when called: + 1. Return NormalCompletion(_string_). + 1. Let getter be CreateBuiltinFunction(getterClosure, 0, "", « »). + 1. Let setterClosure be a new Abstract Closure with parameters (_value_) that captures _error_ and performs the following steps when called: + 1. Perform ! SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _value_). + 1. Let setter be CreateBuiltinFunction(setterClosure, 1, "", « »). + 1. Perform ! OrdinaryDefineOwnProperty(_error_, *"stack"*, PropertyDescriptor { [[Get]]: getter, [[Set]]: setter, [[Enumerable]]: false, [[Configurable]]: true }). 1. Return *undefined*.
From 2ec1e8994e26e40765476f4fed4de8f07d6dc22e Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Tue, 7 Oct 2025 16:33:16 -0400 Subject: [PATCH 05/10] Apply review suggestions --- spec.emu | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/spec.emu b/spec.emu index bba6841..51ac882 100644 --- a/spec.emu +++ b/spec.emu @@ -28,8 +28,8 @@ markEffects: true - [[UseErrorCaptureStackTraceDataProperty]] - a Boolean + [[ErrorCaptureStackTraceStrategy]] + DATAPROPERTY or ACCESSOR Whether to use a data property or an accessor property for the "stack" property installed by Error.captureStackTrace. @@ -63,18 +63,20 @@ markEffects: true 1. NOTE: This can be used to hide implementation details on the stack trace that aren't useful to user. 1. Else, 1. Let _string_ be an implementation-defined string that represents the current stack trace. - 1. Let _useErrorCaptureStackTraceDataProperty_ be the value of the [[UseErrorCaptureStackTraceDataProperty]] field of the surrounding agent's Agent Record. - 1. If _useErrorCaptureStackTraceDataProperty_ is *true*, then + 1. Let _strategy_ be the value of the [[ErrorCaptureStackTraceStrategy]] field of the surrounding agent's Agent Record. + 1. If _strategy_ is DATAPROPERTY, then 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_).. 1. Else, - 1. If ? IsExtensible( _error_ ) is *false*, throw a *TypeError* exception. - 1. Let getterClosure be a new Abstract Closure with no parameters that captures _string_ and performs the following steps when called: + 1. Assert: _strategy_ is ACCESSOR. + 1. If ? IsExtensible(_error_) is *false*, throw a *TypeError* exception. + 1. Let _getterClosure_ be a new Abstract Closure with no parameters that captures _string_ and performs the following steps when called: 1. Return NormalCompletion(_string_). - 1. Let getter be CreateBuiltinFunction(getterClosure, 0, "", « »). - 1. Let setterClosure be a new Abstract Closure with parameters (_value_) that captures _error_ and performs the following steps when called: - 1. Perform ! SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _value_). - 1. Let setter be CreateBuiltinFunction(setterClosure, 1, "", « »). - 1. Perform ! OrdinaryDefineOwnProperty(_error_, *"stack"*, PropertyDescriptor { [[Get]]: getter, [[Set]]: setter, [[Enumerable]]: false, [[Configurable]]: true }). + 1. Let _getter_ be CreateBuiltinFunction(_getterClosure_, 0, "", « »). + 1. Let _setterClosure_ be a new Abstract Closure with parameters (_value_) that captures _error_ and performs the following steps when called: + 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, *null*, *"stack"*, _value_). + 1. Return NormalCompletion(*undefined*). + 1. Let _setter_ be CreateBuiltinFunction(_setterClosure_, 1, "", « »). + 1. Perform ! OrdinaryDefineOwnProperty(_error_, *"stack"*, PropertyDescriptor { [[Get]]: _getter_, [[Set]]: _setter_, [[Enumerable]]: false, [[Configurable]]: true }). 1. Return *undefined*. From 8deb622760fec4cc6e67c80efb9df39cebe330d2 Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Wed, 8 Oct 2025 09:24:56 -0400 Subject: [PATCH 06/10] Apply further review fixes --- spec.emu | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec.emu b/spec.emu index 51ac882..37b19f0 100644 --- a/spec.emu +++ b/spec.emu @@ -29,19 +29,19 @@ markEffects: true [[ErrorCaptureStackTraceStrategy]] - DATAPROPERTY or ACCESSOR + ~data-property~ or ~accessor~ Whether to use a data property or an accessor property for the "stack" property installed by Error.captureStackTrace. -

Once the values of [[Signifier]], [[IsLockFree1]], [[IsLockFree2]], and [[UseErrorCaptureStackTraceDataProperty]] have been observed by any agent in the agent cluster they cannot change.

+

Once the values of [[Signifier]], [[IsLockFree1]], [[IsLockFree2]], and [[ErrorCaptureStackTraceStrategy]] have been observed by any agent in the agent cluster they cannot change.

Agent Clusters

-

All agents within a cluster must have the same value for the [[UseErrorCaptureStackTraceDataProperty]] field in their respective Agent Records.

+

All agents within a cluster must have the same value for the [[ErrorCaptureStackTraceStrategy]] field in their respective Agent Records.

@@ -64,10 +64,10 @@ markEffects: true 1. Else, 1. Let _string_ be an implementation-defined string that represents the current stack trace. 1. Let _strategy_ be the value of the [[ErrorCaptureStackTraceStrategy]] field of the surrounding agent's Agent Record. - 1. If _strategy_ is DATAPROPERTY, then + 1. If _strategy_ is ~data-property~, then 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_).. 1. Else, - 1. Assert: _strategy_ is ACCESSOR. + 1. Assert: _strategy_ is ~accessor~. 1. If ? IsExtensible(_error_) is *false*, throw a *TypeError* exception. 1. Let _getterClosure_ be a new Abstract Closure with no parameters that captures _string_ and performs the following steps when called: 1. Return NormalCompletion(_string_). From afc3b832dfc17fe6f040c5520e25462bebaa6fb3 Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Thu, 9 Oct 2025 10:58:34 -0400 Subject: [PATCH 07/10] Apply suggestions from TG3 discussion --- spec.emu | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/spec.emu b/spec.emu index 37b19f0..a78155c 100644 --- a/spec.emu +++ b/spec.emu @@ -15,16 +15,21 @@ markEffects: true

- -

Agents

- - + +

Realms

+ - - - + + + @@ -34,14 +39,6 @@ markEffects: true
Field NameValueMeaning + Field Name + + Value + + Meaning +
- -

Once the values of [[Signifier]], [[IsLockFree1]], [[IsLockFree2]], and [[ErrorCaptureStackTraceStrategy]] have been observed by any agent in the agent cluster they cannot change.

-
- - -

Agent Clusters

- -

All agents within a cluster must have the same value for the [[ErrorCaptureStackTraceStrategy]] field in their respective Agent Records.

@@ -54,29 +51,28 @@ markEffects: true

Properties of the Error Constructor

-

Error.captureStackTrace ( _error_ [ , _constructor_ ] )

+

Error.captureStackTrace ( _O_ [ , _limit_ ] )

- 1. If _error_ is not an Object, throw a *TypeError* exception. - 1. If IsCallable(_constructor_) is *true*, then + 1. If _O_ is not an Object, throw a *TypeError* exception. + 1. If IsCallable(_limit_) is *true*, then 1. Let _string_ be an implementation-defined string that represents the current stack trace, with all stack - frames above the topmost call to _constructor_, including that call, omitted from the stack trace. + frames above the topmost call to _limit_, including that call, omitted from the stack trace. 1. NOTE: This can be used to hide implementation details on the stack trace that aren't useful to user. 1. Else, 1. Let _string_ be an implementation-defined string that represents the current stack trace. - 1. Let _strategy_ be the value of the [[ErrorCaptureStackTraceStrategy]] field of the surrounding agent's Agent Record. + 1. Let _strategy_ be the value of the [[ErrorCaptureStackTraceStrategy]] field of the current Realm Record. 1. If _strategy_ is ~data-property~, then - 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, OrdinaryObjectCreate(*null*), *"stack"*, _string_).. + 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Value]]: _string_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). 1. Else, 1. Assert: _strategy_ is ~accessor~. - 1. If ? IsExtensible(_error_) is *false*, throw a *TypeError* exception. 1. Let _getterClosure_ be a new Abstract Closure with no parameters that captures _string_ and performs the following steps when called: 1. Return NormalCompletion(_string_). 1. Let _getter_ be CreateBuiltinFunction(_getterClosure_, 0, "", « »). - 1. Let _setterClosure_ be a new Abstract Closure with parameters (_value_) that captures _error_ and performs the following steps when called: - 1. Perform ? SetterThatIgnoresPrototypeProperties(_error_, *null*, *"stack"*, _value_). + 1. Let _setterClosure_ be a new Abstract Closure with parameters (_value_) that captures _O_ and performs the following steps when called: + 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Value]]: _value_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). 1. Return NormalCompletion(*undefined*). 1. Let _setter_ be CreateBuiltinFunction(_setterClosure_, 1, "", « »). - 1. Perform ! OrdinaryDefineOwnProperty(_error_, *"stack"*, PropertyDescriptor { [[Get]]: _getter_, [[Set]]: _setter_, [[Enumerable]]: false, [[Configurable]]: true }). + 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Get]]: _getter_, [[Set]]: _setter_, [[Enumerable]]: false, [[Configurable]]: true }). 1. Return *undefined*.
From aab3b0593b3185ffa4592af41c9afe4280b51826 Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Wed, 15 Oct 2025 12:24:41 -0400 Subject: [PATCH 08/10] Fixup realm access Co-authored-by: Michael Ficarra --- spec.emu | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec.emu b/spec.emu index a78155c..e603cc6 100644 --- a/spec.emu +++ b/spec.emu @@ -60,7 +60,8 @@ markEffects: true 1. NOTE: This can be used to hide implementation details on the stack trace that aren't useful to user. 1. Else, 1. Let _string_ be an implementation-defined string that represents the current stack trace. - 1. Let _strategy_ be the value of the [[ErrorCaptureStackTraceStrategy]] field of the current Realm Record. + 1. Let _realm_ be the current Realm Record. + 1. Let _strategy_ be _realm_.[[ErrorCaptureStackTraceStrategy]]. 1. If _strategy_ is ~data-property~, then 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Value]]: _string_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). 1. Else, From 9bbfb599afb89f469b899fbb393b051d87fe6ab8 Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Mon, 20 Oct 2025 12:05:20 -0400 Subject: [PATCH 09/10] Use private symbol to store stack trace --- spec.emu | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec.emu b/spec.emu index e603cc6..62cdc25 100644 --- a/spec.emu +++ b/spec.emu @@ -66,13 +66,13 @@ markEffects: true 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Value]]: _string_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). 1. Else, 1. Assert: _strategy_ is ~accessor~. - 1. Let _getterClosure_ be a new Abstract Closure with no parameters that captures _string_ and performs the following steps when called: - 1. Return NormalCompletion(_string_). - 1. Let _getter_ be CreateBuiltinFunction(_getterClosure_, 0, "", « »). - 1. Let _setterClosure_ be a new Abstract Closure with parameters (_value_) that captures _O_ and performs the following steps when called: - 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Value]]: _value_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). + 1. Let _captureStackSymbol_ be an implementation-defined Symbol value. + 1. Perform ? DefinePropertyOrThrow(_O_, _captureStackSymbol_, PropertyDescriptor { [[Value]]: _string_, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }). + 1. Let _getter_ be a built-in function that takes no arguments and performs the following steps when called: + 1. Return ? Get(*this* value, _captureStackSymbol_). + 1. Let _setter_ be a built-in function that takes an argument _value_ and performs the following steps when called: + 1. Perform ? DefinePropertyOrThrow(*this* value, *"stack"*, PropertyDescriptor { [[Value]]: _value_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). 1. Return NormalCompletion(*undefined*). - 1. Let _setter_ be CreateBuiltinFunction(_setterClosure_, 1, "", « »). 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Get]]: _getter_, [[Set]]: _setter_, [[Enumerable]]: false, [[Configurable]]: true }). 1. Return *undefined*. From eed5e497bbb750281afffb5305a49361ebcf0216 Mon Sep 17 00:00:00 2001 From: Daniel Minor Date: Tue, 21 Oct 2025 12:15:53 -0400 Subject: [PATCH 10/10] Revert "Use private symbol to store stack trace" This reverts commit 9bbfb599afb89f469b899fbb393b051d87fe6ab8. --- spec.emu | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec.emu b/spec.emu index 62cdc25..e603cc6 100644 --- a/spec.emu +++ b/spec.emu @@ -66,13 +66,13 @@ markEffects: true 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Value]]: _string_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). 1. Else, 1. Assert: _strategy_ is ~accessor~. - 1. Let _captureStackSymbol_ be an implementation-defined Symbol value. - 1. Perform ? DefinePropertyOrThrow(_O_, _captureStackSymbol_, PropertyDescriptor { [[Value]]: _string_, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }). - 1. Let _getter_ be a built-in function that takes no arguments and performs the following steps when called: - 1. Return ? Get(*this* value, _captureStackSymbol_). - 1. Let _setter_ be a built-in function that takes an argument _value_ and performs the following steps when called: - 1. Perform ? DefinePropertyOrThrow(*this* value, *"stack"*, PropertyDescriptor { [[Value]]: _value_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). + 1. Let _getterClosure_ be a new Abstract Closure with no parameters that captures _string_ and performs the following steps when called: + 1. Return NormalCompletion(_string_). + 1. Let _getter_ be CreateBuiltinFunction(_getterClosure_, 0, "", « »). + 1. Let _setterClosure_ be a new Abstract Closure with parameters (_value_) that captures _O_ and performs the following steps when called: + 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Value]]: _value_, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }). 1. Return NormalCompletion(*undefined*). + 1. Let _setter_ be CreateBuiltinFunction(_setterClosure_, 1, "", « »). 1. Perform ? DefinePropertyOrThrow(_O_, *"stack"*, PropertyDescriptor { [[Get]]: _getter_, [[Set]]: _setter_, [[Enumerable]]: false, [[Configurable]]: true }). 1. Return *undefined*.