This repository was archived by the owner on Oct 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathspec.html
1403 lines (1327 loc) · 88.2 KB
/
spec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<meta charset="utf8">
<script src="ecmarkup.js"></script>
<link rel="stylesheet" href="ecmarkup.css">
<title>Resizable ArrayBuffer and growable SharedArrayBuffer</title>
<pre class=metadata>
title: Resizable ArrayBuffer and growable SharedArrayBuffer
status: proposal
stage: 3
location: https://github.com/tc39/proposal-resizablearraybuffer
copyright: false
contributors: Shu-yu Guo
markEffects: true
</pre>
<emu-intro id="intro">
<h1>Resizable ArrayBuffer and growable SharedArrayBuffer</h1>
<p>We extend the `ArrayBuffer` and `SharedArrayBuffer` constructors to take an additional maximum byte length, which would construct dynamically resizable and growable array buffers, respectively.</p>
</emu-intro>
<emu-clause id="sec-arraybuffer-objects-mods">
<h1>Modifications to ArrayBuffer Objects</h1>
<emu-clause id="sec-abstract-operations-for-arraybuffer-objects-mods">
<h1>Modifications to Abstract Operations for ArrayBuffer Objects</h1>
<emu-clause id="sec-detacharraybuffer" type="abstract operation">
<h1>
DetachArrayBuffer (
_arrayBuffer_: an ArrayBuffer,
optional _key_: anything,
): either a normal completion containing ~unused~ or a throw completion
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Assert: IsSharedArrayBuffer(_arrayBuffer_) is *false*.
1. If _key_ is not present, set _key_ to *undefined*.
1. If _arrayBuffer_.[[ArrayBufferDetachKey]] is not _key_, throw a *TypeError* exception.
1. Set _arrayBuffer_.[[ArrayBufferData]] to *null*.
1. Set _arrayBuffer_.[[ArrayBufferByteLength]] to 0.
1. Return ~unused~.
</emu-alg>
<emu-note>
<p>Detaching an ArrayBuffer instance disassociates the Data Block used as its backing store from the instance and sets the byte length of the buffer to 0. <del>No operations defined by this specification use the DetachArrayBuffer abstract operation. However, an ECMAScript host or implementation may define such operations.</del></p>
</emu-note>
</emu-clause>
<emu-clause id="sec-allocatearraybuffer" type="abstract operation">
<h1>
AllocateArrayBuffer (
_constructor_: a constructor,
_byteLength_: a non-negative integer,
<ins>optional _maxByteLength_: a non-negative integer or ~empty~,</ins>
): either a normal completion containing an ArrayBuffer or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It is used to create an ArrayBuffer.</dd>
</dl>
<emu-alg>
1. <ins>Let _slots_ be « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] ».</ins>
1. <ins>If _maxByteLength_ is present and not ~empty~, then</ins>
1. <ins>If _byteLength_ > _maxByteLength_, throw a *RangeError* exception.</ins>
1. <ins>Append [[ArrayBufferMaxByteLength]] to _slots_.</ins>
1. Let _obj_ be ? OrdinaryCreateFromConstructor(_constructor_, *"%ArrayBuffer.prototype%"*, <del>« [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] »</del><ins>_slots_</ins>).
1. Let _block_ be ? CreateByteDataBlock(_byteLength_).
1. Set _obj_.[[ArrayBufferData]] to _block_.
1. Set _obj_.[[ArrayBufferByteLength]] to _byteLength_.
1. <ins>If _maxByteLength_ is present and not ~empty~, then</ins>
1. <ins>If it is not possible to create a Data Block _block_ consisting of _maxByteLength_ bytes, throw a *RangeError* exception.</ins>
1. <ins>NOTE: Resizable ArrayBuffers are designed to be implementable with in-place growth. Implementations reserve the right to throw if, for example, virtual memory cannot be reserved up front.</ins>
1. <ins>Set _obj_.[[ArrayBufferMaxByteLength]] to _maxByteLength_.</ins>
1. Return _obj_.
</emu-alg>
</emu-clause>
<ins class="block">
<emu-clause id="sec-arraybufferlength" type="abstract operation">
<h1>
ArrayBufferByteLength (
_arrayBuffer_: an ArrayBuffer or SharedArrayBuffer,
_order_: ~SeqCst~ or ~Unordered~,
): a non-negative integer
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If IsSharedArrayBuffer(_arrayBuffer_) is *true* and _arrayBuffer_ has an [[ArrayBufferByteLengthData]] internal slot, then
1. Let _bufferByteLengthBlock_ be _arrayBuffer_.[[ArrayBufferByteLengthData]].
1. Return ℝ(GetValueFromBuffer(_bufferByteLengthBlock_, 0, ~BigUint64~, *true*, _order_)).
1. Assert: IsDetachedBuffer(_arrayBuffer_) is *false*.
1. Return _arrayBuffer_.[[ArrayBufferByteLength]].
</emu-alg>
</emu-clause>
<emu-clause id="sec-makeidempotentarraybufferbytelengthgetter" type="abstract operation">
<h1>
MakeIdempotentArrayBufferByteLengthGetter (
_order_: ~SeqCst~ or ~Unordered~,
): an Abstract Closure with one parameter
</h1>
<dl class="header">
<dt>description</dt>
<dd>The returned Abstract Closure helps ensure that there there is a single shared memory read event of the byte length data block in the calling operation.</dd>
</dl>
<emu-alg>
1. NOTE: The [[ArrayBuffer]] slot is used for editorial clarity only, that a getter should only be used with a single ArrayBuffer.
1. Let _lengthStorage_ be { [[ArrayBuffer]]: ~empty~, [[ByteLength]]: ~empty~ }.
1. Let _getter_ be a new Abstract Closure with parameters (_buffer_) that captures _lengthStorage_ and _order_ and performs the following steps when called:
1. If _lengthStorage_.[[ByteLength]] is ~empty~, then
1. Assert: _lengthStorage_.[[ArrayBuffer]] is ~empty~.
1. Set _lengthStorage_.[[ArrayBuffer]] to _buffer_.
1. Set _lengthStorage_.[[ByteLength]] to ArrayBufferByteLength(_buffer_, _order_).
1. Assert: SameValue(_lengthStorage_.[[ArrayBuffer]], _buffer_) is *true*.
1. Return _lengthStorage_.[[ByteLength]].
1. Return _getter_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-isresizablearraybuffer" type="abstract operation">
<h1>
IsResizableArrayBuffer (
_arrayBuffer_: an ArrayBuffer or a SharedArrayBuffer,
): a Boolean
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If _arrayBuffer_ has an [[ArrayBufferMaxByteLength]] internal slot, return *true*.
1. Return *false*.
</emu-alg>
</emu-clause>
<emu-clause id="sec-getarraybuffermaxbytelengthoption" type="abstract operation">
<h1>
GetArrayBufferMaxByteLengthOption (
_options_: an ECMAScript language value,
): a normal completion containing either a non-negative integer or ~empty~
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If Type(_options_) is not Object, return ~empty~.
1. Let _maxByteLength_ be ? Get(_options_, `"maxByteLength"`).
1. If _maxByteLength_ is *undefined*, return ~empty~.
1. Return ? ToIndex(_maxByteLength_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-hostresizearraybuffer" type="host-defined abstract operation">
<h1>
HostResizeArrayBuffer (
_buffer_: an ArrayBuffer,
_newByteLength_: a non-negative integer,
): either a normal completion containing either ~handled~ or ~unhandled~, or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>The host-defined abstract operation HostResizeArrayBuffer takes arguments _buffer_ (an ArrayBuffer object) and _newByteLength_. It gives the host an opportunity to perform implementation-defined resizing of _buffer_. If the host chooses not to handle resizing of _buffer_, it may return ~unhandled~ for the default behaviour.</dd>
</dl>
<p>The implementation of HostResizeArrayBuffer must conform to the following requirements:</p>
<ul>
<li>The abstract operation must return either NormalCompletion(~handled~), NormalCompletion(~unhandled~), or an abrupt throw completion.</li>
<li>The abstract operation does not detach _buffer_.</li>
<li>If the abstract operation completes normally with ~handled~, _buffer_.[[ArrayBufferByteLength]] is _newByteLength_.</li>
</ul>
<p>The default implementation of HostResizeArrayBuffer is to return ~unhandled~.</p>
</emu-clause>
</ins>
</emu-clause>
<emu-clause id="sec-arraybuffer-constructor">
<h1>The ArrayBuffer Constructor</h1>
<emu-clause id="sec-arraybuffer-length">
<h1>ArrayBuffer ( _length_ <ins>[ , _options_ ]</ins> )</h1>
<p>When the `ArrayBuffer` function is called with argument _length_<ins> and optional argument _options_</ins>, the following steps are taken:</p>
<emu-alg>
1. If NewTarget is *undefined*, throw a *TypeError* exception.
1. Let _byteLength_ be ? ToIndex(_length_).
1. <ins>Let _requestedMaxByteLength_ be ? GetArrayBufferMaxByteLengthOption(_options_).</ins>
1. Return ? AllocateArrayBuffer(NewTarget, _byteLength_<ins>, _requestedMaxByteLength_</ins>).
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-the-arraybuffer-prototype-object-mods">
<h1>Modifications to the Properties of the ArrayBuffer Prototype Object</h1>
<emu-clause id="sec-get-arraybuffer-@@species">
<h1>get ArrayBuffer [ @@species ]</h1>
<p>`ArrayBuffer[@@species]` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Return the *this* value.
</emu-alg>
<p>The value of the *"name"* property of this function is *"get [Symbol.species]"*.</p>
<emu-note>
<p>ArrayBuffer prototype methods normally use their *this* value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour <ins>for the <emu-xref href="#sec-arraybuffer.prototype.slice" title></emu-xref> method</ins> by redefining its @@species property.</p>
</emu-note>
</emu-clause>
<ins class="block">
<emu-clause id="sec-get-arraybuffer.prototype.maxbytelength">
<h1>get ArrayBuffer.prototype.maxByteLength</h1>
<p>`ArrayBuffer.prototype.maxByteLength` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferData]]).
1. If IsSharedArrayBuffer(_O_) is *true*, throw a *TypeError* exception.
1. If IsDetachedBuffer(_O_) is *true*, return *+0*<sub>𝔽</sub>.
1. If IsResizableArrayBuffer(_O_) is *true*, then
1. Let _length_ be _O_.[[ArrayBufferMaxByteLength]].
1. Else,
1. Let _length_ be _O_.[[ArrayBufferByteLength]].
1. Return 𝔽(_length_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-get-arraybuffer.prototype.resizable">
<h1>get ArrayBuffer.prototype.resizable</h1>
<p>`ArrayBuffer.prototype.resizable` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferData]]).
1. If IsSharedArrayBuffer(_O_) is *true*, throw a *TypeError* exception.
1. Return IsResizableArrayBuffer(_O_).
</emu-alg>
</emu-clause>
</ins>
<emu-clause id="sec-arraybuffer.prototype.slice">
<h1>ArrayBuffer.prototype.slice ( _start_, _end_ )</h1>
<p>This method performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferData]]).
1. If IsSharedArrayBuffer(_O_) is *true*, throw a *TypeError* exception.
1. If IsDetachedBuffer(_O_) is *true*, throw a *TypeError* exception.
1. Let _len_ be _O_.[[ArrayBufferByteLength]].
1. Let _relativeStart_ be ? ToIntegerOrInfinity(_start_).
1. If _relativeStart_ is -∞, let _first_ be 0.
1. Else if _relativeStart_ < 0, let _first_ be max(_len_ + _relativeStart_, 0).
1. Else, let _first_ be min(_relativeStart_, _len_).
1. If _end_ is *undefined*, let _relativeEnd_ be _len_; else let _relativeEnd_ be ? ToIntegerOrInfinity(_end_).
1. If _relativeEnd_ is -∞, let _final_ be 0.
1. Else if _relativeEnd_ < 0, let _final_ be max(_len_ + _relativeEnd_, 0).
1. Else, let _final_ be min(_relativeEnd_, _len_).
1. Let _newLen_ be max(_final_ - _first_, 0).
1. Let _ctor_ be ? SpeciesConstructor(_O_, %ArrayBuffer%).
1. Let _new_ be ? Construct(_ctor_, « 𝔽(_newLen_) »).
1. Perform ? RequireInternalSlot(_new_, [[ArrayBufferData]]).
1. If IsSharedArrayBuffer(_new_) is *true*, throw a *TypeError* exception.
1. If IsDetachedBuffer(_new_) is *true*, throw a *TypeError* exception.
1. If SameValue(_new_, _O_) is *true*, throw a *TypeError* exception.
1. If _new_.[[ArrayBufferByteLength]] < _newLen_, throw a *TypeError* exception.
1. NOTE: Side-effects of the above steps may have detached <ins>or resized </ins>_O_.
1. If IsDetachedBuffer(_O_) is *true*, throw a *TypeError* exception.
1. Let _fromBuf_ be _O_.[[ArrayBufferData]].
1. Let _toBuf_ be _new_.[[ArrayBufferData]].
1. <ins>If _first_ < _O_.[[ArrayBufferByteLength]], then</ins>
1. Perform CopyDataBlockBytes(_toBuf_, 0, _fromBuf_, _first_, <ins>min(_O_.[[ArrayBufferByteLength]], </ins>_newLen_<ins>)</ins>).
1. Return _new_.
</emu-alg>
</emu-clause>
<ins class="block">
<emu-clause id="sec-arraybuffer.prototype.resize">
<h1>ArrayBuffer.prototype.resize ( _newLength_ )</h1>
<p>The following steps are taken:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferMaxByteLength]]).
1. If IsSharedArrayBuffer(_O_) is *true*, throw a *TypeError* exception.
1. If IsDetachedBuffer(_O_) is *true*, throw a *TypeError* exception.
1. Let _newByteLength_ be ? ToIntegerOrInfinity(_newLength_).
1. If _newByteLength_ < 0 or _newByteLength_ > _O_.[[ArrayBufferMaxByteLength]], throw a *RangeError* exception.
1. Let _hostHandled_ be ? HostResizeArrayBuffer(_O_, _newByteLength_).
1. If _hostHandled_ is ~handled~, return *undefined*.
1. Let _oldBlock_ be _O_.[[ArrayBufferData]].
1. Let _newBlock_ be ? CreateByteDataBlock(_newByteLength_).
1. Let _copyLength_ be min(_newByteLength_, _O_.[[ArrayBufferByteLength]]).
1. Perform CopyDataBlockBytes(_newBlock_, 0, _oldBlock_, 0, _copyLength_).
1. NOTE: Neither creation of the new Data Block nor copying from the old Data Block are observable. Implementations reserve the right to implement this method as in-place growth or shrinkage.
1. Set _O_.[[ArrayBufferData]] to _newBlock_.
1. Set _O_.[[ArrayBufferByteLength]] to _newLength_.
1. Return *undefined*.
</emu-alg>
</emu-clause>
</ins>
</emu-clause>
</emu-clause>
<emu-clause id="sec-sharedarraybuffer-objects-mods">
<h1>Modifications to SharedArrayBuffer Objects</h1>
<emu-clause id="sec-abstract-operations-for-sharedarraybuffer-objects-mods">
<h1>Modifications to Abstract Operations for SharedArrayBuffer Objects</h1>
<emu-clause id="sec-allocatesharedarraybuffer" type="abstract operation">
<h1>
AllocateSharedArrayBuffer (
_constructor_: a constructor,
_byteLength_: a non-negative integer,
<ins>optional _maxByteLength_: a non-negative integer or ~empty~,</ins>
): either a normal completion containing a SharedArrayBuffer or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It is used to create a SharedArrayBuffer.</dd>
</dl>
<emu-alg>
1. <ins>Let _slots_ be « [[ArrayBufferData]] ».</ins>
1. <ins>If _maxByteLength_ is present and not ~empty~, then</ins>
1. <ins>If _byteLength_ > _maxByteLength_, throw a *RangeError* exception.</ins>
1. <ins>Append [[ArrayBufferByteLengthData]] and [[ArrayBufferMaxByteLength]] to _slots_.</ins>
1. <ins>Else, append [[ArrayBufferByteLength]] to _slots_.</ins>
1. Let _obj_ be ? OrdinaryCreateFromConstructor(_constructor_, *"%SharedArrayBuffer.prototype%"*, <del>« [[ArrayBufferData]], [[ArrayBufferByteLength]] »</del><ins>_slots_</ins>).
1. <ins>If _maxByteLength_ is present, let _allocLength_ be _maxByteLength_.</ins>
1. <ins>Else, let _allocLength_ be _byteLength_.</ins>
1. Let _block_ be ? CreateSharedByteDataBlock(<del>_byteLength_</del><ins>_allocLength_</ins>).
1. <ins>NOTE: Growable SharedArrayBuffers must be implemented as in-place growable. Creation of a _maxByteLength_ sized Data Block is a specification mechanism. It may be implemented as committing a _byteLength_ sized buffer while reserving _maxByteLength_ in virtual memory.</ins>
1. Set _obj_.[[ArrayBufferData]] to _block_.
1. <ins>If _maxByteLength_ is present and not ~empty~, then</ins>
1. <ins>Assert: _byteLength_ ≤ _maxByteLength_.</ins>
1. <ins>Let _byteLengthBlock_ be ? CreateSharedByteDataBlock(8).</ins>
1. <ins>Perform SetValueInBuffer(_byteLengthBlock_, 0, ~BigUint64~, ℤ(_byteLength_), *true*, ~SeqCst~).</ins>
1. <ins>Set _obj_.[[ArrayBufferByteLengthData]] to _byteLengthBlock_.</ins>
1. <ins>Set _obj_.[[ArrayBufferMaxByteLength]] to _maxByteLength_.</ins>
1. <ins>Else,</ins>
1. Set _obj_.[[ArrayBufferByteLength]] to _byteLength_.
1. Return _obj_.
</emu-alg>
</emu-clause>
<ins class="block">
<emu-clause id="sec-hostgrowsharedarraybuffer" type="host-defined abstract operation">
<h1>
HostGrowSharedArrayBuffer (
_buffer_: a SharedArrayBuffer,
_newByteLength_: a non-negative integer
): either a normal completion containing either ~handled~ or ~unhandled~, or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It gives the host an opportunity to perform implementation-defined growing of _buffer_. If the host chooses not to handle resizing of _buffer_, it may return ~unhandled~ for the default behaviour.</dd>
</dl>
<p>The implementation of HostGrowSharedArrayBuffer must conform to the following requirements:</p>
<ul>
<li>The abstract operation must return either NormalCompletion(~handled~), NormalCompletion(~unhandled~), or an abrupt throw completion.</li>
<li>If the abstract operation does not complete normally with ~unhandled~, and _newByteLength_ < the current byte length of the _buffer_ or _newByteLength_ > _buffer_.[[ArrayBufferMaxByteLength]], throw a *RangeError* exception.</li>
<li>Let _isLittleEndian_ be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record. If the abstract operation completes normally with ~handled~, a WriteSharedMemory or ReadModifyWriteSharedMemory event whose [[Order]] is ~SeqCst~, [[Payload]] is NumericToRawBytes(~BigUint64~, _newByteLength_, _isLittleEndian_), [[Block]] is _buffer_.[[ArrayBufferByteLengthData]], [[ByteIndex]] is 0, and [[ElementSize]] is 8 is added to the surrounding agent's candidate execution such that racing calls to `SharedArrayBuffer.prototype.grow` are not "lost", i.e. silently do nothing.</li>
</ul>
<p>The default implementation of HostGrowSharedArrayBuffer is to return ~unhandled~.</p>
<emu-note>
<p>The second requirement above is intentionally vague about how or when the current byte length of _buffer_ is read. Because the byte length must be updated via an atomic read-modify-write operation on the underlying hardware, architectures that use load-link/store-conditional or load-exclusive/store-exclusive instruction pairs may wish to keep the paired instructions close in the instruction stream. As such, SharedArrayBuffer.prototype.grow itself does not perform bounds checking on _newByteLength_ before calling HostGrowSharedArrayBuffer, nor is there a requirement on when the current byte length is read.</p>
<p>This is in contrast with HostResizeArrayBuffer, which is guaranteed that the value of _newByteLength_ is ≥ 0 and ≤ _buffer_.[[ArrayBufferMaxByteLength]].</p>
</emu-note>
</emu-clause>
</ins>
</emu-clause>
<emu-clause id="sec-sharedarraybuffer-constructor">
<h1>The SharedArrayBuffer Constructor</h1>
<emu-clause id="sec-sharedarraybuffer-length">
<h1>SharedArrayBuffer ( _length_ <ins>[ , _options_ ]</ins> )</h1>
<p>When the `SharedArrayBuffer` function is called with argument _length_<ins> and optional argument _options_</ins>, the following steps are taken:</p>
<emu-alg>
1. If NewTarget is *undefined*, throw a *TypeError* exception.
1. Let _byteLength_ be ? ToIndex(_length_).
1. <ins>Let _requestedMaxByteLength_ be ? GetArrayBufferMaxByteLengthOption(_options_).</ins>
1. Return ? AllocateSharedArrayBuffer(NewTarget, _byteLength_<ins>, _requestedMaxByteLength_</ins>).
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-the-sharedarraybuffer-prototype-object-mods">
<h1>Modifications to the Properties of the SharedArrayBuffer Prototype Object</h1>
<emu-clause id="sec-get-sharedarraybuffer.prototype.bytelength">
<h1>get SharedArrayBuffer.prototype.byteLength</h1>
<p>`SharedArrayBuffer.prototype.byteLength` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferData]]).
1. If IsSharedArrayBuffer(_O_) is *false*, throw a *TypeError* exception.
1. Let _length_ be <del>_O_.[[ArrayBufferByteLength]]</del><ins>ArrayBufferByteLength(_O_, ~SeqCst~)</ins>.
1. Return 𝔽(_length_).
</emu-alg>
</emu-clause>
<ins class="block">
<emu-clause id="sec-get-sharedarraybuffer.prototype.growable">
<h1>get SharedArrayBuffer.prototype.growable</h1>
<p>`SharedArrayBuffer.prototype.growable` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferData]]).
1. If IsSharedArrayBuffer(_O_) is *false*, throw a *TypeError* exception.
1. Return IsResizableArrayBuffer(_O_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-get-sharedarraybuffer.prototype.maxbytelength">
<h1>get SharedArrayBuffer.prototype.maxByteLength</h1>
<p>`SharedArrayBuffer.prototype.maxByteLength` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferData]]).
1. If IsSharedArrayBuffer(_O_) is *false*, throw a *TypeError* exception.
1. If IsResizableArrayBuffer(_O_) is *true*, then
1. Let _length_ be _O_.[[ArrayBufferMaxByteLength]].
1. Else,
1. Let _length_ be _O_.[[ArrayBufferByteLength]].
1. Return 𝔽(_length_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-sharedarraybuffer.prototype.grow">
<h1>SharedArrayBuffer.prototype.grow ( _newLength_ )</h1>
<p>The following steps are taken:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferMaxByteLength]]).
1. If IsSharedArrayBuffer(_O_) is *false*, throw a *TypeError* exception.
1. Let _newByteLength_ be ? ToIntegerOrInfinity(_newLength_).
1. Let _hostHandled_ be ? HostGrowSharedArrayBuffer(_O_, _newByteLength_).
1. If _hostHandled_ is ~handled~, return *undefined*.
1. Let _rawCurrentByteLengthBytesRead_ be a List of length 8 whose elements are nondeterministically chosen byte values.
1. NOTE: In implementations, _rawCurrentByteLengthBytesRead_ is the result of a load-link, of a load-exclusive, or of an operand of a read-modify-write instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
1. Let _byteLengthBlock_ be _O_.[[ArrayBufferByteLengthData]].
1. Let _isLittleEndian_ be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
1. Let _currentByteLength_ be RawBytesToNumeric(~BigUint64~, _rawCurrentByteLengthBytesRead_, _isLittleEndian_).
1. Let _growFailed_ be *false*.
1. If _newByteLength_ < _currentByteLength_ or _newByteLength_ > _O_.[[ArrayBufferMaxByteLength]], set _growFailed_ to *true*.
1. Let _byteLengthDelta_ be _newByteLength_ - _currentByteLength_.
1. If it is impossible to create a new Shared Data Block value consisting of _byteLengthDelta_ bytes, set _growFailed_ to *true*.
1. NOTE: No new Shared Data Block is constructed and used here. The observable behaviour of growable SharedArrayBuffers is specified by allocating a max-sized Shared Data Block at construction time, and this step is intended to capture the requirement that implementations that run out of memory must throw a *RangeError*.
1. NOTE: The above checks help ensure that concurrent calls to SharedArrayBuffer.prototype.grow are totally ordered. For example, consider two racing calls: `sab.grow(10)` and `sab.grow(20)`. One of the two calls is guaranteed to win the race. The call to `sab.grow(10)` will never shrink `sab` even if `sab.grow(20)` happened first.
1. If _growFailed_ is *false* and _newByteLength_ ≠ _currentByteLength_, then
1. NOTE: Resizes to the same length explicitly do nothing to avoid gratuitous synchronization.
1. Let _second_ be a new read-modify-write modification function with parameters (_oldBytes_, _newBytes_) that captures nothing and performs the following steps atomically when called:
1. Return _newBytes_.
1. Let _newByteLengthBytes_ be NumericToRawBytes(~BigUint64~, ℤ(_newByteLength_), _isLittleEndian_).
1. Let _event_ be ReadModifyWriteSharedMemory { [[Order]]: ~SeqCst~, [[NoTear]]: *true*, [[Block]]: _byteLengthBlock_, [[ByteIndex]]: 0, [[ElementSize]]: 8, [[Payload]]: _newByteLengthBytes_, [[ModifyOp]]: _second_ }.
1. NOTE: The new memory is already zeroed, as a _O_.[[ArrayBufferMaxByteLength]] sized Data Block is already allocated. This is a specification mechanism; an implementation is not required to reserve _O_.[[ArrayBufferMaxByteLength]] bytes of physical memory.
1. Else,
1. Let _event_ be ReadSharedMemory { [[Order]]: ~SeqCst~, [[NoTear]]: *true*, [[Block]]: _byteLengthBlock_, [[ByteIndex]]: 0, [[ElementSize]]: 8 }.
1. Let _execution_ be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
1. Let _eventList_ be the [[EventList]] field of the element in _execution_.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
1. Append _event_ to _eventList_.
1. Append Chosen Value Record { [[Event]]: _event_, [[ChosenValue]]: _rawCurrentByteLengthBytesRead_ } to _execution_.[[ChosenValues]].
1. If _growFailed_ is *true*, throw a *RangeError* exception.
1. Return *undefined*.
</emu-alg>
<emu-note>
<p>Spurious failures of the compare-exchange to update the length are prohibited. If the bounds checking for the new length passes and the implementation is not out of memory, a ReadModifyWriteSharedMemory event (i.e. a successful compare-exchange) is always added into the candidate execution.</p>
<p>Many of the above steps are shared with the algorithm steps of Atomics.compareExchange and should be refactored when merged into the full specification.</p>
</emu-note>
</emu-clause>
</ins>
<emu-clause id="sec-sharedarraybuffer.prototype.slice">
<h1>SharedArrayBuffer.prototype.slice ( _start_, _end_ )</h1>
<p>This method performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[ArrayBufferData]]).
1. If IsSharedArrayBuffer(_O_) is *false*, throw a *TypeError* exception.
1. Let _len_ be <del>_O_.[[ArrayBufferByteLength]]</del><ins>ArrayBufferByteLength(_O_, ~SeqCst~)</ins>.
1. Let _relativeStart_ be ? ToIntegerOrInfinity(_start_).
1. If _relativeStart_ is -∞, let _first_ be 0.
1. Else if _relativeStart_ < 0, let _first_ be max(_len_ + _relativeStart_, 0).
1. Else, let _first_ be min(_relativeStart_, _len_).
1. If _end_ is *undefined*, let _relativeEnd_ be _len_; else let _relativeEnd_ be ? ToIntegerOrInfinity(_end_).
1. If _relativeEnd_ is -∞, let _final_ be 0.
1. Else if _relativeEnd_ < 0, let _final_ be max(_len_ + _relativeEnd_, 0).
1. Else, let _final_ be min(_relativeEnd_, _len_).
1. Let _newLen_ be max(_final_ - _first_, 0).
1. Let _ctor_ be ? SpeciesConstructor(_O_, %SharedArrayBuffer%).
1. Let _new_ be ? Construct(_ctor_, « 𝔽(_newLen_) »).
1. Perform ? RequireInternalSlot(_new_, [[ArrayBufferData]]).
1. <ins>NOTE: Unlike ArrayBuffers, SharedArrayBuffers cannot shrink, so the length does not need to be reloaded.</ins>
1. If IsSharedArrayBuffer(_new_) is *false*, throw a *TypeError* exception.
1. If _new_.[[ArrayBufferData]] and _O_.[[ArrayBufferData]] are the same Shared Data Block values, throw a *TypeError* exception.
1. If _new_.[[ArrayBufferByteLength]] < _newLen_, throw a *TypeError* exception.
1. Let _fromBuf_ be _O_.[[ArrayBufferData]].
1. Let _toBuf_ be _new_.[[ArrayBufferData]].
1. Perform CopyDataBlockBytes(_toBuf_, 0, _fromBuf_, _first_, _newLen_).
1. Return _new_.
</emu-alg>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="sec-integer-indexed-exotic-objects-mods">
<h1>Modifications to Integer-Indexed Exotic Objects</h1>
<emu-clause id="sec-integer-indexed-exotic-objects-ownpropertykeys" type="internal method">
<h1>[[OwnPropertyKeys]] ( ): a normal completion containing a List of property keys</h1>
<dl class="header">
<dt>for</dt>
<dd>an Integer-Indexed exotic object _O_</dd>
</dl>
<emu-alg>
1. Let _keys_ be a new empty List.
1. Assert: _O_ is an Integer-Indexed exotic object.
1. <del>If IsDetachedBuffer(_O_.[[ViewedArrayBuffer]]) is *false*, then</del>
1. <del>For each integer _i_ starting with 0 such that _i_ < _O_.[[ArrayLength]], in ascending order, do</del>
1. <del>Add ! ToString(𝔽(_i_)) as the last element of _keys_.</del>
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. <ins>Let _len_ be IntegerIndexedObjectLength(_O_, _getBufferByteLength_).</ins>
1. <ins>If _len_ is not ~out-of-bounds~, then</ins>
1. <ins>For each integer _i_ starting with 0 such that _i_ < _len_, in ascending order, do</ins>
1. <ins>Add ! ToString(𝔽(_i_)) as the last element of _keys_.</ins>
1. For each own property key _P_ of _O_ such that Type(_P_) is String and _P_ is not an integer index, in ascending chronological order of property creation, do
1. Add _P_ as the last element of _keys_.
1. For each own property key _P_ of _O_ such that Type(_P_) is Symbol, in ascending chronological order of property creation, do
1. Add _P_ as the last element of _keys_.
1. Return _keys_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-isvalidintegerindex" type="abstract operation">
<h1>
IsValidIntegerIndex (
_O_: an Integer-Indexed exotic object,
_index_: a Number,
): a Boolean
</h1>
<dl class="header">
</dl>
<emu-alg>
1. <del>If IsDetachedBuffer(_O_.[[ViewedArrayBuffer]]) is *true*, return *false*.</del>
1. If IsIntegralNumber(_index_) is *false*, return *false*.
1. If _index_ is *-0*<sub>𝔽</sub>, return *false*.
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~Unordered~).</ins>
1. <ins>NOTE: Bounds checking is not a synchronizing operation when _O_'s backing buffer is a growable SharedArrayBuffer.</ins>
1. <ins>Let _length_ be IntegerIndexedObjectLength(_O_, _getBufferByteLength_).</ins>
1. If <ins>_length_ is ~out-of-bounds~ or</ins> ℝ(_index_) < 0 or ℝ(_index_) ≥ <del>_O_.[[ArrayLength]]</del><ins>_length_</ins>, return *false*.
1. Return *true*.
</emu-alg>
</emu-clause>
<ins class="block">
<emu-clause id="sec-integerindexedobjectbytelength" type="abstract operation">
<h1>
IntegerIndexedObjectByteLength (
_O_: an Integer-Indexed exotic object,
_getBufferByteLength_: an Abstract Closure,
): a non-negative integer
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Let _length_ be IntegerIndexedObjectLength(_O_, _getBufferByteLength_).
1. If _length_ is ~out-of-bounds~ or _length_ = 0, return 0.
1. If _O_.[[ByteLength]] is not ~auto~, return _O_.[[ByteLength]].
1. Let _elementSize_ be TypedArrayElementSize(_O_).
1. Return _length_ × _elementSize_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-integerindexedobjectlength" type="abstract operation">
<h1>
IntegerIndexedObjectLength (
_O_: an Integer-Indexed exotic object,
_getBufferByteLength_: an Abstract Closure,
): a non-negative integer or ~out-of-bounds~
</h1>
<dl class="header">
</dl>
<emu-alg>
1. If IsIntegerIndexedObjectOutOfBounds(_O_, _getBufferByteLength_) is *true*, return ~out-of-bounds~.
1. If _O_.[[ArrayLength]] is not ~auto~, return _O_.[[ArrayLength]].
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. Let _bufferByteLength_ be _getBufferByteLength_(_buffer_).
1. Assert: IsResizableArrayBuffer(_buffer_) is *true*.
1. Let _byteOffset_ be _O_.[[ByteOffset]].
1. Let _elementSize_ be TypedArrayElementSize(_O_).
1. Return floor((_bufferByteLength_ - _byteOffset_) / _elementSize_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-isintegerindexedobjectoutofbounds" type="abstract operation">
<h1>
IsIntegerIndexedObjectOutOfBounds (
_O_: an Integer-Indexed exotic object,
_getBufferByteLength_: an Abstract Closure,
): a Boolean
</h1>
<dl class="header">
<dt>description</dt>
<dd>It checks if any of the object's numeric properties reference a value at an index not contained within the underlying data block's bounds.</dd>
</dl>
<emu-alg>
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. If IsDetachedBuffer(_O_.[[ViewedArrayBuffer]]) is *true*, return *true*.
1. Let _bufferByteLength_ be _getBufferByteLength_(_buffer_).
1. Let _byteOffsetStart_ be _O_.[[ByteOffset]].
1. If _O_.[[ArrayLength]] is ~auto~, then
1. Let _byteOffsetEnd_ be _bufferByteLength_.
1. Else,
1. Let _elementSize_ be TypedArrayElementSize(_O_).
1. Let _byteOffsetEnd_ be _byteOffsetStart_ + _O_.[[ArrayLength]] × _elementSize_.
1. If _byteOffsetStart_ > _bufferByteLength_ or _byteOffsetEnd_ > _bufferByteLength_, return *true*.
1. NOTE: 0-length TypedArrays are not considered out-of-bounds.
1. Return *false*.
</emu-alg>
</emu-clause>
<emu-clause id="sec-isarraybufferviewoutofbounds" type="abstract operation">
<h1>
IsArrayBufferViewOutOfBounds(
_O_: an Integer-Indexed exotic object or a DataView,
): a Boolean
</h1>
<dl class="header">
<dt>description</dt>
<dd>It checks if either any of a TypedArray's numeric properties or a DataView object's methods can reference a value at an index not contained within the underlying data block's bounds. This abstract operation exists as a convenience for upstream specifications.</dd>
</dl>
<emu-alg>
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. If IsDetachedBuffer(_buffer_) is *true*, return *true*.
1. Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).
1. If IsSharedArrayBuffer(_buffer_) is *true*, then
1. Assert: If _O_ has a [[DataView]] internal slot, IsViewOutOfBounds(_O_, _getBufferByteLength_) is *false*. Else, IsIntegerIndexedObjectOutOfBounds(_O_, _getBufferByteLength_) is *false*.
1. NOTE: SharedArrayBuffers can only grow, and views on it cannot go out of bounds after construction. This is special-cased in this operation to avoid shared memory loads of the buffer's byte length, which are not necessary for this check.
1. Return *false*.
1. If _O_ has a [[DataView]] internal slot, return IsViewOutOfBounds(_O_, _getBufferByteLength_).
1. Return IsIntegerIndexedObjectOutOfBounds(_O_, _getBufferByteLength_).
</emu-alg>
</emu-clause>
</ins>
</emu-clause>
<emu-clause id="sec-typedarray-objects-mods">
<h1>Modifications to TypedArray Objects</h1>
<emu-clause id="sec-properties-of-the-%typedarrayprototype%-object-mods">
<h1>Modifications to Properties of the %TypedArray.prototype% Object</h1>
<emu-clause id="sec-validatetypedarray" type="abstract operation">
<h1>
ValidateTypedArray (
_O_: an ECMAScript language value,
): either a normal completion containing ~unused~ or a throw completion
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Perform ? RequireInternalSlot(_O_, [[TypedArrayName]]).
1. Assert: _O_ has a [[ViewedArrayBuffer]] internal slot.
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. <del>If IsDetachedBuffer(_buffer_) is *true*, throw a *TypeError* exception.</del>
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. <ins>If IsIntegerIndexedObjectOutOfBounds(_O_, _getBufferByteLength_) is *true*, throw a *TypeError* exception.</ins>
1. Return _buffer_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-get-%typedarray%.prototype.bytelength">
<h1>get %TypedArray%.prototype.byteLength</h1>
<p>%TypedArray%`.prototype.byteLength` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[TypedArrayName]]).
1. Assert: _O_ has a [[ViewedArrayBuffer]] internal slot.
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. <del>If IsDetachedBuffer(_buffer_) is *true*, return *+0*<sub>𝔽</sub></del>.
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _size_ be <del>_O_.[[ByteLength]]</del><ins>IntegerIndexedObjectByteLength(_O_, _getBufferByteLength_)</ins>.
1. Return 𝔽(_size_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-get-%typedarray%.prototype.byteoffset">
<h1>get %TypedArray%.prototype.byteOffset</h1>
<p>%TypedArray%`.prototype.byteOffset` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[TypedArrayName]]).
1. Assert: _O_ has a [[ViewedArrayBuffer]] internal slot.
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. <del>If IsDetachedBuffer(_buffer_) is *true*, return *+0*<sub>𝔽</sub>.</del>
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. <ins>If IsIntegerIndexedObjectOutOfBounds(_O_, _getBufferByteLength_) is *true*, return *+0*<sub>𝔽</sub>.</ins>
1. Let _offset_ be _O_.[[ByteOffset]].
1. Return 𝔽(_offset_).
</emu-alg>
</emu-clause>
<emu-clause id="sec-get-%typedarray%.prototype.length">
<h1>get %TypedArray%.prototype.length</h1>
<p>%TypedArray%`.prototype.length` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[TypedArrayName]]).
1. Assert: _O_ has [[ViewedArrayBuffer]] and [[ArrayLength]] internal slots.
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. <del>If IsDetachedBuffer(_buffer_) is *true*, return *+0*<sub>𝔽</sub>.</del>
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _length_ be <del>_O_.[[ArrayLength]]</del><ins>IntegerIndexedObjectLength(_O_, _getBufferByteLength_)</ins>.
1. <ins>If _length_ is ~out-of-bounds~, set _length_ to 0.</ins>
1. Return 𝔽(_length_).
</emu-alg>
<p>This function is not generic. The *this* value must be an object with a [[TypedArrayName]] internal slot.</p>
</emu-clause>
<emu-clause id="sec-%typedarray%.prototype.copywithin">
<h1>%TypedArray%.prototype.copyWithin ( _target_, _start_ [ , _end_ ] )</h1>
<p>The interpretation and use of the arguments of %TypedArray%`.prototype.copyWithin` are the same as for `Array.prototype.copyWithin` as defined in <emu-xref href="#sec-array.prototype.copywithin"></emu-xref>.</p>
<p>This method performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? ValidateTypedArray(_O_).
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _len_ be <del>_O_.[[ArrayLength]]</del><ins>IntegerIndexedObjectLength(_O_, _getBufferByteLength_)</ins>.
1. <ins>Assert: _len_ is not ~out-of-bounds~.</ins>
1. Let _relativeTarget_ be ? ToIntegerOrInfinity(_target_).
1. If _relativeTarget_ is -∞, let _to_ be 0.
1. Else if _relativeTarget_ < 0, let _to_ be max(_len_ + _relativeTarget_, 0).
1. Else, let _to_ be min(_relativeTarget_, _len_).
1. Let _relativeStart_ be ? ToIntegerOrInfinity(_start_).
1. If _relativeStart_ is -∞, let _from_ be 0.
1. Else if _relativeStart_ < 0, let _from_ be max(_len_ + _relativeStart_, 0).
1. Else, let _from_ be min(_relativeStart_, _len_).
1. If _end_ is *undefined*, let _relativeEnd_ be _len_; else let _relativeEnd_ be ? ToIntegerOrInfinity(_end_).
1. If _relativeEnd_ is -∞, let _final_ be 0.
1. Else if _relativeEnd_ < 0, let _final_ be max(_len_ + _relativeEnd_, 0).
1. Else, let _final_ be min(_relativeEnd_, _len_).
1. Let _count_ be min(_final_ - _from_, _len_ - _to_).
1. If _count_ > 0, then
1. NOTE: The copying must be performed in a manner that preserves the bit-level encoding of the source data.
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. <ins>Set _getBufferByteLength_ to MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. <ins>Set _len_ to IntegerIndexedObjectLength(_O_, _getBufferByteLength_).</ins>
1. If <del>IsDetachedBuffer(_buffer_) is *true*</del><ins>_len_ is ~out-of-bounds~</ins>, throw a *TypeError* exception.
1. Let _typedArrayName_ be the String value of _O_.[[TypedArrayName]].
1. Let _elementSize_ be the Element Size value specified in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for _typedArrayName_.
1. Let _byteOffset_ be _O_.[[ByteOffset]].
1. <ins>Let _bufferByteLimit_ be _len_ × _elementSize_ + _byteOffset_.</ins>
1. Let _toByteIndex_ be _to_ × _elementSize_ + _byteOffset_.
1. Let _fromByteIndex_ be _from_ × _elementSize_ + _byteOffset_.
1. Let _countBytes_ be _count_ × _elementSize_.
1. If _fromByteIndex_ < _toByteIndex_ and _toByteIndex_ < _fromByteIndex_ + _countBytes_, then
1. Let _direction_ be -1.
1. Set _fromByteIndex_ to _fromByteIndex_ + _countBytes_ - 1.
1. Set _toByteIndex_ to _toByteIndex_ + _countBytes_ - 1.
1. Else,
1. Let _direction_ be 1.
1. Repeat, while _countBytes_ > 0,
1. <ins>If _fromByteIndex_ < _bufferByteLimit_ and _toByteIndex_ < _bufferByteLimit_, then</ins>
1. Let _value_ be GetValueFromBuffer(_buffer_, _fromByteIndex_, ~Uint8~, *true*, ~Unordered~).
1. Perform SetValueInBuffer(_buffer_, _toByteIndex_, ~Uint8~, _value_, *true*, ~Unordered~).
1. Set _fromByteIndex_ to _fromByteIndex_ + _direction_.
1. Set _toByteIndex_ to _toByteIndex_ + _direction_.
1. Set _countBytes_ to _countBytes_ - 1.
1. Return _O_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-%typedarray%.prototype.fill">
<h1>%TypedArray%.prototype.fill ( _value_ [ , _start_ [ , _end_ ] ] )</h1>
<p>The interpretation and use of the arguments of %TypedArray%`.prototype.fill` are the same as for `Array.prototype.fill` as defined in <emu-xref href="#sec-array.prototype.fill"></emu-xref>.</p>
<p>This method performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? ValidateTypedArray(_O_).
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _len_ be <del>_O_.[[ArrayLength]]</del><ins>IntegerIndexedObjectLength(_O_, _getBufferByteLength_)</ins>.
1. <ins>Assert: _len_ is not ~out-of-bounds~.</ins>
1. If _O_.[[ContentType]] is ~BigInt~, set _value_ to ? ToBigInt(_value_).
1. Otherwise, set _value_ to ? ToNumber(_value_).
1. Let _relativeStart_ be ? ToIntegerOrInfinity(_start_).
1. If _relativeStart_ is -∞, let _k_ be 0.
1. Else if _relativeStart_ < 0, let _k_ be max(_len_ + _relativeStart_, 0).
1. Else, let _k_ be min(_relativeStart_, _len_).
1. If _end_ is *undefined*, let _relativeEnd_ be _len_; else let _relativeEnd_ be ? ToIntegerOrInfinity(_end_).
1. If _relativeEnd_ is -∞, let _final_ be 0.
1. Else if _relativeEnd_ < 0, let _final_ be max(_len_ + _relativeEnd_, 0).
1. Else, let _final_ be min(_relativeEnd_, _len_).
1. <del>If IsDetachedBuffer(_O_.[[ViewedArrayBuffer]]) is *true*, throw a *TypeError* exception.</del>
1. <ins>Set _getBufferByteLength_ to MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. <ins>Set _len_ to IntegerIndexedObjectLength(_O_, _getBufferByteLength_).</ins>
1. <ins>If _len_ is ~out-of-bounds~, throw a *TypeError* exception.</ins>
1. <ins>Set _final_ to min(_final_, _len_).</ins>
1. Repeat, while _k_ < _final_,
1. Let _Pk_ be ! ToString(𝔽(_k_)).
1. Perform ! Set(_O_, _Pk_, _value_, *true*).
1. Set _k_ to _k_ + 1.
1. Return _O_.
</emu-alg>
</emu-clause>
<emu-clause id="sec-%typedarray%.prototype.slice">
<h1>%TypedArray%.prototype.slice ( _start_, _end_ )</h1>
<p>The interpretation and use of the arguments of %TypedArray%`.prototype.slice` are the same as for `Array.prototype.slice` as defined in <emu-xref href="#sec-array.prototype.slice"></emu-xref>. The following steps are taken:</p>
<p>This method performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? ValidateTypedArray(_O_).
1. <ins>Let _getBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _len_ be <del>_O_.[[ArrayLength]]</del><ins>IntegerIndexedObjectLength(_O_, _getBufferByteLength_)</ins>.
1. <ins>Assert: _len_ is not ~out-of-bounds~.</ins>
1. Let _relativeStart_ be ? ToIntegerOrInfinity(_start_).
1. If _relativeStart_ is -∞, let _k_ be 0.
1. Else if _relativeStart_ < 0, let _k_ be max(_len_ + _relativeStart_, 0).
1. Else, let _k_ be min(_relativeStart_, _len_).
1. If _end_ is *undefined*, let _relativeEnd_ be _len_; else let _relativeEnd_ be ? ToIntegerOrInfinity(_end_).
1. If _relativeEnd_ is -∞, let _final_ be 0.
1. Else if _relativeEnd_ < 0, let _final_ be max(_len_ + _relativeEnd_, 0).
1. Else, let _final_ be min(_relativeEnd_, _len_).
1. Let _count_ be max(_final_ - _k_, 0).
1. Let _A_ be ? TypedArraySpeciesCreate(_O_, « 𝔽(_count_) »).
1. If _count_ > 0, then
1. <del>If IsDetachedBuffer(_O_.[[ViewedArrayBuffer]]) is *true*, throw a *TypeError* exception.</del>
1. <ins>Set _getBufferByteLength_ to MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. <ins>Set _len_ to IntegerIndexedObjectLength(_O_, _getBufferByteLength_).</ins>
1. <ins>If _len_ is ~out-of-bounds~, throw a *TypeError* exception.</ins>
1. <ins>Set _final_ to min(_final_, _len_).</ins>
1. Let _srcName_ be the String value of _O_.[[TypedArrayName]].
1. Let _srcType_ be the Element Type value in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for _srcName_.
1. Let _targetName_ be the String value of _A_.[[TypedArrayName]].
1. Let _targetType_ be the Element Type value in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for _targetName_.
1. If _srcType_ is different from _targetType_, then
1. Let _n_ be 0.
1. Repeat, while _k_ < _final_,
1. Let _Pk_ be ! ToString(𝔽(_k_)).
1. Let _kValue_ be ! Get(_O_, _Pk_).
1. Perform ! Set(_A_, ! ToString(𝔽(_n_)), _kValue_, *true*).
1. Set _k_ to _k_ + 1.
1. Set _n_ to _n_ + 1.
1. Else,
1. Let _srcBuffer_ be _O_.[[ViewedArrayBuffer]].
1. Let _targetBuffer_ be _A_.[[ViewedArrayBuffer]].
1. Let _elementSize_ be the Element Size value specified in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for Element Type _srcType_.
1. NOTE: If _srcType_ and _targetType_ are the same, the transfer must be performed in a manner that preserves the bit-level encoding of the source data.
1. Let _srcByteOffset_ be _O_.[[ByteOffset]].
1. Let _targetByteIndex_ be _A_.[[ByteOffset]].
1. Let _srcByteIndex_ be (_k_ × _elementSize_) + _srcByteOffset_.
1. Let _limit_ be _targetByteIndex_ + <ins>min(</ins>_count_<ins>, _len_)</ins> × _elementSize_.
1. Repeat, while _targetByteIndex_ < _limit_,
1. Let _value_ be GetValueFromBuffer(_srcBuffer_, _srcByteIndex_, ~Uint8~, *true*, ~Unordered~).
1. Perform SetValueInBuffer(_targetBuffer_, _targetByteIndex_, ~Uint8~, _value_, *true*, ~Unordered~).
1. Set _srcByteIndex_ to _srcByteIndex_ + 1.
1. Set _targetByteIndex_ to _targetByteIndex_ + 1.
1. Return _A_.
</emu-alg>
<p>This function is not generic. The *this* value must be an object with a [[TypedArrayName]] internal slot.</p>
</emu-clause>
<emu-clause id="sec-%typedarray%.prototype.subarray">
<h1>%TypedArray%.prototype.subarray ( _begin_, _end_ )</h1>
<p>Returns a new _TypedArray_ whose element type is the same as this _TypedArray_ and whose ArrayBuffer is the same as the ArrayBuffer of this _TypedArray_, referencing the elements at _begin_, inclusive, up to _end_, exclusive. If either _begin_ or _end_ is negative, it refers to an index from the end of the array, as opposed to from the beginning.</p>
<p>This method performs the following steps when called:</p>
<emu-alg>
1. Let _O_ be the *this* value.
1. Perform ? RequireInternalSlot(_O_, [[TypedArrayName]]).
1. Assert: _O_ has a [[ViewedArrayBuffer]] internal slot.
1. Let _buffer_ be _O_.[[ViewedArrayBuffer]].
1. <ins>Let _getSrcBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _srcLength_ be <del>_O_.[[ArrayLength]]</del><ins>IntegerIndexedObjectLength(_O_, _getSrcBufferByteLength_)</ins>.
1. <ins>If _srcLength_ is ~out-of-bounds~, set _srcLength_ to 0.</ins>
1. Let _relativeBegin_ be ? ToIntegerOrInfinity(_begin_).
1. If _relativeBegin_ is -∞, let _beginIndex_ be 0.
1. Else if _relativeBegin_ < 0, let _beginIndex_ be max(_srcLength_ + _relativeBegin_, 0).
1. Else, let _beginIndex_ be min(_relativeBegin_, _srcLength_).
1. <ins>If _O_.[[ArrayLength]] is ~auto~ and _end_ is *undefined*, then</ins>
1. <ins>Let _newLength_ be *undefined*.</ins>
1. <ins>Else,</ins>
1. If _end_ is *undefined*, let _relativeEnd_ be _srcLength_; else let _relativeEnd_ be ? ToIntegerOrInfinity(_end_).
1. If _relativeEnd_ is -∞, let _endIndex_ be 0.
1. Else if _relativeEnd_ < 0, let _endIndex_ be max(_srcLength_ + _relativeEnd_, 0).
1. Else, let _endIndex_ be min(_relativeEnd_, _srcLength_).
1. Let _newLength_ be max(_endIndex_ - _beginIndex_, 0).
1. Let _constructorName_ be the String value of _O_.[[TypedArrayName]].
1. Let _elementSize_ be the Element Size value specified in <emu-xref href="#table-the-typedarray-constructors"></emu-xref> for _constructorName_.
1. Let _srcByteOffset_ be _O_.[[ByteOffset]].
1. Let _beginByteOffset_ be _srcByteOffset_ + _beginIndex_ × _elementSize_.
1. <ins>If _newLength_ is *undefined*, then</ins>
1. <ins>Let _argumentsList_ be « _buffer_, 𝔽(_beginByteOffset_) ».</ins>
1. <ins>Else,</ins>
1. Let _argumentsList_ be « _buffer_, 𝔽(_beginByteOffset_), 𝔽(_newLength_) ».
1. Return ? TypedArraySpeciesCreate(_O_, _argumentsList_).
</emu-alg>
<p>This function is not generic. The *this* value must be an object with a [[TypedArrayName]] internal slot.</p>
</emu-clause>
<emu-clause id="sec-settypedarrayfromtypedarray" type="abstract operation" oldids="sec-%typedarray%.prototype.set-typedarray-offset">
<h1>
SetTypedArrayFromTypedArray (
_target_: a TypedArray,
_targetOffset_: a non-negative integer or +∞,
_source_: a TypedArray,
): either a normal completion containing ~unused~ or a throw completion
</h1>
<dl class="header">
<dt>description</dt>
<dd>It sets multiple values in _target_, starting at index _targetOffset_, reading the values from _source_.</dd>
</dl>
<emu-alg>
1. Assert: _source_ is an Object that has a [[TypedArrayName]] internal slot.
1. Let _targetBuffer_ be _target_.[[ViewedArrayBuffer]].
1. <del>If IsDetachedBuffer(_targetBuffer_) is *true*, throw a *TypeError* exception.</del>
1. <ins>Let _getTargetBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _targetLength_ be <del>_target_.[[ArrayLength]]</del><ins>IntegerIndexedObjectLength(_target_, _getTargetBufferByteLength_)</ins>.
1. <ins>If _targetLength_ is ~out-of-bounds~, throw a *TypeError* exception.</ins>
1. Let _srcBuffer_ be _source_.[[ViewedArrayBuffer]].
1. <del>If IsDetachedBuffer(_srcBuffer_) is *true*, throw a *TypeError* exception.</del>
1. Let _targetType_ be TypedArrayElementType(_target_).
1. Let _targetElementSize_ be TypedArrayElementSize(_target_).
1. Let _targetByteOffset_ be _target_.[[ByteOffset]].
1. Let _srcType_ be TypedArrayElementType(_source_).
1. Let _srcElementSize_ be TypedArrayElementSize(_source_).
1. <ins>Let _getSrcBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _srcLength_ be <del>_source_.[[ArrayLength]]</del><ins>IntegerIndexedObjectLength(_source_, _getSrcBufferByteLength_)</ins>.
1. <ins>If _srcLength_ is ~out-of-bounds~, throw a *TypeError* exception.</ins>
1. Let _srcByteOffset_ be _source_.[[ByteOffset]].
1. If _targetOffset_ is +∞, throw a *RangeError* exception.
1. If _srcLength_ + _targetOffset_ > _targetLength_, throw a *RangeError* exception.
1. If _target_.[[ContentType]] ≠ _source_.[[ContentType]], throw a *TypeError* exception.
1. If both IsSharedArrayBuffer(_srcBuffer_) and IsSharedArrayBuffer(_targetBuffer_) are *true*, then
1. If _srcBuffer_.[[ArrayBufferData]] and _targetBuffer_.[[ArrayBufferData]] are the same Shared Data Block values, let _same_ be *true*; else let _same_ be *false*.
1. Else, let _same_ be SameValue(_srcBuffer_, _targetBuffer_).
1. If _same_ is *true*, then
1. Let _srcByteLength_ be <del>_source_.[[ByteLength]]</del><ins>IntegerIndexedObjectByteLength(_source_, _getSrcBufferByteLength_)</ins>.
1. Set _srcBuffer_ to ? CloneArrayBuffer(_srcBuffer_, _srcByteOffset_, _srcByteLength_).
1. Let _srcByteIndex_ be 0.
1. Else, let _srcByteIndex_ be _srcByteOffset_.
1. Let _targetByteIndex_ be _targetOffset_ × _targetElementSize_ + _targetByteOffset_.
1. Let _limit_ be _targetByteIndex_ + _targetElementSize_ × _srcLength_.
1. If _srcType_ is the same as _targetType_, then
1. NOTE: If _srcType_ and _targetType_ are the same, the transfer must be performed in a manner that preserves the bit-level encoding of the source data.
1. Repeat, while _targetByteIndex_ < _limit_,
1. Let _value_ be GetValueFromBuffer(_srcBuffer_, _srcByteIndex_, ~Uint8~, *true*, ~Unordered~).
1. Perform SetValueInBuffer(_targetBuffer_, _targetByteIndex_, ~Uint8~, _value_, *true*, ~Unordered~).
1. Set _srcByteIndex_ to _srcByteIndex_ + 1.
1. Set _targetByteIndex_ to _targetByteIndex_ + 1.
1. Else,
1. Repeat, while _targetByteIndex_ < _limit_,
1. Let _value_ be GetValueFromBuffer(_srcBuffer_, _srcByteIndex_, _srcType_, *true*, ~Unordered~).
1. Perform SetValueInBuffer(_targetBuffer_, _targetByteIndex_, _targetType_, _value_, *true*, ~Unordered~).
1. Set _srcByteIndex_ to _srcByteIndex_ + _srcElementSize_.
1. Set _targetByteIndex_ to _targetByteIndex_ + _targetElementSize_.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-typedarray-constructors-mods">
<h1>Modifications to the _TypedArray_ Constructors</h1>
<emu-clause id="sec-initializetypedarrayfromtypedarray" type="abstract operation" oldids="sec-typedarray-typedarray">
<h1>
InitializeTypedArrayFromTypedArray (
_O_: a TypedArray,
_srcArray_: a TypedArray,
): either a normal completion containing ~unused~ or a throw completion
</h1>
<dl class="header">
</dl>
<emu-alg>
1. Let _srcData_ be _srcArray_.[[ViewedArrayBuffer]].
1. <del>If IsDetachedBuffer(_srcData_) is *true*, throw a *TypeError* exception.</del>
1. Let _elementType_ be TypedArrayElementType(_O_).
1. Let _elementSize_ be TypedArrayElementSize(_O_).
1. <ins>Let _getSrcBufferByteLength_ be MakeIdempotentArrayBufferByteLengthGetter(~SeqCst~).</ins>
1. Let _elementLength_ be <del>_srcArray_.[[ArrayLength]]</del><ins>IntegerIndexedObjectLength(_srcArray_, _getSrcBufferByteLength_)</ins>.
1. <ins>If _elementLength_ is ~out-of-bounds~, throw a *TypeError* exception.</ins>
1. Let _srcType_ be TypedArrayElementType(_srcArray_).
1. Let _srcElementSize_ be TypedArrayElementSize(_srcArray_).
1. Let _srcByteOffset_ be _srcArray_.[[ByteOffset]].
1. Let _byteLength_ be _elementSize_ × _elementLength_.
1. If _elementType_ is the same as _srcType_, then
1. Let _data_ be ? CloneArrayBuffer(_srcData_, _srcByteOffset_, _byteLength_).
1. Else,
1. Let _data_ be ? <emu-meta suppress-effects="user-code">AllocateArrayBuffer(%ArrayBuffer%, _byteLength_)</emu-meta>.
1. If _srcArray_.[[ContentType]] ≠ _O_.[[ContentType]], throw a *TypeError* exception.
1. Let _srcByteIndex_ be _srcByteOffset_.
1. Let _targetByteIndex_ be 0.
1. Let _count_ be _elementLength_.
1. Repeat, while _count_ > 0,
1. Let _value_ be GetValueFromBuffer(_srcData_, _srcByteIndex_, _srcType_, *true*, ~Unordered~).
1. Perform SetValueInBuffer(_data_, _targetByteIndex_, _elementType_, _value_, *true*, ~Unordered~).
1. Set _srcByteIndex_ to _srcByteIndex_ + _srcElementSize_.
1. Set _targetByteIndex_ to _targetByteIndex_ + _elementSize_.
1. Set _count_ to _count_ - 1.
1. Set _O_.[[ViewedArrayBuffer]] to _data_.
1. Set _O_.[[ByteLength]] to _byteLength_.
1. Set _O_.[[ByteOffset]] to 0.
1. Set _O_.[[ArrayLength]] to _elementLength_.
1. Return ~unused~.
</emu-alg>
</emu-clause>
<emu-clause id="sec-initializetypedarrayfromarraybuffer" type="abstract operation" oldids="sec-typedarray-buffer-byteoffset-length">