Skip to content

Commit dc7184a

Browse files
authored
[GC] Fix casts of non-GC data (#3483)
The code previously assumed it could always call getGCData, but that assumes the input is an array or a struct. It could also be an anyref etc. that contains something other than GC data.
1 parent 46f0229 commit dc7184a

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

src/wasm-interpreter.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,11 +1433,19 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
14331433
return cast;
14341434
}
14351435
cast.originalRef = ref.getSingleValue();
1436-
auto gcData = cast.originalRef.getGCData();
1437-
if (!gcData) {
1436+
if (cast.originalRef.isNull()) {
14381437
cast.outcome = cast.Null;
14391438
return cast;
14401439
}
1440+
// The input may not be a struct or an array; for example it could be an
1441+
// anyref of null (already handled above) or anything else (handled here,
1442+
// but this is for future use as atm the binaryen interpreter cannot
1443+
// represent external references).
1444+
if (!cast.originalRef.isGCData()) {
1445+
cast.outcome = cast.Failure;
1446+
return cast;
1447+
}
1448+
auto gcData = cast.originalRef.getGCData();
14411449
auto refRtt = gcData->rtt;
14421450
auto intendedRtt = rtt.getSingleValue();
14431451
if (!refRtt.isSubRtt(intendedRtt)) {

test/passes/Oz_fuzz-exec_all-features.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
[fuzz-exec] calling br_on_cast
2222
[LoggingExternalInterface logging 3]
2323
[trap unreachable]
24+
[fuzz-exec] calling cast-null-anyref-to-gc
25+
[LoggingExternalInterface logging 0]
2426
(module
2527
(type ${mut:i32} (struct (field (mut i32))))
2628
(type $none_=>_none (func))
@@ -32,6 +34,7 @@
3234
(export "arrays" (func $1))
3335
(export "rtts" (func $2))
3436
(export "br_on_cast" (func $3))
37+
(export "cast-null-anyref-to-gc" (func $4))
3538
(func $0 (; has Stack IR ;)
3639
(local $0 (ref null ${mut:i32}))
3740
(call $log
@@ -194,6 +197,11 @@
194197
)
195198
(unreachable)
196199
)
200+
(func $4 (; has Stack IR ;)
201+
(call $log
202+
(i32.const 0)
203+
)
204+
)
197205
)
198206
[fuzz-exec] calling structs
199207
[LoggingExternalInterface logging 0]
@@ -218,3 +226,5 @@
218226
[fuzz-exec] calling br_on_cast
219227
[LoggingExternalInterface logging 3]
220228
[trap unreachable]
229+
[fuzz-exec] calling cast-null-anyref-to-gc
230+
[LoggingExternalInterface logging 0]

test/passes/Oz_fuzz-exec_all-features.wast

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,15 @@
179179
)
180180
)
181181
)
182+
(func "cast-null-anyref-to-gc"
183+
;; a null anyref is a literal which is not even of GC data, as it's not an
184+
;; array or a struct, so our casting code should not assume it is. it is ok
185+
;; to try to cast it, and the result should be 0.
186+
(call $log
187+
(ref.test $struct
188+
(ref.null any)
189+
(rtt.canon $struct)
190+
)
191+
)
192+
)
182193
)

0 commit comments

Comments
 (0)