You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+4-5Lines changed: 4 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,10 +53,9 @@ Exactly how to implement the subsequence search algorithm is intended to be left
53
53
54
54
The `needle` argument can be:
55
55
56
-
* A **TypedArray of the same element type** as the haystack — its element values are extracted directly.
57
-
* A **different-type TypedArray** — coerced via its `@@iterator` method, with each element converted to the haystack's element type (just like any other iterable).
58
-
* An **iterable object** (other than a String) — its elements are collected and converted to the haystack's element type, then searched for.
59
-
* A **String** — throws a `TypeError`. Although strings are iterable, their iteration yields code points, which is unlikely to be the intended behavior when searching a TypedArray.
56
+
* A **TypedArray** (same or different element type) — iterated via its `@@iterator` method. Each yielded value must be the correct type for the haystack (Number for non-BigInt TypedArrays, BigInt for BigInt TypedArrays); if any value is the wrong type, the search returns `-1`. This creates a snapshot of the needle's elements, which is necessary for correctness when the needle is backed by a SharedArrayBuffer.
57
+
* An **iterable object** (other than a String) — its elements are collected and type-checked against the haystack's element type. If any element is the wrong type, the search returns `-1`.
58
+
* A **String** — throws a `TypeError`. Although strings are iterable, their iteration yields code points, which is unlikely to be the intended behaviour when searching a TypedArray.
): either a normal completion containing either a List of Numbers or a List of BigInts, or a throw completion
48
-
</h1>
49
-
<dl class="header">
50
-
<dt>description</dt>
51
-
<dd>It iterates _iterable_ using _iteratorMethod_ and coerces each element to the appropriate numeric type for _elementType_, returning the results as a List.</dd>
52
-
</dl>
53
-
<emu-alg>
54
-
1. Let _values_ be ? IteratorToList(? GetIteratorFromMethod(_iterable_, _iteratorMethod_)).
55
-
1. Let _result_ be a new empty List.
56
-
1. For each element _v_ of _values_, do
57
-
1. If IsBigIntElementType(_elementType_) is *true*, let _numValue_ be ? ToBigInt(_v_).
): either a normal completion containing either a TypedArray, a List of Numbers, or a List of BigInts, or a throw completion
69
+
): either a normal completion containing either a List of Numbers, a List of BigInts, or ~not-found~, or a throw completion
93
70
</h1>
94
71
<dl class="header">
95
72
<dt>description</dt>
96
-
<dd>It produces a sequence of element values compatible with _O_ from _needle_. If _needle_ is a same-type TypedArray, it is returned directly. If _needle_ is an iterable Object, its elements are collected, coerced to the element type of _O_, and returned as a List. Non-Object values (including Strings, which would otherwise be boxed into iterable String objects) and non-iterable Objects throw a *TypeError*.</dd>
73
+
<dd>It produces a List of element values compatible with _O_ from _needle_. If _needle_ is an iterable Object, its elements are collected and validated against the element type of _O_. If any element is not the expected type, ~not-found~ is returned. Non-Object values (including Strings, which would otherwise be boxed into iterable String objects) and non-iterable Objects throw a *TypeError*.</dd>
97
74
</dl>
98
75
<emu-alg>
99
-
1. If _needle_ is an Object, then
100
-
1. If _needle_ has a [[TypedArrayName]] internal slot and TypedArrayElementType(_O_) is TypedArrayElementType(_needle_), return _needle_.
101
-
1. Let _iteratorMethod_ be ? GetMethod(_needle_, @@iterator).
102
-
1. If _iteratorMethod_ is not *undefined*, return ? IterableToTypedArrayElementList(_needle_, _iteratorMethod_, TypedArrayElementType(_O_)).
103
-
1. Throw a *TypeError* exception.
104
-
1. Else,
105
-
1. Throw a *TypeError* exception.
76
+
1. If _needle_ is not an Object, throw a *TypeError* exception.
77
+
1. Let _iteratorMethod_ be ? GetMethod(_needle_, @@iterator).
78
+
1. If _iteratorMethod_ is *undefined*, throw a *TypeError* exception.
79
+
1. Let _values_ be ? IteratorToList(? GetIteratorFromMethod(_needle_, _iteratorMethod_)).
80
+
1. Let _elementType_ be TypedArrayElementType(_O_).
81
+
1. Let _result_ be a new empty List.
82
+
1. For each element _v_ of _values_, do
83
+
1. If IsBigIntElementType(_elementType_) is *true*, then
84
+
1. If _v_ is not a BigInt, return ~not-found~.
85
+
1. Else,
86
+
1. If _v_ is not a Number, return ~not-found~.
87
+
1. Append _v_ to _result_.
88
+
1. Return _result_.
106
89
</emu-alg>
107
90
<emu-note>
108
-
<p>When _needle_ is a same-type TypedArray, it is returned directly. A different-type TypedArray is coerced via its @@iterator method like any other iterable, with each element converted to the element type of _O_.</p>
91
+
<p>All TypedArray needles (whether same-type or different-type) are iterated via their @@iterator method. This ensures that the resulting List is a snapshot of the needle's elements at the time of the call, which is necessary for correctness when the needle is backed by a SharedArrayBuffer (see <a href="https://github.com/tc39/proposal-typedarray-findwithin/issues/8">issue #8</a>).</p>
92
+
<p>If the iterable yields values of the wrong type (e.g., BigInts when the haystack is a non-BigInt TypedArray, or Numbers when it is a BigInt TypedArray), ~not-found~ is returned rather than throwing. Such values can never SameValueZero-match any element of the haystack, so returning ~not-found~ (which callers interpret as *-1*<sub>𝔽</sub>) is the correct result without the cost of performing the search. Alternatively we could
93
+
throw a TypeError in these cases.</p>
109
94
</emu-note>
110
95
<emu-note type="editor">
111
-
<p>The acceptance of iterable objects as needles is intended to improve ergonomics (see <a href="https://github.com/tc39/proposal-typedarray-findwithin/issues/1">issue #1</a>). String primitives are not Objects and so fall through to the *TypeError* in the final step. Non-iterable objects and non-String primitives also throw to avoid silent misuse (see <a href="https://github.com/tc39/proposal-typedarray-findwithin/issues/7">issue #7</a>).</p>
96
+
<p>The acceptance of iterable objects as needles is intended to improve ergonomics (see <a href="https://github.com/tc39/proposal-typedarray-findwithin/issues/1">issue #1</a>). String primitives are not Objects and so fall through to the *TypeError* in the first step. Non-iterable objects and non-String primitives also throw to avoid silent misuse (see <a href="https://github.com/tc39/proposal-typedarray-findwithin/issues/7">issue #7</a>).</p>
112
97
</emu-note>
113
98
</emu-clause>
114
99
@@ -117,7 +102,7 @@ contributors: James M Snell
117
102
TypedArraySearchSubsequence (
118
103
_O_: a TypedArray,
119
104
_haystackLength_: a non-negative integer,
120
-
_needle_: either a TypedArray, a List of Numbers, or a List of BigInts,
105
+
_needle_: either a List of Numbers or a List of BigInts,
121
106
_direction_: ~first~ or ~last~,
122
107
_position_: a non-negative integer,
123
108
): an integral Number
@@ -136,12 +121,9 @@ contributors: James M Snell
136
121
1. If _needleLength_ > _haystackLength_, return *-1*<sub>𝔽</sub>.
137
122
1. [id="step-search-last"] Return the largest integer _k_ such that _k_ ≤ _position_ and _k_ + _needleLength_ ≤ _haystackLength_ and SequenceSameValueZeroEqual(the List of elements of _O_ from index _k_ to _k_ + _needleLength_ - 1, _needle_) is *true*, or *-1*<sub>𝔽</sub> if no such _k_ exists.
138
123
</emu-alg>
139
-
<emu-note type="editor">
140
-
<p>The description of the subsequence search in <emu-xref href="#step-search-first"></emu-xref> and <emu-xref href="#step-search-last"></emu-xref> is intentionally high-level, allowing implementations freedom in how the search is performed. A question for committee is whether these steps need to be specified more precisely with explicit algorithmic substeps (e.g., element-by-element comparison with specific iteration order), even if implementations are expected to use optimized approaches such as Boyer-Moore or other string matching algorithms.</p>
141
-
</emu-note>
142
124
<emu-note>
143
-
<p>The _needle_ is produced by CoerceToCompatibleTypedArrayElementList, which ensures element values are compatible with the element type of _O_. When _needle_ is a same-type TypedArray, it qualifies as a List of Numbers or a List of BigInts for the purposes of SequenceSameValueZeroEqual. Subsequence equality is determined by SequenceSameValueZeroEqual.</p>
144
-
<p>Implementations may use any technique to search for the subsequence, such as naive search, Boyer-Moore, or other string matching algorithms, provided the observable result is correct.</p>
125
+
<p>The _needle_ is produced by ToCompatibleTypedArrayElementList, which validates that element values are the correct type for _O_ and are a snapshot that cannot be modified during the search. The elements of _O_ (the haystack) are not snapshotted, consistent with how %TypedArray%.prototype.indexOf and %TypedArray%.prototype.lastIndexOf scan the haystack directly. When _O_ is backed by a SharedArrayBuffer, another agent may modify elements of _O_ during the search.</p>
126
+
<p>Implementations may use any technique to search for the subsequence, such as naive search, Boyer-Moore, or other matching algorithms, provided the observable result is correct.</p>
145
127
</emu-note>
146
128
</emu-clause>
147
129
</emu-clause>
@@ -155,11 +137,12 @@ contributors: James M Snell
155
137
<emu-alg>
156
138
1. Let _O_ be the *this* value.
157
139
1. Let _taRecord_ be ? ValidateTypedArray(_O_, ~seq-cst~).
158
-
1. Let _coerced_ be ? CoerceToCompatibleTypedArrayElementList(_O_, _needle_).
140
+
1. Let _needleList_ be ? ToCompatibleTypedArrayElementList(_O_, _needle_).
141
+
1. If _needleList_ is ~not-found~, return *-1*<sub>𝔽</sub>.
159
142
1. Let _haystackLength_ be TypedArrayLength(_taRecord_).
160
-
1. Let _n_ be ? ValidateIntegralNumberOffset(_position_, 0).
143
+
1. Let _n_ be ? ValidateIntegralNumber(_position_, 0).
161
144
1. Let _startFrom_ be the result of clamping _n_ between 0 and _haystackLength_.
0 commit comments