Skip to content

Commit f48f3c9

Browse files
MaxGraeydcodeIO
authored andcommitted
Add TypedArray#includes/indexOf/lastIndexOf (AssemblyScript#660)
1 parent a4e5857 commit f48f3c9

File tree

7 files changed

+15635
-2041
lines changed

7 files changed

+15635
-2041
lines changed

std/assembly/index.d.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,18 +1115,18 @@ declare abstract class TypedArray<T> implements ArrayBufferView<T> {
11151115
readonly byteLength: i32;
11161116
/** The length (in elements). */
11171117
readonly length: i32;
1118+
/** The includes() method determines whether a typed array includes a certain element, returning true or false as appropriate. */
1119+
includes(searchElement: T, fromIndex?: i32): bool;
1120+
/** The indexOf() method returns the first index at which a given element can be found in the typed array, or -1 if it is not present. */
1121+
indexOf(searchElement: T, fromIndex?: i32): i32;
1122+
/** The lastIndexOf() method returns the last index at which a given element can be found in the typed array, or -1 if it is not present. The typed array is searched backwards, starting at fromIndex. */
1123+
lastIndexOf(searchElement: T, fromIndex?: i32): i32;
11181124
/** Returns a new TypedArray of this type on the same ArrayBuffer from begin inclusive to end exclusive. */
11191125
subarray(begin?: i32, end?: i32): this;
11201126
/** The reduce() method applies a function against an accumulator and each value of the typed array (from left-to-right) has to reduce it to a single value. This method has the same algorithm as Array.prototype.reduce(). */
1121-
reduce<W>(
1122-
callbackfn: (accumulator: W, value: T, index: i32, self: this) => W,
1123-
initialValue: W,
1124-
): W;
1127+
reduce<W>(callbackfn: (accumulator: W, value: T, index: i32, self: this) => W, initialValue: W): W;
11251128
/** The reduceRight() method applies a function against an accumulator and each value of the typed array (from left-to-right) has to reduce it to a single value, starting from the end of the array. This method has the same algorithm as Array.prototype.reduceRight(). */
1126-
reduceRight<W>(
1127-
callbackfn: (accumulator: W, value: T, index: i32, self: this) => W,
1128-
initialValue: W,
1129-
): W;
1129+
reduceRight<W>(callbackfn: (accumulator: W, value: T, index: i32, self: this) => W, initialValue: W): W;
11301130
/** The some() method tests whether some element in the typed array passes the test implemented by the provided function. This method has the same algorithm as Array.prototype.some().*/
11311131
some(callbackfn: (value: T, index: i32, self: this) => bool): bool;
11321132
/** The map() method creates a new typed array with the results of calling a provided function on every element in this typed array. This method has the same algorithm as Array.prototype.map().*/

std/assembly/typedarray.ts

Lines changed: 184 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ export class Int8Array extends ArrayBufferView {
3434
store<i8>(this.dataStart + <usize>index, value);
3535
}
3636

37+
includes(searchElement: i8, fromIndex: i32 = 0): bool {
38+
return INCLUDES<Int8Array, i8>(this, searchElement, fromIndex);
39+
}
40+
41+
indexOf(searchElement: i8, fromIndex: i32 = 0): i32 {
42+
return INDEX_OF<Int8Array, i8>(this, searchElement, fromIndex);
43+
}
44+
45+
lastIndexOf(searchElement: i8, fromIndex: i32 = this.length): i32 {
46+
return LAST_INDEX_OF<Int8Array, i8>(this, searchElement, fromIndex);
47+
}
48+
3749
fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array {
3850
return FILL<Int8Array, i8>(this, value, start, end);
3951
}
@@ -116,6 +128,18 @@ export class Uint8Array extends ArrayBufferView {
116128
store<u8>(this.dataStart + <usize>index, value);
117129
}
118130

131+
includes(searchElement: u8, fromIndex: i32 = 0): bool {
132+
return INCLUDES<Uint8Array, u8>(this, searchElement, fromIndex);
133+
}
134+
135+
indexOf(searchElement: u8, fromIndex: i32 = 0): i32 {
136+
return INDEX_OF<Uint8Array, u8>(this, searchElement, fromIndex);
137+
}
138+
139+
lastIndexOf(searchElement: u8, fromIndex: i32 = this.length): i32 {
140+
return LAST_INDEX_OF<Uint8Array, u8>(this, searchElement, fromIndex);
141+
}
142+
119143
fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array {
120144
return FILL<Uint8Array, u8>(this, value, start, end);
121145
}
@@ -198,6 +222,18 @@ export class Uint8ClampedArray extends ArrayBufferView {
198222
store<u8>(this.dataStart + <usize>index, ~(<i32>value >> 31) & (((255 - value) >> 31) | value));
199223
}
200224

225+
includes(searchElement: u8, fromIndex: i32 = 0): bool {
226+
return INCLUDES<Uint8ClampedArray, u8>(this, searchElement, fromIndex);
227+
}
228+
229+
indexOf(searchElement: u8, fromIndex: i32 = 0): i32 {
230+
return INDEX_OF<Uint8ClampedArray, u8>(this, searchElement, fromIndex);
231+
}
232+
233+
lastIndexOf(searchElement: u8, fromIndex: i32 = this.length): i32 {
234+
return LAST_INDEX_OF<Uint8ClampedArray, u8>(this, searchElement, fromIndex);
235+
}
236+
201237
fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray {
202238
return FILL<Uint8ClampedArray, u8>(this, value, start, end);
203239
}
@@ -280,6 +316,18 @@ export class Int16Array extends ArrayBufferView {
280316
store<i16>(this.dataStart + (<usize>index << alignof<i16>()), value);
281317
}
282318

319+
includes(searchElement: i16, fromIndex: i32 = 0): bool {
320+
return INCLUDES<Int16Array, i16>(this, searchElement, fromIndex);
321+
}
322+
323+
indexOf(searchElement: i16, fromIndex: i32 = 0): i32 {
324+
return INDEX_OF<Int16Array, i16>(this, searchElement, fromIndex);
325+
}
326+
327+
lastIndexOf(searchElement: i16, fromIndex: i32 = this.length): i32 {
328+
return LAST_INDEX_OF<Int16Array, i16>(this, searchElement, fromIndex);
329+
}
330+
283331
fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array {
284332
return FILL<Int16Array, i16>(this, value, start, end);
285333
}
@@ -362,6 +410,18 @@ export class Uint16Array extends ArrayBufferView {
362410
store<u16>(this.dataStart + (<usize>index << alignof<u16>()), value);
363411
}
364412

413+
includes(searchElement: u16, fromIndex: i32 = 0): bool {
414+
return INCLUDES<Uint16Array, u16>(this, searchElement, fromIndex);
415+
}
416+
417+
indexOf(searchElement: u16, fromIndex: i32 = 0): i32 {
418+
return INDEX_OF<Uint16Array, u16>(this, searchElement, fromIndex);
419+
}
420+
421+
lastIndexOf(searchElement: u16, fromIndex: i32 = this.length): i32 {
422+
return LAST_INDEX_OF<Uint16Array, u16>(this, searchElement, fromIndex);
423+
}
424+
365425
fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array {
366426
return FILL<Uint16Array, u16>(this, value, start, end);
367427
}
@@ -444,6 +504,18 @@ export class Int32Array extends ArrayBufferView {
444504
store<i32>(this.dataStart + (<usize>index << alignof<i32>()), value);
445505
}
446506

507+
includes(searchElement: i32, fromIndex: i32 = 0): bool {
508+
return INCLUDES<Int32Array, i32>(this, searchElement, fromIndex);
509+
}
510+
511+
indexOf(searchElement: i32, fromIndex: i32 = 0): i32 {
512+
return INDEX_OF<Int32Array, i32>(this, searchElement, fromIndex);
513+
}
514+
515+
lastIndexOf(searchElement: i32, fromIndex: i32 = this.length): i32 {
516+
return LAST_INDEX_OF<Int32Array, i32>(this, searchElement, fromIndex);
517+
}
518+
447519
fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array {
448520
return FILL<Int32Array, i32>(this, value, start, end);
449521
}
@@ -526,6 +598,18 @@ export class Uint32Array extends ArrayBufferView {
526598
store<u32>(this.dataStart + (<usize>index << alignof<u32>()), value);
527599
}
528600

601+
includes(searchElement: u32, fromIndex: i32 = 0): bool {
602+
return INCLUDES<Uint32Array, u32>(this, searchElement, fromIndex);
603+
}
604+
605+
indexOf(searchElement: u32, fromIndex: i32 = 0): i32 {
606+
return INDEX_OF<Uint32Array, u32>(this, searchElement, fromIndex);
607+
}
608+
609+
lastIndexOf(searchElement: u32, fromIndex: i32 = this.length): i32 {
610+
return LAST_INDEX_OF<Uint32Array, u32>(this, searchElement, fromIndex);
611+
}
612+
529613
fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array {
530614
return FILL<Uint32Array, u32>(this, value, start, end);
531615
}
@@ -608,6 +692,18 @@ export class Int64Array extends ArrayBufferView {
608692
store<i64>(this.dataStart + (<usize>index << alignof<i64>()), value);
609693
}
610694

695+
includes(searchElement: i64, fromIndex: i32 = 0): bool {
696+
return INCLUDES<Int64Array, i64>(this, searchElement, fromIndex);
697+
}
698+
699+
indexOf(searchElement: i64, fromIndex: i32 = 0): i32 {
700+
return INDEX_OF<Int64Array, i64>(this, searchElement, fromIndex);
701+
}
702+
703+
lastIndexOf(searchElement: i64, fromIndex: i32 = this.length): i32 {
704+
return LAST_INDEX_OF<Int64Array, i64>(this, searchElement, fromIndex);
705+
}
706+
611707
fill(value: i64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array {
612708
return FILL<Int64Array, i64>(this, value, start, end);
613709
}
@@ -690,6 +786,18 @@ export class Uint64Array extends ArrayBufferView {
690786
store<u64>(this.dataStart + (<usize>index << alignof<u64>()), value);
691787
}
692788

789+
includes(searchElement: u64, fromIndex: i32 = 0): bool {
790+
return INCLUDES<Uint64Array, u64>(this, searchElement, fromIndex);
791+
}
792+
793+
indexOf(searchElement: u64, fromIndex: i32 = 0): i32 {
794+
return INDEX_OF<Uint64Array, u64>(this, searchElement, fromIndex);
795+
}
796+
797+
lastIndexOf(searchElement: u64, fromIndex: i32 = this.length): i32 {
798+
return LAST_INDEX_OF<Uint64Array, u64>(this, searchElement, fromIndex);
799+
}
800+
693801
fill(value: u64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array {
694802
return FILL<Uint64Array, u64>(this, value, start, end);
695803
}
@@ -772,6 +880,18 @@ export class Float32Array extends ArrayBufferView {
772880
store<f32>(this.dataStart + (<usize>index << alignof<f32>()), value);
773881
}
774882

883+
includes(searchElement: f32, fromIndex: i32 = 0): bool {
884+
return INCLUDES<Float32Array, f32>(this, searchElement, fromIndex);
885+
}
886+
887+
indexOf(searchElement: f32, fromIndex: i32 = 0): i32 {
888+
return INDEX_OF<Float32Array, f32>(this, searchElement, fromIndex);
889+
}
890+
891+
lastIndexOf(searchElement: f32, fromIndex: i32 = this.length): i32 {
892+
return LAST_INDEX_OF<Float32Array, f32>(this, searchElement, fromIndex);
893+
}
894+
775895
fill(value: f32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array {
776896
return FILL<Float32Array, f32>(this, value, start, end);
777897
}
@@ -854,6 +974,18 @@ export class Float64Array extends ArrayBufferView {
854974
store<f64>(this.dataStart + (<usize>index << alignof<f64>()), value);
855975
}
856976

977+
includes(searchElement: f64, fromIndex: i32 = 0): bool {
978+
return INCLUDES<Float64Array, f64>(this, searchElement, fromIndex);
979+
}
980+
981+
indexOf(searchElement: f64, fromIndex: i32 = 0): i32 {
982+
return INDEX_OF<Float64Array, f64>(this, searchElement, fromIndex);
983+
}
984+
985+
lastIndexOf(searchElement: f64, fromIndex: i32 = this.length): i32 {
986+
return LAST_INDEX_OF<Float64Array, f64>(this, searchElement, fromIndex);
987+
}
988+
857989
fill(value: f64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array {
858990
return FILL<Float64Array, f64>(this, value, start, end);
859991
}
@@ -1027,6 +1159,55 @@ function FIND_INDEX<TArray extends ArrayBufferView, T>(
10271159
return -1;
10281160
}
10291161

1162+
// @ts-ignore: decorator
1163+
@inline
1164+
function INCLUDES<TArray extends ArrayBufferView, T>(
1165+
array: TArray,
1166+
searchElement: T,
1167+
fromIndex: i32,
1168+
): bool {
1169+
return INDEX_OF<TArray, T>(array, searchElement, fromIndex) >= 0;
1170+
}
1171+
1172+
// @ts-ignore: decorator
1173+
@inline
1174+
function INDEX_OF<TArray extends ArrayBufferView, T>(
1175+
array: TArray,
1176+
searchElement: T,
1177+
fromIndex: i32,
1178+
): i32 {
1179+
var index: isize = fromIndex;
1180+
var length: isize = array.length;
1181+
if (length == 0 || index >= length) return -1;
1182+
if (index < 0) index = max(length + index, 0);
1183+
var dataStart = array.dataStart;
1184+
while (index < length) {
1185+
if (load<T>(dataStart + (index << alignof<T>())) == searchElement) return <i32>index;
1186+
++index;
1187+
}
1188+
return -1;
1189+
}
1190+
1191+
// @ts-ignore: decorator
1192+
@inline
1193+
function LAST_INDEX_OF<TArray extends ArrayBufferView, T>(
1194+
array: TArray,
1195+
searchElement: T,
1196+
fromIndex: i32,
1197+
): i32 {
1198+
var index: isize = fromIndex;
1199+
var length: isize = array.length;
1200+
if (length == 0) return -1;
1201+
if (index < 0) index = length + index; // no need to clamp
1202+
else if (index >= length) index = length - 1;
1203+
var dataStart = array.dataStart;
1204+
while (index >= 0) {
1205+
if (load<T>(dataStart + (index << alignof<T>())) == searchElement) return <i32>index;
1206+
--index;
1207+
}
1208+
return -1;
1209+
}
1210+
10301211
// @ts-ignore: decorator
10311212
@inline
10321213
function SOME<TArray extends ArrayBufferView, T>(
@@ -1070,9 +1251,9 @@ function FOREACH<TArray extends ArrayBufferView, T>(
10701251
@inline
10711252
export function REVERSE<TArray extends ArrayBufferView, T>(array: TArray): TArray {
10721253
var dataStart = array.dataStart;
1073-
for (let front = 0, back = array.length - 1; front < back; ++front, --back) {
1074-
let frontPtr = dataStart + (<usize>front << alignof<T>());
1075-
let backPtr = dataStart + (<usize>back << alignof<T>());
1254+
for (let front: usize = 0, back: usize = array.length - 1; front < back; ++front, --back) {
1255+
let frontPtr = dataStart + (front << alignof<T>());
1256+
let backPtr = dataStart + (back << alignof<T>());
10761257
let temp = load<T>(frontPtr);
10771258
store<T>(frontPtr, load<T>(backPtr));
10781259
store<T>(backPtr, temp);

tests/compiler/std/dataview.optimized.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,7 @@
16091609
if
16101610
i32.const 280
16111611
i32.const 376
1612-
i32.const 115
1612+
i32.const 127
16131613
i32.const 44
16141614
call $~lib/builtins/abort
16151615
unreachable

tests/compiler/std/dataview.untouched.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3302,7 +3302,7 @@
33023302
if
33033303
i32.const 280
33043304
i32.const 376
3305-
i32.const 115
3305+
i32.const 127
33063306
i32.const 44
33073307
call $~lib/builtins/abort
33083308
unreachable

0 commit comments

Comments
 (0)