Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normative: Permit Symbol as WeakMap key and WeakSet entry #2038

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -5593,6 +5593,16 @@ <h1>IsStringPrefix ( _p_, _q_ )</h1>
</emu-note>
</emu-clause>

<emu-clause id="sec-hasidentity" aoid="HasIdentity">
<h1>HasIdentity ( _argument_ )</h1>
<p>The abstract operation HasIdentity takes argument _argument_ (an ECMAScript language value). It determines if _argument_ is considered to have a unique identity, enabling _argument_ to be a key of a WeakMap or entry in a WeakSet. This operation performs the following steps when called:</p>
<emu-alg>
1. If Type(_argument_) is Object, return *true*.
1. If Type(_argument_) is Symbol, return *true*.
1. Return *false*.
</emu-alg>
</emu-clause>

<emu-clause id="sec-samevalue" aoid="SameValue">
<h1>SameValue ( _x_, _y_ )</h1>
<p>The abstract operation SameValue takes arguments _x_ (an ECMAScript language value) and _y_ (an ECMAScript language value) and returns a completion record whose [[Type]] is ~normal~ and whose [[Value]] is a Boolean. It performs the following steps when called:</p>
Expand Down Expand Up @@ -36614,11 +36624,11 @@ <h1>Properties of Set Iterator Instances</h1>

<emu-clause id="sec-weakmap-objects">
<h1>WeakMap Objects</h1>
<p>WeakMap objects are collections of key/value pairs where the keys are objects and values may be arbitrary ECMAScript language values. A WeakMap may be queried to see if it contains a key/value pair with a specific key, but no mechanism is provided for enumerating the objects it holds as keys. If an object that is being used as the key of a WeakMap key/value pair is only reachable by following a chain of references that start within that WeakMap, then that key/value pair is inaccessible and is automatically removed from the WeakMap. WeakMap implementations must detect and remove such key/value pairs and any associated resources.</p>
<p>WeakMap objects are collections of key/value pairs where the keys are objects and/or symbols and values may be arbitrary ECMAScript language values. A WeakMap may be queried to see if it contains a key/value pair with a specific key, but no mechanism is provided for enumerating the keys. If a value that is being used as the key of a WeakMap key/value pair is only reachable by following a chain of references that start within that WeakMap, then that key/value pair is inaccessible and is automatically removed from the WeakMap. WeakMap implementations must detect and remove such key/value pairs and any associated resources.</p>
<p>An implementation may impose an arbitrarily determined latency between the time a key/value pair of a WeakMap becomes inaccessible and the time when the key/value pair is removed from the WeakMap. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to observe a key of a WeakMap that does not require the observer to present the observed key.</p>
<p>WeakMap objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of key/value pairs in the collection. The data structure used in this WeakMap objects specification are only intended to describe the required observable semantics of WeakMap objects. It is not intended to be a viable implementation model.</p>
<emu-note>
<p>WeakMap and WeakSets are intended to provide mechanisms for dynamically associating state with an object in a manner that does not &ldquo;leak&rdquo; memory resources if, in the absence of the WeakMap or WeakSet, the object otherwise became inaccessible and subject to resource reclamation by the implementation's garbage collection mechanisms. This characteristic can be achieved by using an inverted per-object mapping of weak map instances to keys. Alternatively each weak map may internally store its key to value mappings but this approach requires coordination between the WeakMap or WeakSet implementation and the garbage collector. The following references describe mechanism that may be useful to implementations of WeakMap and WeakSets:</p>
<p>WeakMap and WeakSets are intended to provide mechanisms for dynamically associating state with an object or symbol in a manner that does not &ldquo;leak&rdquo; memory resources if, in the absence of the WeakMap or WeakSet, the object or symbol otherwise became inaccessible and subject to resource reclamation by the implementation's garbage collection mechanisms. This characteristic can be achieved by using an inverted per-object/symbol mapping of weak map instances to keys. Alternatively, each WeakMap may internally store its key to value mappings, but this approach requires coordination between the WeakMap or WeakSet implementation and the garbage collector. The following references describe mechanism that may be useful to implementations of WeakMap and WeakSet:</p>
<p>Barry Hayes. 1997. Ephemerons: a new finalization mechanism. In <i>Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '97)</i>, A. Michael Berman (Ed.). ACM, New York, NY, USA, 176-183, <a href="http://doi.acm.org/10.1145/263698.263733">http://doi.acm.org/10.1145/263698.263733</a>.</p>
<p>Alexandra Barros, Roberto Ierusalimschy, Eliminating Cycles in Weak Tables. Journal of Universal Computer Science - J.UCS, vol. 14, no. 21, pp. 3481-3497, 2008, <a href="http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak">http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak</a></p>
</emu-note>
Expand Down Expand Up @@ -36688,7 +36698,7 @@ <h1>WeakMap.prototype.delete ( _key_ )</h1>
1. Let _M_ be the *this* value.
1. Perform ? RequireInternalSlot(_M_, [[WeakMapData]]).
1. Let _entries_ be the List that is _M_.[[WeakMapData]].
1. If Type(_key_) is not Object, return *false*.
1. If HasIdentity(_key_) is *false*, return *false*.
1. For each Record { [[Key]], [[Value]] } _p_ that is an element of _entries_, do
1. If _p_.[[Key]] is not ~empty~ and SameValue(_p_.[[Key]], _key_) is *true*, then
1. Set _p_.[[Key]] to ~empty~.
Expand All @@ -36708,7 +36718,7 @@ <h1>WeakMap.prototype.get ( _key_ )</h1>
1. Let _M_ be the *this* value.
1. Perform ? RequireInternalSlot(_M_, [[WeakMapData]]).
1. Let _entries_ be the List that is _M_.[[WeakMapData]].
1. If Type(_key_) is not Object, return *undefined*.
1. If HasIdentity(_key_) is *false*, return *undefined*.
1. For each Record { [[Key]], [[Value]] } _p_ that is an element of _entries_, do
1. If _p_.[[Key]] is not ~empty~ and SameValue(_p_.[[Key]], _key_) is *true*, return _p_.[[Value]].
1. Return *undefined*.
Expand All @@ -36722,7 +36732,7 @@ <h1>WeakMap.prototype.has ( _key_ )</h1>
1. Let _M_ be the *this* value.
1. Perform ? RequireInternalSlot(_M_, [[WeakMapData]]).
1. Let _entries_ be the List that is _M_.[[WeakMapData]].
1. If Type(_key_) is not Object, return *false*.
1. If HasIdentity(_key_) is *false*, return *false*.
1. For each Record { [[Key]], [[Value]] } _p_ that is an element of _entries_, do
1. If _p_.[[Key]] is not ~empty~ and SameValue(_p_.[[Key]], _key_) is *true*, return *true*.
1. Return *false*.
Expand All @@ -36736,7 +36746,7 @@ <h1>WeakMap.prototype.set ( _key_, _value_ )</h1>
1. Let _M_ be the *this* value.
1. Perform ? RequireInternalSlot(_M_, [[WeakMapData]]).
1. Let _entries_ be the List that is _M_.[[WeakMapData]].
1. If Type(_key_) is not Object, throw a *TypeError* exception.
1. If HasIdentity(_key_) is *false*, throw a *TypeError* exception.
1. For each Record { [[Key]], [[Value]] } _p_ that is an element of _entries_, do
1. If _p_.[[Key]] is not ~empty~ and SameValue(_p_.[[Key]], _key_) is *true*, then
1. Set _p_.[[Value]] to _value_.
Expand All @@ -36762,8 +36772,8 @@ <h1>Properties of WeakMap Instances</h1>

<emu-clause id="sec-weakset-objects">
<h1>WeakSet Objects</h1>
<p>WeakSet objects are collections of objects. A distinct object may only occur once as an element of a WeakSet's collection. A WeakSet may be queried to see if it contains a specific object, but no mechanism is provided for enumerating the objects it holds. If an object that is contained by a WeakSet is only reachable by following a chain of references that start within that WeakSet, then that object is inaccessible and is automatically removed from the WeakSet. WeakSet implementations must detect and remove such objects and any associated resources.</p>
<p>An implementation may impose an arbitrarily determined latency between the time an object contained in a WeakSet becomes inaccessible and the time when the object is removed from the WeakSet. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to determine if a WeakSet contains a particular object that does not require the observer to present the observed object.</p>
<p>WeakSet objects are collections of objects and/or symbols. A distinct value may only occur once as an element of a WeakSet's collection. A WeakSet may be queried to see if it contains a specific value, but no mechanism is provided for enumerating its values. If a value that is contained by a WeakSet is only reachable by following a chain of references that start within that WeakSet, then that value is inaccessible and is automatically removed from the WeakSet. WeakSet implementations must detect and remove such values and any associated resources.</p>
<p>An implementation may impose an arbitrarily determined latency between the time a value contained in a WeakSet becomes inaccessible and the time when the value is removed from the WeakSet. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to determine if a WeakSet contains a particular value that does not require the observer to present the observed value.</p>
<p>WeakSet objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this WeakSet objects specification is only intended to describe the required observable semantics of WeakSet objects. It is not intended to be a viable implementation model.</p>
<emu-note>
<p>See the NOTE in <emu-xref href="#sec-weakmap-objects"></emu-xref>.</p>
Expand Down Expand Up @@ -36832,7 +36842,7 @@ <h1>WeakSet.prototype.add ( _value_ )</h1>
<emu-alg>
1. Let _S_ be the *this* value.
1. Perform ? RequireInternalSlot(_S_, [[WeakSetData]]).
1. If Type(_value_) is not Object, throw a *TypeError* exception.
1. If HasIdentity(_value_) is *false*, throw a *TypeError* exception.
1. Let _entries_ be the List that is _S_.[[WeakSetData]].
1. For each _e_ that is an element of _entries_, do
1. If _e_ is not ~empty~ and SameValue(_e_, _value_) is *true*, then
Expand All @@ -36853,7 +36863,7 @@ <h1>WeakSet.prototype.delete ( _value_ )</h1>
<emu-alg>
1. Let _S_ be the *this* value.
1. Perform ? RequireInternalSlot(_S_, [[WeakSetData]]).
1. If Type(_value_) is not Object, return *false*.
1. If HasIdentity(_value_) is *false*, return *false*.
1. Let _entries_ be the List that is _S_.[[WeakSetData]].
1. For each _e_ that is an element of _entries_, do
1. If _e_ is not ~empty~ and SameValue(_e_, _value_) is *true*, then
Expand All @@ -36873,7 +36883,7 @@ <h1>WeakSet.prototype.has ( _value_ )</h1>
1. Let _S_ be the *this* value.
1. Perform ? RequireInternalSlot(_S_, [[WeakSetData]]).
1. Let _entries_ be the List that is _S_.[[WeakSetData]].
1. If Type(_value_) is not Object, return *false*.
1. If HasIdentity(_value_) is *false*, return *false*.
1. For each _e_ that is an element of _entries_, do
1. If _e_ is not ~empty~ and SameValue(_e_, _value_) is *true*, return *true*.
1. Return *false*.
Expand Down