Guest execution limits: fuel/epoch interruption + public ResourceLimiter
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 504
- Forks
- 37
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 44
Description
Motivation
We are embedding WasmKit in a game engine as the execution tier for downloaded gameplay modules — the interpreter path exists specifically for platforms where JIT is unavailable (iOS), so WasmKit is a natural fit and has been working well for us (the em_host-style import surface runs a ~50-function host table at 60 Hz ticks).
The gap we hit is guest resource containment. Module code is not fully trusted (eventually user-generated), and today an embedder has no in-process way to bound either of:
-
Execution time — a guest that never returns from a call (an accidental
while true {}is enough) cannot be stopped. We currently contain this at process level (the instance lives in a child process with a heartbeat watchdog that kills and quarantines it), which works but forces a process boundary on every embedder and loses the instance-per-actor isolation story for in-process hosts. -
Memory growth — a guest can
memory.growuntil OS pressure. The machinery for this already exists:ResourceLimiteris a plainpublic protocol, but the installation point is SPI-gated:// Sources/WasmKit/Execution/Store.swift @_spi(Fuzzing) // Consider making this public public var resourceLimiter: ResourceLimiter = DefaultResourceLimiter()
Requests
1. A preemption/budget mechanism for runaway guests
Either shape would serve embedders:
- Fuel metering: a configurable budget decremented on back-edges/calls, trapping with a distinct
Trapreason when exhausted (wasmi's model), or - Epoch/deadline interruption: a cheap flag checked at loop back-edges and function entries that an external thread can set to interrupt the running guest (Wasmtime's epoch model — typically cited as the lower-overhead option for interpreters too).
EngineInterceptor (onEnterFunction/onExitFunction) can't substitute here — it is function-granular, so a loop that never calls out is invisible to it. And #364's fuzzing fix (@_spi(Fuzzing) Module.dropStartFunction()) sidesteps the same class of problem for instantiation rather than solving it generally, which suggests the primitive is missing rather than merely unexposed.
A trap-on-exhaustion/interrupt would compose naturally with the existing Trap error surface — the embedder catches it at the export call site, exactly like an OOB today.
2. Make Store.resourceLimiter public
The protocol (ResourceLimiter) is already public (and AnyObject-constrained since #393, so this stays Embedded-Swift-friendly); only the @_spi(Fuzzing) on the Store property stands between embedders and memory/table growth limits. Promoting it — with whatever rename/shape you prefer — would let hosts cap a guest instance without patching.
Offer
Happy to help: we can test either mechanism against our embedding (a 52-import host table driven at fixed 60 Hz on macOS/arm64, both full-Swift and Embedded-flavor wasm32-unknown-wasip1 guests), contribute benchmarks of the check overhead on the register-machine interpreter, or take a swing at the resourceLimiter promotion as a PR if the direction is agreeable.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Sources/WasmKit/Execution/Store.swift and the existing ResourceLimiter property, then trace EngineInterceptor and the Trap error surface. Compare the proposed fuel or epoch interruption shapes against the interpreter entry and loop paths named in the issue. Done means embedders can configure resource limits publicly and runaway guests stop through a Trap-compatible mechanism, validated with the offered host scenarios and overhead benchmarks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift, wasm
- Domain
- backend, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100