Skip to content

Commit 1289cf8

Browse files
committed
Bug 1977692: Allow -0 to convert to i31ref. r=rhunt
This required changing the C++ conversion path (deep in ToWebAssemblyValue) and the JIT entry path. Differential Revision: https://phabricator.services.mozilla.com/D258039
1 parent 24033f0 commit 1289cf8

File tree

4 files changed

+17
-9
lines changed

4 files changed

+17
-9
lines changed

js/src/jit-test/lib/wasm.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,6 @@ let WasmNonAnyrefValues = [
488488
{x:1337},
489489
["abracadabra"],
490490
13.37,
491-
-0,
492491
0x7fffffff + 0.1,
493492
-0x7fffffff - 0.1,
494493
0x80000000 + 0.1,

js/src/jit-test/tests/wasm/gc/i31ref.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
// -0 is a valid value with which to create an i31ref, but because it
2+
// roundtrips to +0, it wrecks a lot of our WASM tests (which use Object.is for
3+
// comparison). Therefore we don't include -0 in the main list, and deal with
4+
// that complexity in this file specifically.
5+
WasmI31refValues.push(-0);
6+
17
let InvalidI31Values = [
28
null,
39
Number.EPSILON,
410
Number.MAX_SAFE_INTEGER,
511
Number.MIN_SAFE_INTEGER,
612
Number.MIN_VALUE,
713
Number.MAX_VALUE,
14+
Infinity,
15+
-Infinity,
816
Number.NaN,
9-
-0,
1017
// Number objects are not coerced
1118
...WasmI31refValues.map(n => new Number(n)),
1219
// Non-integers are not valid
@@ -95,16 +102,16 @@ for (let i of InvalidI31Values) {
95102
// Test that we can roundtrip 31-bit integers through the i31ref type
96103
// faithfully.
97104
for (let i of WasmI31refValues) {
98-
assertEq(refI31(i), i);
99-
assertEq(refI31Identity(i), i);
105+
assertEq(refI31(i), Object.is(i, -0) ? 0 : i);
106+
assertEq(refI31Identity(i), Object.is(i, -0) ? 0 : i);
100107
assertEq(i31GetU(i), valueAsI31GetU(i));
101-
assertEq(i31GetS(i), i);
108+
assertEq(i31GetS(i), Object.is(i, -0) ? 0 : i);
102109
}
103110

104111
// Test that i31ref values are truncated when given a 32-bit value
105112
for (let i of WasmI31refValues) {
106113
let adjusted = i | 0x80000000;
107-
assertEq(refI31(adjusted), i);
114+
assertEq(refI31(adjusted), Object.is(i, -0) ? 0 : i);
108115
}
109116

110117
// Test that comparing identical i31 values works

js/src/jit/MacroAssembler.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7187,7 +7187,8 @@ void MacroAssembler::branchValueConvertsToWasmAnyRefInline(
71877187
bind(&checkDouble);
71887188
{
71897189
unboxDouble(src, scratchFloat);
7190-
convertDoubleToInt32(scratchFloat, scratchInt, &fallthrough);
7190+
convertDoubleToInt32(scratchFloat, scratchInt, &fallthrough,
7191+
/*negativeZeroCheck=*/false);
71917192
branch32(Assembler::GreaterThan, scratchInt,
71927193
Imm32(wasm::AnyRef::MaxI31Value), &fallthrough);
71937194
branch32(Assembler::LessThan, scratchInt, Imm32(wasm::AnyRef::MinI31Value),
@@ -7216,7 +7217,8 @@ void MacroAssembler::convertValueToWasmAnyRef(ValueOperand src, Register dest,
72167217
bind(&doubleValue);
72177218
{
72187219
unboxDouble(src, scratchFloat);
7219-
convertDoubleToInt32(scratchFloat, dest, oolConvert);
7220+
convertDoubleToInt32(scratchFloat, dest, oolConvert,
7221+
/*negativeZeroCheck=*/false);
72207222
branch32(Assembler::GreaterThan, dest, Imm32(wasm::AnyRef::MaxI31Value),
72217223
oolConvert);
72227224
branch32(Assembler::LessThan, dest, Imm32(wasm::AnyRef::MinI31Value),

js/src/wasm/WasmAnyRef.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ bool AnyRef::fromJSValue(JSContext* cx, HandleValue value,
8686
if (value.isDouble()) {
8787
double doubleValue = value.toDouble();
8888
int32_t intValue;
89-
if (mozilla::NumberIsInt32(doubleValue, &intValue) &&
89+
if (mozilla::NumberEqualsInt32(doubleValue, &intValue) &&
9090
!int32NeedsBoxing(intValue)) {
9191
result.set(AnyRef::fromInt32(intValue));
9292
return true;

0 commit comments

Comments
 (0)