@@ -42020,6 +42020,152 @@ <h1>Set Objects</h1>
42020
42020
<p>Set objects are collections of ECMAScript language values. A distinct value may only occur once as an element of a Set's collection. Distinct values are discriminated using the SameValueZero comparison algorithm.</p>
42021
42021
<p>Set 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 specification is only intended to describe the required observable semantics of Set objects. It is not intended to be a viable implementation model.</p>
42022
42022
42023
+ <emu-clause id="sec-abstract-operations-for-set-objects">
42024
+ <h1>Abstract Operations For Set Objects</h1>
42025
+
42026
+ <emu-clause id="sec-set-records">
42027
+ <h1>Set Records</h1>
42028
+ <p>An <dfn variants="Set Records">Set Record</dfn> is a Record value used to encapsulate the interface of a Set or similar object.</p>
42029
+ <p>Set Records have the fields listed in <emu-xref href="#table-set-record-fields"></emu-xref>.</p>
42030
+ <emu-table id="table-set-record-fields" caption="Set Record Fields">
42031
+ <table>
42032
+ <tr>
42033
+ <th>
42034
+ Field Name
42035
+ </th>
42036
+ <th>
42037
+ Value
42038
+ </th>
42039
+ <th>
42040
+ Meaning
42041
+ </th>
42042
+ </tr>
42043
+ <tr>
42044
+ <td>
42045
+ [[SetObject]]
42046
+ </td>
42047
+ <td>
42048
+ an Object
42049
+ </td>
42050
+ <td>
42051
+ the Set or similar object.
42052
+ </td>
42053
+ </tr>
42054
+ <tr>
42055
+ <td>
42056
+ [[Size]]
42057
+ </td>
42058
+ <td>
42059
+ a non-negative integer or +∞
42060
+ </td>
42061
+ <td>
42062
+ The reported size of the object.
42063
+ </td>
42064
+ </tr>
42065
+ <tr>
42066
+ <td>
42067
+ [[Has]]
42068
+ </td>
42069
+ <td>
42070
+ a function object
42071
+ </td>
42072
+ <td>
42073
+ The `has` method of the object.
42074
+ </td>
42075
+ </tr>
42076
+ <tr>
42077
+ <td>
42078
+ [[Keys]]
42079
+ </td>
42080
+ <td>
42081
+ a function object
42082
+ </td>
42083
+ <td>
42084
+ The `keys` method of the object.
42085
+ </td>
42086
+ </tr>
42087
+ </table>
42088
+ </emu-table>
42089
+ </emu-clause>
42090
+
42091
+ <emu-clause id="sec-getsetrecord" type="abstract operation">
42092
+ <h1>
42093
+ GetSetRecord (
42094
+ _obj_: an ECMAScript language value,
42095
+ ): either a normal completion containing a Set Record or a throw completion
42096
+ </h1>
42097
+ <dl class="header">
42098
+ </dl>
42099
+ <emu-alg>
42100
+ 1. If _obj_ is not an Object, throw a *TypeError* exception.
42101
+ 1. Let _rawSize_ be ? Get(_obj_, *"size"*).
42102
+ 1. Let _numSize_ be ? ToNumber(_rawSize_).
42103
+ 1. NOTE: If _rawSize_ is *undefined*, then _numSize_ will be *NaN*.
42104
+ 1. If _numSize_ is *NaN*, throw a *TypeError* exception.
42105
+ 1. Let _intSize_ be ! ToIntegerOrInfinity(_numSize_).
42106
+ 1. If _intSize_ < 0, throw a *RangeError* exception.
42107
+ 1. Let _has_ be ? Get(_obj_, *"has"*).
42108
+ 1. If IsCallable(_has_) is *false*, throw a *TypeError* exception.
42109
+ 1. Let _keys_ be ? Get(_obj_, *"keys"*).
42110
+ 1. If IsCallable(_keys_) is *false*, throw a *TypeError* exception.
42111
+ 1. Return a new Set Record { [[SetObject]]: _obj_, [[Size]]: _intSize_, [[Has]]: _has_, [[Keys]]: _keys_ }.
42112
+ </emu-alg>
42113
+ </emu-clause>
42114
+
42115
+ <emu-clause id="sec-setdatahas" type="abstract operation">
42116
+ <h1>
42117
+ SetDataHas (
42118
+ _setData_: a List of either ECMAScript language values or ~empty~,
42119
+ _value_: an ECMAScript language value,
42120
+ ): a Boolean
42121
+ </h1>
42122
+ <dl class="header">
42123
+ </dl>
42124
+ <emu-alg>
42125
+ 1. If SetDataIndex(_setData_, _value_) is ~not-found~, return *false*.
42126
+ 1. Return *true*.
42127
+ </emu-alg>
42128
+ </emu-clause>
42129
+
42130
+ <emu-clause id="sec-setdataindex" type="abstract operation">
42131
+ <h1>
42132
+ SetDataIndex (
42133
+ _setData_: a List of either ECMAScript language values or ~empty~,
42134
+ _value_: an ECMAScript language value,
42135
+ ): a non-negative integer or ~not-found~
42136
+ </h1>
42137
+ <dl class="header">
42138
+ </dl>
42139
+ <emu-alg>
42140
+ 1. Set _value_ to CanonicalizeKeyedCollectionKey(_value_).
42141
+ 1. Let _size_ be the number of elements in _setData_.
42142
+ 1. Let _index_ be 0.
42143
+ 1. Repeat, while _index_ < _size_,
42144
+ 1. Let _e_ be _setData_[_index_].
42145
+ 1. If _e_ is not ~empty~ and _e_ is _value_, then
42146
+ 1. Return _index_.
42147
+ 1. Set _index_ to _index_ + 1.
42148
+ 1. Return ~not-found~.
42149
+ </emu-alg>
42150
+ </emu-clause>
42151
+
42152
+ <emu-clause id="sec-setdatasize" type="abstract operation">
42153
+ <h1>
42154
+ SetDataSize (
42155
+ _setData_: a List of either ECMAScript language values or ~empty~,
42156
+ ): a non-negative integer
42157
+ </h1>
42158
+ <dl class="header">
42159
+ </dl>
42160
+ <emu-alg>
42161
+ 1. Let _count_ be 0.
42162
+ 1. For each element _e_ of _setData_, do
42163
+ 1. If _e_ is not ~empty~, set _count_ to _count_ + 1.
42164
+ 1. Return _count_.
42165
+ </emu-alg>
42166
+ </emu-clause>
42167
+ </emu-clause>
42168
+
42023
42169
<emu-clause id="sec-set-constructor">
42024
42170
<h1>The Set Constructor</h1>
42025
42171
<p>The Set constructor:</p>
@@ -42141,6 +42287,40 @@ <h1>Set.prototype.delete ( _value_ )</h1>
42141
42287
</emu-note>
42142
42288
</emu-clause>
42143
42289
42290
+ <emu-clause id="sec-set.prototype.difference">
42291
+ <h1>Set.prototype.difference ( _other_ )</h1>
42292
+ <p>This method performs the following steps when called:</p>
42293
+ <emu-alg>
42294
+ 1. Let _O_ be the *this* value.
42295
+ 1. Perform ? RequireInternalSlot(_O_, [[SetData]]).
42296
+ 1. Let _otherRec_ be ? GetSetRecord(_other_).
42297
+ 1. Let _resultSetData_ be a copy of _O_.[[SetData]].
42298
+ 1. If SetDataSize(_O_.[[SetData]]) ≤ _otherRec_.[[Size]], then
42299
+ 1. Let _thisSize_ be the number of elements in _O_.[[SetData]].
42300
+ 1. Let _index_ be 0.
42301
+ 1. Repeat, while _index_ < _thisSize_,
42302
+ 1. Let _e_ be _resultSetData_[_index_].
42303
+ 1. If _e_ is not ~empty~, then
42304
+ 1. Let _inOther_ be ToBoolean(? Call(_otherRec_.[[Has]], _otherRec_.[[SetObject]], « _e_ »)).
42305
+ 1. If _inOther_ is *true*, then
42306
+ 1. Set _resultSetData_[_index_] to ~empty~.
42307
+ 1. Set _index_ to _index_ + 1.
42308
+ 1. Else,
42309
+ 1. Let _keysIter_ be ? GetIteratorFromMethod(_otherRec_.[[SetObject]], _otherRec_.[[Keys]]).
42310
+ 1. Let _next_ be ~not-started~.
42311
+ 1. Repeat, while _next_ is not ~done~,
42312
+ 1. Set _next_ to ? IteratorStepValue(_keysIter_).
42313
+ 1. If _next_ is not ~done~, then
42314
+ 1. Set _next_ to CanonicalizeKeyedCollectionKey(_next_).
42315
+ 1. Let _valueIndex_ be SetDataIndex(_resultSetData_, _next_).
42316
+ 1. If _valueIndex_ is not ~not-found~, then
42317
+ 1. Set _resultSetData_[_valueIndex_] to ~empty~.
42318
+ 1. Let _result_ be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
42319
+ 1. Set _result_.[[SetData]] to _resultSetData_.
42320
+ 1. Return _result_.
42321
+ </emu-alg>
42322
+ </emu-clause>
42323
+
42144
42324
<emu-clause id="sec-set.prototype.entries">
42145
42325
<h1>Set.prototype.entries ( )</h1>
42146
42326
<p>This method performs the following steps when called:</p>
@@ -42195,6 +42375,119 @@ <h1>Set.prototype.has ( _value_ )</h1>
42195
42375
</emu-alg>
42196
42376
</emu-clause>
42197
42377
42378
+ <emu-clause id="sec-set.prototype.intersection">
42379
+ <h1>Set.prototype.intersection ( _other_ )</h1>
42380
+ <p>This method performs the following steps when called:</p>
42381
+ <emu-alg>
42382
+ 1. Let _O_ be the *this* value.
42383
+ 1. Perform ? RequireInternalSlot(_O_, [[SetData]]).
42384
+ 1. Let _otherRec_ be ? GetSetRecord(_other_).
42385
+ 1. Let _resultSetData_ be a new empty List.
42386
+ 1. If SetDataSize(_O_.[[SetData]]) ≤ _otherRec_.[[Size]], then
42387
+ 1. Let _thisSize_ be the number of elements in _O_.[[SetData]].
42388
+ 1. Let _index_ be 0.
42389
+ 1. Repeat, while _index_ < _thisSize_,
42390
+ 1. Let _e_ be _O_.[[SetData]][_index_].
42391
+ 1. Set _index_ to _index_ + 1.
42392
+ 1. If _e_ is not ~empty~, then
42393
+ 1. Let _inOther_ be ToBoolean(? Call(_otherRec_.[[Has]], _otherRec_.[[SetObject]], « _e_ »)).
42394
+ 1. If _inOther_ is *true*, then
42395
+ 1. NOTE: It is possible for earlier calls to _otherRec_.[[Has]] to remove and re-add an element of _O_.[[SetData]], which can cause the same element to be visited twice during this iteration.
42396
+ 1. If SetDataHas(_resultSetData_, _e_) is *false*, then
42397
+ 1. Append _e_ to _resultSetData_.
42398
+ 1. NOTE: The number of elements in _O_.[[SetData]] may have increased during execution of _otherRec_.[[Has]].
42399
+ 1. Set _thisSize_ to the number of elements in _O_.[[SetData]].
42400
+ 1. Else,
42401
+ 1. Let _keysIter_ be ? GetIteratorFromMethod(_otherRec_.[[SetObject]], _otherRec_.[[Keys]]).
42402
+ 1. Let _next_ be ~not-started~.
42403
+ 1. Repeat, while _next_ is not ~done~,
42404
+ 1. Set _next_ to ? IteratorStepValue(_keysIter_).
42405
+ 1. If _next_ is not ~done~, then
42406
+ 1. Set _next_ to CanonicalizeKeyedCollectionKey(_next_).
42407
+ 1. Let _inThis_ be SetDataHas(_O_.[[SetData]], _next_).
42408
+ 1. If _inThis_ is *true*, then
42409
+ 1. NOTE: Because _other_ is an arbitrary object, it is possible for its *"keys"* iterator to produce the same value more than once.
42410
+ 1. If SetDataHas(_resultSetData_, _next_) is *false*, then
42411
+ 1. Append _next_ to _resultSetData_.
42412
+ 1. Let _result_ be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
42413
+ 1. Set _result_.[[SetData]] to _resultSetData_.
42414
+ 1. Return _result_.
42415
+ </emu-alg>
42416
+ </emu-clause>
42417
+
42418
+ <emu-clause id="sec-set.prototype.isdisjointfrom">
42419
+ <h1>Set.prototype.isDisjointFrom ( _other_ )</h1>
42420
+ <p>This method performs the following steps when called:</p>
42421
+ <emu-alg>
42422
+ 1. Let _O_ be the *this* value.
42423
+ 1. Perform ? RequireInternalSlot(_O_, [[SetData]]).
42424
+ 1. Let _otherRec_ be ? GetSetRecord(_other_).
42425
+ 1. If SetDataSize(_O_.[[SetData]]) ≤ _otherRec_.[[Size]], then
42426
+ 1. Let _thisSize_ be the number of elements in _O_.[[SetData]].
42427
+ 1. Let _index_ be 0.
42428
+ 1. Repeat, while _index_ < _thisSize_,
42429
+ 1. Let _e_ be _O_.[[SetData]][_index_].
42430
+ 1. Set _index_ to _index_ + 1.
42431
+ 1. If _e_ is not ~empty~, then
42432
+ 1. Let _inOther_ be ToBoolean(? Call(_otherRec_.[[Has]], _otherRec_.[[SetObject]], « _e_ »)).
42433
+ 1. If _inOther_ is *true*, return *false*.
42434
+ 1. NOTE: The number of elements in _O_.[[SetData]] may have increased during execution of _otherRec_.[[Has]].
42435
+ 1. Set _thisSize_ to the number of elements in _O_.[[SetData]].
42436
+ 1. Else,
42437
+ 1. Let _keysIter_ be ? GetIteratorFromMethod(_otherRec_.[[SetObject]], _otherRec_.[[Keys]]).
42438
+ 1. Let _next_ be ~not-started~.
42439
+ 1. Repeat, while _next_ is not ~done~,
42440
+ 1. Set _next_ to ? IteratorStepValue(_keysIter_).
42441
+ 1. If _next_ is not ~done~, then
42442
+ 1. If SetDataHas(_O_.[[SetData]], _next_) is *true*, then
42443
+ 1. Perform ? IteratorClose(_keysIter_, NormalCompletion(~unused~)).
42444
+ 1. Return *false*.
42445
+ 1. Return *true*.
42446
+ </emu-alg>
42447
+ </emu-clause>
42448
+
42449
+ <emu-clause id="sec-set.prototype.issubsetof">
42450
+ <h1>Set.prototype.isSubsetOf ( _other_ )</h1>
42451
+ <p>This method performs the following steps when called:</p>
42452
+ <emu-alg>
42453
+ 1. Let _O_ be the *this* value.
42454
+ 1. Perform ? RequireInternalSlot(_O_, [[SetData]]).
42455
+ 1. Let _otherRec_ be ? GetSetRecord(_other_).
42456
+ 1. If SetDataSize(_O_.[[SetData]]) > _otherRec_.[[Size]], return *false*.
42457
+ 1. Let _thisSize_ be the number of elements in _O_.[[SetData]].
42458
+ 1. Let _index_ be 0.
42459
+ 1. Repeat, while _index_ < _thisSize_,
42460
+ 1. Let _e_ be _O_.[[SetData]][_index_].
42461
+ 1. Set _index_ to _index_ + 1.
42462
+ 1. If _e_ is not ~empty~, then
42463
+ 1. Let _inOther_ be ToBoolean(? Call(_otherRec_.[[Has]], _otherRec_.[[SetObject]], « _e_ »)).
42464
+ 1. If _inOther_ is *false*, return *false*.
42465
+ 1. NOTE: The number of elements in _O_.[[SetData]] may have increased during execution of _otherRec_.[[Has]].
42466
+ 1. Set _thisSize_ to the number of elements in _O_.[[SetData]].
42467
+ 1. Return *true*.
42468
+ </emu-alg>
42469
+ </emu-clause>
42470
+
42471
+ <emu-clause id="sec-set.prototype.issupersetof">
42472
+ <h1>Set.prototype.isSupersetOf ( _other_ )</h1>
42473
+ <p>This method performs the following steps when called:</p>
42474
+ <emu-alg>
42475
+ 1. Let _O_ be the *this* value.
42476
+ 1. Perform ? RequireInternalSlot(_O_, [[SetData]]).
42477
+ 1. Let _otherRec_ be ? GetSetRecord(_other_).
42478
+ 1. If SetDataSize(_O_.[[SetData]]) < _otherRec_.[[Size]], return *false*.
42479
+ 1. Let _keysIter_ be ? GetIteratorFromMethod(_otherRec_.[[SetObject]], _otherRec_.[[Keys]]).
42480
+ 1. Let _next_ be ~not-started~.
42481
+ 1. Repeat, while _next_ is not ~done~,
42482
+ 1. Set _next_ to ? IteratorStepValue(_keysIter_).
42483
+ 1. If _next_ is not ~done~, then
42484
+ 1. If SetDataHas(_O_.[[SetData]], _next_) is *false*, then
42485
+ 1. Perform ? IteratorClose(_keysIter_, NormalCompletion(~unused~)).
42486
+ 1. Return *false*.
42487
+ 1. Return *true*.
42488
+ </emu-alg>
42489
+ </emu-clause>
42490
+
42198
42491
<emu-clause id="sec-set.prototype.keys">
42199
42492
<h1>Set.prototype.keys ( )</h1>
42200
42493
<p>The initial value of the *"keys"* property is %Set.prototype.values%, defined in <emu-xref href="#sec-set.prototype.values"></emu-xref>.</p>
@@ -42209,10 +42502,56 @@ <h1>get Set.prototype.size</h1>
42209
42502
<emu-alg>
42210
42503
1. Let _S_ be the *this* value.
42211
42504
1. Perform ? RequireInternalSlot(_S_, [[SetData]]).
42212
- 1. Let _count_ be 0.
42213
- 1. For each element _e_ of _S_.[[SetData]], do
42214
- 1. If _e_ is not ~empty~, set _count_ to _count_ + 1.
42215
- 1. Return 𝔽(_count_).
42505
+ 1. Let _size_ be SetDataSize(_S_.[[SetData]]).
42506
+ 1. Return 𝔽(_size_).
42507
+ </emu-alg>
42508
+ </emu-clause>
42509
+
42510
+ <emu-clause id="sec-set.prototype.symmetricdifference">
42511
+ <h1>Set.prototype.symmetricDifference ( _other_ )</h1>
42512
+ <p>This method performs the following steps when called:</p>
42513
+ <emu-alg>
42514
+ 1. Let _O_ be the *this* value.
42515
+ 1. Perform ? RequireInternalSlot(_O_, [[SetData]]).
42516
+ 1. Let _otherRec_ be ? GetSetRecord(_other_).
42517
+ 1. Let _keysIter_ be ? GetIteratorFromMethod(_otherRec_.[[SetObject]], _otherRec_.[[Keys]]).
42518
+ 1. Let _resultSetData_ be a copy of _O_.[[SetData]].
42519
+ 1. Let _next_ be ~not-started~.
42520
+ 1. Repeat, while _next_ is not ~done~,
42521
+ 1. Set _next_ to ? IteratorStepValue(_keysIter_).
42522
+ 1. If _next_ is not ~done~, then
42523
+ 1. Set _next_ to CanonicalizeKeyedCollectionKey(_next_).
42524
+ 1. Let _resultIndex_ be SetDataIndex(_resultSetData_, _next_).
42525
+ 1. If _resultIndex_ is ~not-found~, let _alreadyInResult_ be *false*. Otherwise let _alreadyInResult_ be *true*.
42526
+ 1. If SetDataHas(_O_.[[SetData]], _next_) is *true*, then
42527
+ 1. If _alreadyInResult_ is *true*, set _resultSetData_[_resultIndex_] to ~empty~.
42528
+ 1. Else,
42529
+ 1. If _alreadyInResult_ is *false*, append _next_ to _resultSetData_.
42530
+ 1. Let _result_ be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
42531
+ 1. Set _result_.[[SetData]] to _resultSetData_.
42532
+ 1. Return _result_.
42533
+ </emu-alg>
42534
+ </emu-clause>
42535
+
42536
+ <emu-clause id="sec-set.prototype.union">
42537
+ <h1>Set.prototype.union ( _other_ )</h1>
42538
+ <p>This method performs the following steps when called:</p>
42539
+ <emu-alg>
42540
+ 1. Let _O_ be the *this* value.
42541
+ 1. Perform ? RequireInternalSlot(_O_, [[SetData]]).
42542
+ 1. Let _otherRec_ be ? GetSetRecord(_other_).
42543
+ 1. Let _keysIter_ be ? GetIteratorFromMethod(_otherRec_.[[SetObject]], _otherRec_.[[Keys]]).
42544
+ 1. Let _resultSetData_ be a copy of _O_.[[SetData]].
42545
+ 1. Let _next_ be ~not-started~.
42546
+ 1. Repeat, while _next_ is not ~done~,
42547
+ 1. Set _next_ to ? IteratorStepValue(_keysIter_).
42548
+ 1. If _next_ is not ~done~, then
42549
+ 1. Set _next_ to CanonicalizeKeyedCollectionKey(_next_).
42550
+ 1. If SetDataHas(_resultSetData_, _next_) is *false*, then
42551
+ 1. Append _next_ to _resultSetData_.
42552
+ 1. Let _result_ be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
42553
+ 1. Set _result_.[[SetData]] to _resultSetData_.
42554
+ 1. Return _result_.
42216
42555
</emu-alg>
42217
42556
</emu-clause>
42218
42557
0 commit comments