Repository navigation
Conversation
added 2 commits
August 15, 2026 19:37
`run_guest` read the file and instantiated in one body, so a caller with bytes already in hand had nowhere to enter. A module fetched from a page never touches the disk. `run_guest_bytes` is that entry point and now holds the whole sequence: validate, link, `instantiate_and_start`, call the entry export, check the status, warn when a guest reports OK without mutating anything. `run_guest` reads the file and calls it. One copy rather than two, deliberately. Everything that decides whether a guest ran correctly is subtle enough to be worth having in a single place -- the note on why this is `instantiate_and_start` and not `instantiate` has to keep applying to the only copy of that call. No behaviour change: both existing callers keep the signature they had.
A page can now hand its interface to a WebAssembly guest: <script type="application/wasm" src="/demo.wasm" mount="#root"></script> The module is fetched with the page, vetted, and mounted against the parsed document. No JavaScript anywhere in the path: a page that declares a module is parsed without a script runtime, because attaching an engine to run none is dead weight. This is the other shape from `--wasm`. That replaces the document entirely -- an empty `<html><body>` the guest fills, no HTML at all. Here the document exists first, including whatever sits inside the mount, and the guest takes that element over. The fallback is the reason for most of the care here. It is what a browser without wasm shows, so every way of failing has to leave it standing: a bad selector, a 404, a server answering 200 with its index page, a module that instantiates and then reports a non-OK status. The mount is emptied only after the entry export has returned OK. Failure re-parses rather than repairs. A guest appends into the mount as it builds, so a run that fails part way leaves its own half-built tree beside the fallback with no way to tell them apart afterwards. Parsing the same bytes again is the only way to be certain the document is what the page said. Bytes are vetted before wasmi sees them, because the failure that catches is not a corrupt module. The site this exists for is behind a CDN that answers 200 with its index page for every unknown path, so a missing module arrives as `<!doctype html>` and wasmi reports byte offsets in a file that is not a module. That has to say the server returned HTML: the fix is a deploy, not a rebuild. Same origin only. The guest runs against the host ABI with the whole document reachable, which is a different trust decision from a local file named on the command line. Cross-origin needs a policy, not a default. `runtime="..."` is parsed and ignored. Nothing implements preloaded runtimes yet and the live page carries the attribute, so failing on it would reject the page it is meant to serve.
Owner
Author
|
Folded into #19, which now carries this whole stack against master. |
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.
A page can now hand its interface to a WebAssembly guest, with no JavaScript
anywhere in the path:
Until this, the only way to run a guest was
chuzz --wasm /abs/path.wasm. Thattag described a loading mechanism no browser implemented, including this one.
Confirmed against the live site
Real page, real module, end to end: fetched and parsed, tag found,
srcresolved and confirmed same-origin, module fetched and vetted,
#rootlocated,guest instantiated under wasmi, entry export returned
OK, and only then the 17fallback nodes removed. The module checks out independently too —
content-type: application/wasm, 708 bytes, magic0061736d.The same URL in Chrome shows the fallback unchanged:
curlreturns an<h1>and explanatory prose inside
#root, which browsers render because the tag isinert to them. Not a blank page.
The fallback is the reason for most of the care
It is what a browser without wasm shows, so every way of failing has to leave it
standing. Verified across all four, with the success case in the same test so
the three "intact" assertions cannot pass merely because nothing ever mounts:
#root.panelpresentFailure re-parses rather than repairs. A guest appends into the mount as it
builds, so a run that fails part way leaves its own half-built tree beside the
fallback with no way to tell them apart afterwards. Parsing the same bytes again
is the only way to be certain the document is what the page said. The mount is
emptied only after the entry export returns
OK.Bytes are vetted before wasmi sees them
The site this exists for sits behind a CDN that answers 200 with its index
page for every unknown path, so a missing module arrives as
<!doctype html>and wasmi reports byte offsets in a file that is not a module. That has to say
the server returned HTML: the fix is a deploy, not a rebuild. A genuinely
corrupt module says something else, and the test pins the two apart.
Same origin only
The guest runs against the host ABI with the whole document reachable — a
different trust decision from a local file named on the command line.
Cross-origin needs a policy, not a default.
runtime="..."is parsed and ignored. Nothing implements preloaded runtimesyet and the live page carries
runtime="solid@1", so failing on it would rejectthe page this exists to serve.
Structure
run_guestwas split:run_guest_bytesholds the whole instantiate sequenceand
run_guestreads a file and calls it. One copy rather than two, so the noteon why it is
instantiate_and_startand notinstantiatekeeps applying to theonly copy. Both existing callers keep their signatures.
Verified
--wasm,--capture-wasmand--captureall demonstrated still working, notassumed. 24 tests, clippy clean, fmt clean, and the
--no-default-featuresbuild without
wasmcompiles (it keeps the fallback and says why).Known gaps
--capturedoes not take this path. It loads throughdocument_loader,not
browser.rs, so capturing that URL renders the fallback. That matters forproducing a chrome-free still of the page.
Content-Typeis not checked.blitz_net::fetch_asyncreturns(String, Bytes)with no headers. Status is covered (non-2xx becomesProviderError::HttpStatus) and magic bytes are covered; the distinct "serverreturned HTML" message comes from sniffing instead. A real MIME check needs a
header-returning fetch in blitz-net.
OKhaving built nothing empties the fallback andleaves a blank mount.
run_guest_byteswarns but succeeds.Storekept alive past the mount.