Skip to content

cranelift: preserve fuel across stack-switching instructions - #14644

Open
ctiller wants to merge 1 commit into
bytecodealliance:mainfrom
ctiller:fix/stack-switching-fuel
Open

ctiller wants to merge 1 commit into
bytecodealliance:mainfrom
ctiller:fix/stack-switching-fuel

Conversation

@ctiller

@ctiller ctiller commented Oct 9, 2026

Copy link
Copy Markdown

When consume_fuel is enabled, FuncEnvironment caches the in-flight fuel counter in a function-local Cranelift SSA Variable (self.fuel_var) and synchronizes it with VMStoreContext::fuel_consumed across calls, returns, and exception handlers.

Previously, stack-switching instructions (resume, resume_throw, resume_throw_ref, suspend, and switch) did not flush/save self.fuel_var before switching stacks or reload self.fuel_var upon returning or resuming, and translate_resume_impl did not reload self.fuel_var at the entry of suspend_block before dispatching to (on $tag $label) handler blocks. As a result, fuel consumed inside a continuation was overwritten whenever control switched back to the parent or target stack.

Save self.fuel_var in fuel_before_op prior to resume*, suspend, and switch, reload self.fuel_var in fuel_after_op on normal return/wake-up, and call env.on_catch_block_entry(builder) at the start of suspend_block.

Assisted-by: Gemini

@ctiller
ctiller requested review from a team as code owners October 9, 2026 23:46
@ctiller
ctiller requested review from cfallin and removed request for a team October 9, 2026 23:46
When `consume_fuel` is enabled, `FuncEnvironment` caches the in-flight fuel
counter in a function-local Cranelift SSA `Variable` (`self.fuel_var`) and
synchronizes it with `VMStoreContext::fuel_consumed` across calls, returns,
and exception handlers.

Previously, stack-switching instructions (`resume`, `resume_throw`,
`resume_throw_ref`, `suspend`, and `switch`) did not flush/save `self.fuel_var`
before switching stacks or reload `self.fuel_var` upon returning or resuming,
and `translate_resume_impl` did not reload `self.fuel_var` at the entry of
`suspend_block` before dispatching to `(on $tag $label)` handler blocks. As a
result, fuel consumed inside a continuation was overwritten whenever control
switched back to the parent or target stack.

Save `self.fuel_var` in `fuel_before_op` prior to `resume*`, `suspend`, and
`switch`, reload `self.fuel_var` in `fuel_after_op` on normal return/wake-up,
and call `env.on_catch_block_entry(builder)` at the start of `suspend_block`.

Assisted-by: Gemini
@ctiller
ctiller force-pushed the fix/stack-switching-fuel branch from e1cc518 to 1891b0f Compare October 9, 2026 23:50
@cfallin
cfallin added this pull request to the merge queue Oct 10, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 10, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants