Skip to content

Commit 3f34964

Browse files
MaxGraeydcodeIO
authored andcommitted
Sync Array/TypedArray#includes with spec if there's a NaN (AssemblyScript#931)
1 parent 6ef1f75 commit 3f34964

13 files changed

+3459
-2190
lines changed

std/assembly/array.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,21 @@ export class Array<T> extends ArrayBufferView {
153153
}
154154

155155
includes(value: T, fromIndex: i32 = 0): bool {
156-
return this.indexOf(value, fromIndex) >= 0;
156+
if (isFloat<T>()) {
157+
let length = this.length_;
158+
if (length == 0 || fromIndex >= length) return false;
159+
if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);
160+
let dataStart = this.dataStart;
161+
while (fromIndex < length) {
162+
let elem = load<T>(dataStart + (<usize>fromIndex << alignof<T>()));
163+
// @ts-ignore
164+
if (elem == value || isNaN(elem) & isNaN(value)) return true;
165+
++fromIndex;
166+
}
167+
return false;
168+
} else {
169+
return this.indexOf(value, fromIndex) >= 0;
170+
}
157171
}
158172

159173
indexOf(value: T, fromIndex: i32 = 0): i32 {

std/assembly/dataview.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class DataView {
4545
getFloat64(byteOffset: i32, littleEndian: boolean = false): f64 {
4646
if (
4747
(byteOffset >>> 31) | i32(byteOffset + 8 > this.byteLength)
48-
) throw new RangeError(E_INDEXOUTOFRANGE);
48+
) throw new RangeError(E_INDEXOUTOFRANGE);
4949
return littleEndian
5050
? load<f64>(this.dataStart + <usize>byteOffset)
5151
: reinterpret<f64>(
@@ -63,15 +63,15 @@ export class DataView {
6363
getInt16(byteOffset: i32, littleEndian: boolean = false): i16 {
6464
if (
6565
(byteOffset >>> 31) | i32(byteOffset + 2 > this.byteLength)
66-
) throw new RangeError(E_INDEXOUTOFRANGE);
66+
) throw new RangeError(E_INDEXOUTOFRANGE);
6767
var result: i16 = load<i16>(this.dataStart + <usize>byteOffset);
6868
return littleEndian ? result : bswap<i16>(result);
6969
}
7070

7171
getInt32(byteOffset: i32, littleEndian: boolean = false): i32 {
7272
if (
7373
(byteOffset >>> 31) | i32(byteOffset + 4 > this.byteLength)
74-
) throw new RangeError(E_INDEXOUTOFRANGE);
74+
) throw new RangeError(E_INDEXOUTOFRANGE);
7575
var result: i32 = load<i32>(this.dataStart + <usize>byteOffset);
7676
return littleEndian ? result : bswap<i32>(result);
7777
}

std/assembly/typedarray.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1577,7 +1577,22 @@ function INCLUDES<TArray extends ArrayBufferView, T>(
15771577
searchElement: T,
15781578
fromIndex: i32,
15791579
): bool {
1580-
return INDEX_OF<TArray, T>(array, searchElement, fromIndex) >= 0;
1580+
if (isFloat<T>()) {
1581+
let index: isize = fromIndex;
1582+
let length: isize = array.length;
1583+
if (length == 0 || index >= length) return false;
1584+
if (index < 0) index = max(length + index, 0);
1585+
let dataStart = array.dataStart;
1586+
while (index < length) {
1587+
let elem = load<T>(dataStart + (index << alignof<T>()));
1588+
// @ts-ignore
1589+
if (elem == searchElement || isNaN(elem) & isNaN(searchElement)) return true;
1590+
++index;
1591+
}
1592+
return false;
1593+
} else {
1594+
return INDEX_OF<TArray, T>(array, searchElement, fromIndex) >= 0;
1595+
}
15811596
}
15821597

15831598
// @ts-ignore: decorator

tests/compiler/retain-release-sanity.optimized.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2298,7 +2298,7 @@
22982298
if
22992299
i32.const 424
23002300
i32.const 376
2301-
i32.const 271
2301+
i32.const 285
23022302
i32.const 20
23032303
call $~lib/builtins/abort
23042304
unreachable

tests/compiler/retain-release-sanity.untouched.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3909,7 +3909,7 @@
39093909
if
39103910
i32.const 424
39113911
i32.const 376
3912-
i32.const 271
3912+
i32.const 285
39133913
i32.const 20
39143914
call $~lib/builtins/abort
39153915
unreachable

tests/compiler/std/array.optimized.wat

Lines changed: 1029 additions & 731 deletions
Large diffs are not rendered by default.

tests/compiler/std/array.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ var i: i32;
302302

303303
i = arr.indexOf(43, 2);
304304
assert(i == 3);
305+
306+
assert(([NaN] as f32[]).indexOf(NaN) == -1);
307+
assert(([NaN] as f64[]).indexOf(NaN) == -1);
305308
}
306309

307310
// Array#includes //////////////////////////////////////////////////////////////////////////////////
@@ -337,6 +340,9 @@ var i: i32;
337340
includes = arr.includes(43, 2);
338341
assert(includes == true);
339342

343+
assert(([NaN] as f32[]).includes(NaN));
344+
assert(([NaN] as f64[]).includes(NaN));
345+
340346
arr.splice(1, 1);
341347

342348
assert(arr.length == 4);

tests/compiler/std/array.untouched.wat

Lines changed: 1362 additions & 963 deletions
Large diffs are not rendered by default.

tests/compiler/std/dataview.optimized.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,7 +2059,7 @@
20592059
i32.const 280
20602060
i32.const 432
20612061
i32.const 48
2062-
i32.const 7
2062+
i32.const 6
20632063
call $~lib/builtins/abort
20642064
unreachable
20652065
end
@@ -2123,7 +2123,7 @@
21232123
i32.const 280
21242124
i32.const 432
21252125
i32.const 66
2126-
i32.const 7
2126+
i32.const 6
21272127
call $~lib/builtins/abort
21282128
unreachable
21292129
end
@@ -2157,7 +2157,7 @@
21572157
i32.const 280
21582158
i32.const 432
21592159
i32.const 74
2160-
i32.const 7
2160+
i32.const 6
21612161
call $~lib/builtins/abort
21622162
unreachable
21632163
end

tests/compiler/std/dataview.untouched.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3841,7 +3841,7 @@
38413841
i32.const 280
38423842
i32.const 432
38433843
i32.const 48
3844-
i32.const 7
3844+
i32.const 6
38453845
call $~lib/builtins/abort
38463846
unreachable
38473847
end
@@ -3913,7 +3913,7 @@
39133913
i32.const 280
39143914
i32.const 432
39153915
i32.const 66
3916-
i32.const 7
3916+
i32.const 6
39173917
call $~lib/builtins/abort
39183918
unreachable
39193919
end
@@ -3961,7 +3961,7 @@
39613961
i32.const 280
39623962
i32.const 432
39633963
i32.const 74
3964-
i32.const 7
3964+
i32.const 6
39653965
call $~lib/builtins/abort
39663966
unreachable
39673967
end

0 commit comments

Comments
 (0)