Skip to content

Commit 9568ca7

Browse files
Liedtkeguybedford
authored andcommitted
deps: V8: cherry-pick 5f1342c20b59
Original commit message: [wasm][exnref] Fix broken abstract casts ref.test, ref.cast, br_on_cast, br_on_cast_fail allow arbitrary heap types, so they also allow exnref and noexnref. This CL also fixes the missing type checks in the js to wasm wrapper. Bug: v8:14398 Change-Id: Ieefb9a8e99d3d7a4b175db60f55b7fa9a96c5203 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5372489 Reviewed-by: Thibaud Michaud <[email protected]> Commit-Queue: Matthias Liedtke <[email protected]> Cr-Commit-Position: refs/heads/main@{#92867} Refs: v8/v8@5f1342c
1 parent dbabdf7 commit 9568ca7

12 files changed

Lines changed: 262 additions & 13 deletions

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
# Reset this number to 0 on major V8 upgrades.
4040
# Increment by one for each non-official patch applied to deps/v8.
41-
'v8_embedder_string': '-node.39',
41+
'v8_embedder_string': '-node.40',
4242

4343
##### V8 defaults for Node.js #####
4444

deps/v8/src/compiler/turboshaft/wasm-lowering-reducer.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ class WasmLoweringReducer : public Next {
556556
// The none-types only perform a null check. They need no control flow.
557557
if (to_rep == wasm::HeapType::kNone ||
558558
to_rep == wasm::HeapType::kNoExtern ||
559-
to_rep == wasm::HeapType::kNoFunc) {
559+
to_rep == wasm::HeapType::kNoFunc ||
560+
to_rep == wasm::HeapType::kNoExn) {
560561
result = __ IsNull(object, config.from);
561562
break;
562563
}
@@ -628,7 +629,8 @@ class WasmLoweringReducer : public Next {
628629
// The none-types only perform a null check.
629630
if (to_rep == wasm::HeapType::kNone ||
630631
to_rep == wasm::HeapType::kNoExtern ||
631-
to_rep == wasm::HeapType::kNoFunc) {
632+
to_rep == wasm::HeapType::kNoFunc ||
633+
to_rep == wasm::HeapType::kNoExn) {
632634
__ TrapIfNot(__ IsNull(object, config.from), OpIndex::Invalid(),
633635
TrapId::kTrapIllegalCast);
634636
break;

deps/v8/src/compiler/wasm-compiler.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7325,6 +7325,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
73257325
// TODO(14034): Add more fast paths?
73267326
case wasm::HeapType::kExtern:
73277327
case wasm::HeapType::kNoExtern:
7328+
case wasm::HeapType::kExn:
7329+
case wasm::HeapType::kNoExn:
73287330
if (type.kind() == wasm::kRef) {
73297331
Node* null_value = gasm_->LoadImmutable(
73307332
MachineType::Pointer(), gasm_->LoadRootRegister(),
@@ -7345,9 +7347,6 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
73457347
return input;
73467348
case wasm::HeapType::kString:
73477349
return BuildCheckString(input, js_context, type);
7348-
case wasm::HeapType::kExn:
7349-
case wasm::HeapType::kNoExn:
7350-
return input;
73517350
case wasm::HeapType::kNone:
73527351
case wasm::HeapType::kNoFunc:
73537352
case wasm::HeapType::kI31:

deps/v8/src/compiler/wasm-gc-lowering.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ Reduction WasmGCLowering::ReduceWasmTypeCheckAbstract(Node* node) {
224224
// The none-types only perform a null check. They need no control flow.
225225
if (to_rep == wasm::HeapType::kNone ||
226226
to_rep == wasm::HeapType::kNoExtern ||
227-
to_rep == wasm::HeapType::kNoFunc) {
227+
to_rep == wasm::HeapType::kNoFunc || to_rep == wasm::HeapType::kNoExn) {
228228
result = IsNull(object, config.from);
229229
break;
230230
}
@@ -398,7 +398,7 @@ Reduction WasmGCLowering::ReduceWasmTypeCastAbstract(Node* node) {
398398
// The none-types only perform a null check.
399399
if (to_rep == wasm::HeapType::kNone ||
400400
to_rep == wasm::HeapType::kNoExtern ||
401-
to_rep == wasm::HeapType::kNoFunc) {
401+
to_rep == wasm::HeapType::kNoFunc || to_rep == wasm::HeapType::kNoExn) {
402402
gasm_.TrapUnless(IsNull(object, config.from), TrapId::kTrapIllegalCast);
403403
UpdateSourcePosition(gasm_.effect(), node);
404404
break;

deps/v8/src/wasm/baseline/liftoff-compiler.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6580,6 +6580,7 @@ class LiftoffCompiler {
65806580
case HeapType::kNone:
65816581
case HeapType::kNoExtern:
65826582
case HeapType::kNoFunc:
6583+
case HeapType::kNoExn:
65836584
DCHECK(null_succeeds);
65846585
return AssertNullTypecheck(decoder, obj, result_val);
65856586
case HeapType::kAny:
@@ -6674,6 +6675,7 @@ class LiftoffCompiler {
66746675
case HeapType::kNone:
66756676
case HeapType::kNoExtern:
66766677
case HeapType::kNoFunc:
6678+
case HeapType::kNoExn:
66776679
DCHECK(null_succeeds);
66786680
return BrOnNull(decoder, obj, depth, /*pass_null_along_branch*/ true,
66796681
nullptr);
@@ -6707,6 +6709,7 @@ class LiftoffCompiler {
67076709
case HeapType::kNone:
67086710
case HeapType::kNoExtern:
67096711
case HeapType::kNoFunc:
6712+
case HeapType::kNoExn:
67106713
DCHECK(null_succeeds);
67116714
return BrOnNonNull(decoder, obj, nullptr, depth,
67126715
/*drop_null_on_fallthrough*/ false);

deps/v8/src/wasm/function-body-decoder-impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4659,7 +4659,8 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
46594659
((!null_succeeds || !obj.type.is_nullable()) &&
46604660
(expected_type.representation() == HeapType::kNone ||
46614661
expected_type.representation() == HeapType::kNoFunc ||
4662-
expected_type.representation() == HeapType::kNoExtern));
4662+
expected_type.representation() == HeapType::kNoExtern ||
4663+
expected_type.representation() == HeapType::kNoExn));
46634664
}
46644665
bool TypeCheckAlwaysFails(Value obj, uint32_t ref_index) {
46654666
// All old casts / checks treat null as failure.

deps/v8/src/wasm/graph-builder-interface.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,6 +1803,7 @@ class WasmGraphBuildingInterface {
18031803
case HeapType::kNone:
18041804
case HeapType::kNoExtern:
18051805
case HeapType::kNoFunc:
1806+
case HeapType::kNoExn:
18061807
DCHECK(null_succeeds);
18071808
// This is needed for BrOnNull. {value_on_branch} is on the value stack
18081809
// and BrOnNull interacts with the values on the stack.
@@ -1841,6 +1842,7 @@ class WasmGraphBuildingInterface {
18411842
case HeapType::kNone:
18421843
case HeapType::kNoExtern:
18431844
case HeapType::kNoFunc:
1845+
case HeapType::kNoExn:
18441846
DCHECK(null_succeeds);
18451847
// We need to store a node in the stack where the decoder so far only
18461848
// pushed a value and expects the `BrOnCastFailAbstract` to set it.

deps/v8/src/wasm/wrappers.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,8 @@ class WasmWrapperTSGraphBuilder : public WasmGraphBuilderBase {
857857
// TODO(14034): Add more fast paths?
858858
case wasm::HeapType::kExtern:
859859
case wasm::HeapType::kNoExtern:
860+
case wasm::HeapType::kExn:
861+
case wasm::HeapType::kNoExn:
860862
if (type.kind() == wasm::kRef) {
861863
IF (__ TaggedEqual(input, LOAD_ROOT(NullValue))) {
862864
CallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError, {},
@@ -867,9 +869,6 @@ class WasmWrapperTSGraphBuilder : public WasmGraphBuilderBase {
867869
return input;
868870
case wasm::HeapType::kString:
869871
return BuildCheckString(input, context, type);
870-
case wasm::HeapType::kExn:
871-
case wasm::HeapType::kNoExn:
872-
return input;
873872
case wasm::HeapType::kNone:
874873
case wasm::HeapType::kNoFunc:
875874
case wasm::HeapType::kI31:
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
// Copyright 2024 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --experimental-wasm-exnref --no-experimental-wasm-inlining
6+
7+
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
8+
9+
let getExnRef = function() {
10+
let tag = new WebAssembly.Tag({parameters:[]});
11+
return new WebAssembly.Exception(tag, []);
12+
};
13+
14+
(function RefTestExnRef() {
15+
print(arguments.callee.name);
16+
let builder = new WasmModuleBuilder();
17+
let tag = builder.addTag(makeSig([], []));
18+
19+
builder.addFunction('testExnRef',
20+
makeSig([kWasmExnRef], [kWasmI32, kWasmI32]))
21+
.addBody([
22+
kExprLocalGet, 0, kGCPrefix, kExprRefTest, kExnRefCode,
23+
kExprLocalGet, 0, kGCPrefix, kExprRefTest, kNullExnRefCode,
24+
]).exportFunc();
25+
26+
builder.addFunction('testNullExnRef',
27+
makeSig([kWasmExnRef], [kWasmI32, kWasmI32]))
28+
.addBody([
29+
kExprLocalGet, 0, kGCPrefix, kExprRefTestNull, kExnRefCode,
30+
kExprLocalGet, 0, kGCPrefix, kExprRefTestNull, kNullExnRefCode,
31+
]).exportFunc();
32+
33+
let instance = builder.instantiate();
34+
let wasm = instance.exports;
35+
assertEquals([0, 0], wasm.testExnRef(null));
36+
assertEquals([1, 0], wasm.testExnRef(getExnRef()));
37+
assertEquals([1, 1], wasm.testNullExnRef(null));
38+
assertEquals([1, 0], wasm.testNullExnRef(getExnRef()));
39+
})();
40+
41+
(function RefCastExnRef() {
42+
print(arguments.callee.name);
43+
let builder = new WasmModuleBuilder();
44+
45+
builder.addFunction('castToExnRef',
46+
makeSig([kWasmExnRef], [kWasmExnRef]))
47+
.addBody([kExprLocalGet, 0, kGCPrefix, kExprRefCast, kExnRefCode])
48+
.exportFunc();
49+
builder.addFunction('castToNullExnRef',
50+
makeSig([kWasmExnRef], [kWasmExnRef]))
51+
.addBody([kExprLocalGet, 0, kGCPrefix, kExprRefCast, kNullExnRefCode])
52+
.exportFunc();
53+
builder.addFunction('castNullToExnRef',
54+
makeSig([kWasmExnRef], [kWasmExnRef]))
55+
.addBody([kExprLocalGet, 0, kGCPrefix, kExprRefCastNull, kExnRefCode])
56+
.exportFunc();
57+
builder.addFunction('castNullToNullExnRef',
58+
makeSig([kWasmExnRef], [kWasmExnRef]))
59+
.addBody([kExprLocalGet, 0, kGCPrefix, kExprRefCastNull, kNullExnRefCode])
60+
.exportFunc();
61+
62+
let instance = builder.instantiate();
63+
let wasm = instance.exports;
64+
65+
let exnRef = getExnRef();
66+
assertTraps(kTrapIllegalCast, () => wasm.castToExnRef(null));
67+
assertEquals(exnRef, wasm.castToExnRef(exnRef));
68+
assertTraps(kTrapIllegalCast, () => wasm.castToNullExnRef(null));
69+
assertTraps(kTrapIllegalCast, () => wasm.castToNullExnRef(exnRef));
70+
71+
assertSame(null, wasm.castNullToExnRef(null));
72+
assertEquals(exnRef, wasm.castNullToExnRef(exnRef));
73+
assertSame(null, wasm.castNullToNullExnRef(null));
74+
assertTraps(kTrapIllegalCast, () => wasm.castNullToNullExnRef(exnRef));
75+
})();
76+
77+
(function BrOnCastExnRef() {
78+
print(arguments.callee.name);
79+
let builder = new WasmModuleBuilder();
80+
81+
builder.addFunction('castToExnRef',
82+
makeSig([kWasmExnRef], [kWasmI32]))
83+
.addBody([
84+
kExprBlock, kWasmRef, kExnRefCode,
85+
kExprLocalGet, 0,
86+
...wasmBrOnCast(
87+
0, wasmRefNullType(kWasmExnRef), wasmRefType(kWasmExnRef)),
88+
kExprI32Const, 0,
89+
kExprReturn,
90+
kExprEnd,
91+
kExprDrop,
92+
kExprI32Const, 1,
93+
kExprReturn,
94+
])
95+
.exportFunc();
96+
builder.addFunction('castToNullExnRef',
97+
makeSig([kWasmExnRef], [kWasmI32]))
98+
.addBody([
99+
kExprBlock, kWasmRef, kNullExnRefCode,
100+
kExprLocalGet, 0,
101+
...wasmBrOnCast(
102+
0, wasmRefNullType(kWasmExnRef), wasmRefType(kWasmNullExnRef)),
103+
kExprI32Const, 0,
104+
kExprReturn,
105+
kExprEnd,
106+
kExprDrop,
107+
kExprI32Const, 1,
108+
kExprReturn,
109+
])
110+
.exportFunc();
111+
112+
builder.addFunction('castNullToExnRef',
113+
makeSig([kWasmExnRef], [kWasmI32]))
114+
.addBody([
115+
kExprBlock, kWasmRefNull, kExnRefCode,
116+
kExprLocalGet, 0,
117+
...wasmBrOnCast(0,
118+
wasmRefNullType(kWasmExnRef), wasmRefNullType(kWasmExnRef)),
119+
kExprI32Const, 0,
120+
kExprReturn,
121+
kExprEnd,
122+
kExprDrop,
123+
kExprI32Const, 1,
124+
kExprReturn,
125+
])
126+
.exportFunc();
127+
builder.addFunction('castNullToNullExnRef',
128+
makeSig([kWasmExnRef], [kWasmI32]))
129+
.addBody([
130+
kExprBlock, kWasmRefNull, kNullExnRefCode,
131+
kExprLocalGet, 0,
132+
...wasmBrOnCast(0,
133+
wasmRefNullType(kWasmExnRef), wasmRefNullType(kWasmNullExnRef)),
134+
kExprI32Const, 0,
135+
kExprReturn,
136+
kExprEnd,
137+
kExprDrop,
138+
kExprI32Const, 1,
139+
kExprReturn,
140+
])
141+
.exportFunc();
142+
143+
builder.addFunction('castFailToExnRef',
144+
makeSig([kWasmExnRef], [kWasmI32]))
145+
.addBody([
146+
kExprBlock, kWasmRefNull, kExnRefCode,
147+
kExprLocalGet, 0,
148+
...wasmBrOnCastFail(0,
149+
wasmRefNullType(kWasmExnRef), wasmRefType(kWasmExnRef)),
150+
kExprI32Const, 0,
151+
kExprReturn,
152+
kExprEnd,
153+
kExprDrop,
154+
kExprI32Const, 1,
155+
kExprReturn,
156+
])
157+
.exportFunc();
158+
builder.addFunction('castFailToNullExnRef',
159+
makeSig([kWasmExnRef], [kWasmI32]))
160+
.addBody([
161+
kExprBlock, kWasmRefNull, kExnRefCode,
162+
kExprLocalGet, 0,
163+
...wasmBrOnCastFail(0,
164+
wasmRefNullType(kWasmExnRef), wasmRefType(kWasmNullExnRef)),
165+
kExprI32Const, 0,
166+
kExprReturn,
167+
kExprEnd,
168+
kExprDrop,
169+
kExprI32Const, 1,
170+
kExprReturn,
171+
])
172+
.exportFunc();
173+
174+
builder.addFunction('castFailNullToExnRef',
175+
makeSig([kWasmExnRef], [kWasmI32]))
176+
.addBody([
177+
kExprBlock, kWasmRef, kExnRefCode,
178+
kExprLocalGet, 0,
179+
...wasmBrOnCastFail(0,
180+
wasmRefNullType(kWasmExnRef), wasmRefNullType(kWasmExnRef)),
181+
kExprI32Const, 0,
182+
kExprReturn,
183+
kExprEnd,
184+
kExprDrop,
185+
kExprI32Const, 1,
186+
kExprReturn,
187+
])
188+
.exportFunc();
189+
builder.addFunction('castFailNullToNullExnRef',
190+
makeSig([kWasmExnRef], [kWasmI32]))
191+
.addBody([
192+
kExprBlock, kWasmRef, kExnRefCode,
193+
kExprLocalGet, 0,
194+
...wasmBrOnCastFail(0,
195+
wasmRefNullType(kWasmExnRef), wasmRefNullType(kWasmNullExnRef)),
196+
kExprI32Const, 0,
197+
kExprReturn,
198+
kExprEnd,
199+
kExprDrop,
200+
kExprI32Const, 1,
201+
kExprReturn,
202+
])
203+
.exportFunc();
204+
205+
let instance = builder.instantiate();
206+
let wasm = instance.exports;
207+
let exnRef = getExnRef();
208+
209+
assertEquals(0, wasm.castToExnRef(null));
210+
assertEquals(1, wasm.castToExnRef(exnRef));
211+
212+
assertEquals(0, wasm.castToNullExnRef(null));
213+
assertEquals(0, wasm.castToNullExnRef(exnRef));
214+
215+
assertEquals(1, wasm.castNullToExnRef(null));
216+
assertEquals(1, wasm.castNullToExnRef(exnRef));
217+
218+
assertEquals(1, wasm.castNullToNullExnRef(null));
219+
assertEquals(0, wasm.castNullToNullExnRef(exnRef));
220+
221+
assertEquals(1, wasm.castFailToExnRef(null));
222+
assertEquals(0, wasm.castFailToExnRef(exnRef));
223+
224+
assertEquals(1, wasm.castFailToNullExnRef(null));
225+
assertEquals(1, wasm.castFailToNullExnRef(exnRef));
226+
227+
assertEquals(0, wasm.castFailNullToExnRef(null));
228+
assertEquals(0, wasm.castFailNullToExnRef(exnRef));
229+
230+
assertEquals(0, wasm.castFailNullToNullExnRef(null));
231+
assertEquals(1, wasm.castFailNullToNullExnRef(exnRef));
232+
})();

deps/v8/test/mjsunit/wasm/gc-casts-invalid.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
// Flags: --experimental-wasm-exnref
6+
57
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
68

79
(function TestRefTestInvalid() {
@@ -20,6 +22,11 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
2022
[wasmRefType(sig), kExternRefCode],
2123
[kWasmAnyRef, kExternRefCode],
2224
[kWasmAnyRef, kFuncRefCode],
25+
[kWasmAnyRef, kExnRefCode],
26+
[wasmRefType(sig), kExnRefCode],
27+
[kWasmNullExternRef, kExnRefCode],
28+
[wasmRefType(array), kNullExnRefCode],
29+
[kWasmNullFuncRef, kNullExnRefCode],
2330
];
2431
let casts = [
2532
kExprRefTest,

0 commit comments

Comments
 (0)