Repository navigation
Conversation
Add the `enginewasm` crate: task types defined by untrusted core-wasm modules (wasmtime, no WASI; only `ge.log` may be imported) under memory, epoch-timeout and io caps, with metadata read from custom sections before any guest code runs. A mod may ship a WGSL kernel (`ge:wgsl`), validated with naga against a two-buffer binding contract and run through wgpu with many payloads packed per dispatch; it must match the CPU path byte for byte. The server loads `./mods/*.wasm` behind `engine --features wasm` and uses the mod's `ge_verify` for payloads and results; `wasm_worker` leases and runs tasks on the GPU or CPU, and `--bench` compares the two locally. Spec in docs/wasm.md; example guest in examples/wasm-mix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…line - `[wasm]` / `[wasm.mods."ns:name"]` in config.toml (`WasmConfig`) set memory, call/GPU timeouts, io caps, pool size and memory64 per mod, plus capability grants: `fs` mounts (read-only or writable, via cap-std handles so `..`/absolute/symlink escapes are refused) and a `net` `host:port` allowlist. Everything stays denied by default; the server and `wasm_worker --config` fail closed on a bad table. - `ge.fs_read`/`fs_write`/`net_connect`/`send`/`recv`/`close` host calls; sockets inherit the call's remaining budget and close when it ends. - wasm64 (memory64) modules: the host is generic over pointer width and the ABI is now `ge_run(ptr, len, out) -> i32` with a `[ptr, len]` result slot, so one Rust source builds for wasm32 and wasm64 (example included). - `wasm_worker --bench` adds a native row compiled from the example's own `mix.rs` and reports speedups against it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # AGENTS.md # Cargo.lock # engine/Cargo.toml
# Conflicts: # Cargo.lock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
This adds a new
enginewasmcrate. With it, a task type can be defined by an untrusted WebAssembly module (wasm32 or wasm64) instead of a native.rfmod. The mod can also ship a WGSL compute kernel that workers run on the GPU through wgpu (WebGPU on Vulkan/Metal/DX12)../mods/*.wasmand uses the mod'sge_verifyto check payloads and results. It never runs tasks.wasm_worker): leases chunks and runs them either on the GPU (the mod's kernel) or on the CPU (the mod'sge_run). Both paths must produce identical bytes.wasm_worker --bench Ncompares native vs wasm vs GPU locally. The native row is compiled from the example mod's ownmix.rs.config.toml[wasm], with per-mod overrides. Everything is denied by default.Full spec is in
docs/wasm.md.Configuration: limits and grants
wasm_worker --configboth read this table.[wasm]table, such as a typo'd key or a malformedhost:port, stops startup instead of falling back to defaults.ge.fs_read/ge.fs_write):<mount>/<relative path>.cap-stddirectory handles, so.., absolute paths and symlinks that point out of the mount are all refused.write = true.ge.net_connect/send/recv/close):host:portmatches from the allowlist can be connected to.ge.*import is always linked, so any mod loads. A call the mod wasn't granted returns-1.64-bit wasm
ge_alloc(usize) -> usize,ge_verify(ptr, len) -> i32, andge_run(ptr, len, out) -> i32, which writes[ptr, len]to a slot the host allocates.wasm32-unknown-unknownand, on nightly with-Zbuild-std, forwasm64-unknown-unknown. The example ships both.memory64 = falserefuses 64-bit modules, globally or per mod.Safety model
CPU path (wasmtime):
ge.*call.StoreLimits). Oversized initial memory fails to instantiate, andmemory.growpast the cap returns -1.Loading:
ge:meta) and the kernel (ge:wgsl) are read from custom sections before any guest code is compiled or run. Unknown keys are rejected.[A-Za-z0-9_-](:is refused, because these names become storage key prefixes).GPU path (wgpu):
Performance
These numbers are from
demo:mix(lowbias32, 1024 rounds per word) on an RX 6800 (Vulkan) against 12 CPU threads. Every backend produced identical bytes, and rates vary by about ±15% between runs.Tests
enginewasm/tests/sandbox.rshas 22 tests, all using hand-written WAT guests:memory64switch, a 5 GiB memory, and the shared host calls;..,//and unknown mounts are denied; a symlink escape is refused; read-only vs writable mounts;cargo test --workspace,cargo build --workspaceand clippy on the new code are all clean.Known gaps / follow-ups
RunnerKind::Gpuon the wire. The worker picks its backend locally. Advertising it to the server needs aPROTO_VERSIONbump.Try it
🤖 Generated with Claude Code