Skip to content

Commit 5884400

Browse files
alexcrichtonbongjunj
authored andcommitted
Check fuel on GC-related branching instructions (bytecodealliance#11426)
Previously GC instructions didn't check for fuel meaning that an infinite loop with a GC-related branch instruction would never terminate.
1 parent 2b13c7a commit 5884400

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

crates/cranelift/src/func_environ.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,10 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
419419
| Operator::Br { .. }
420420
| Operator::BrIf { .. }
421421
| Operator::BrTable { .. }
422+
| Operator::BrOnNull { .. }
423+
| Operator::BrOnNonNull { .. }
424+
| Operator::BrOnCast { .. }
425+
| Operator::BrOnCastFail { .. }
422426

423427
// Exiting a scope means that we need to update the fuel
424428
// consumption because there are multiple ways to exit a scope and

tests/all/fuel.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fn fuel_consumed(config: &Config, wasm: &[u8]) -> Result<u64> {
5757
Ok(u64::MAX - store.get_fuel()?)
5858
}
5959

60-
#[wasmtime_test]
60+
#[wasmtime_test(wasm_features(gc, function_references))]
6161
#[cfg_attr(miri, ignore)]
6262
fn iloop(config: &mut Config) -> Result<()> {
6363
config.consume_fuel(true);
@@ -113,6 +113,64 @@ fn iloop(config: &mut Config) -> Result<()> {
113113
)
114114
"#,
115115
)?;
116+
iloop_aborts(
117+
&config,
118+
r#"
119+
(module
120+
(start 0)
121+
(func loop ref.null func br_on_null 0 drop end)
122+
)
123+
"#,
124+
)?;
125+
iloop_aborts(
126+
&config,
127+
r#"
128+
(module
129+
(start 0)
130+
(func
131+
ref.func 0
132+
loop (param (ref func))
133+
br_on_non_null 0
134+
unreachable
135+
end
136+
)
137+
(elem declare func 0)
138+
)
139+
"#,
140+
)?;
141+
iloop_aborts(
142+
&config,
143+
r#"
144+
(module
145+
(start 0)
146+
(func
147+
i32.const 0
148+
ref.i31
149+
loop (param (ref i31))
150+
br_on_cast 0 anyref (ref i31)
151+
unreachable
152+
end
153+
)
154+
(elem declare func 0)
155+
)
156+
"#,
157+
)?;
158+
iloop_aborts(
159+
&config,
160+
r#"
161+
(module
162+
(start 0)
163+
(func
164+
ref.null any
165+
loop (param anyref)
166+
br_on_cast_fail 0 anyref (ref i31)
167+
unreachable
168+
end
169+
)
170+
(elem declare func 0)
171+
)
172+
"#,
173+
)?;
116174

117175
fn iloop_aborts(config: &Config, wat: &str) -> Result<()> {
118176
let engine = Engine::new(&config)?;

0 commit comments

Comments
 (0)