Stream: web-preview

Topic: component(-web)-sdk repo


view this post on Zulip Ryan Hunt (Sep 15 2026 at 16:39):

I talked with Thomas Lively about getting a new repo in the WebAssembly org. He was open to it, but pushed slightly back and asked why we can't just rename 'wasi-sdk'. I missed last weeks meeting, so I believe this was discussed more then and Alex strongly preferred not renaming it. Alex, what are your concerns again? I told Thomas I'd get back to him with more rationale.

That aside, there is the question of what to name the new repo. I wonder if it's possible to name the new repo to just 'component-sdk' and publish both new artifacts there. Then eventually when enough things are migrated, we could deprecate the 'wasi-sdk' repo. It feels like a nice goal to eventually have a single repo for all this code, and 'component' is generic enough to cover both.

I don't think 'web-sdk' would fly, it's too generic and we'd probably get pushback. 'web-component-sdk' collides with web components. So that would leave 'component-web-sdk' as a fallback.

@Alex Crichton @Ben Visness

view this post on Zulip Alex Crichton (Sep 15 2026 at 16:44):

My main worry was basically the volume of locations that refer to "wasi" or "wasi-sdk" that have to be updated to something else when the wasi-sdk repo is archived/renamed/etc. Some examples are:

For myself this was then all capped off with the realization that this would sort of continue to perpetuate the feeling of instability for WASI and such.


Overall though I very much agree that the long-term goal should be one place to get clang & co. I do not want a long-term solution where there's both a wasi-sdk and component-web-sdk for example.

view this post on Zulip Alex Crichton (Sep 15 2026 at 16:45):

tl;dr; I got cold feet and had second thoughts about renaming wasi-sdk

view this post on Zulip Alex Crichton (Sep 15 2026 at 16:45):

Maintenance of wasi-sdk is also pretty onerous right now insofar as every PR has like ~6 hours of CI because windows is slow and refuses to ccache correctly.

view this post on Zulip Alex Crichton (Sep 15 2026 at 16:47):

I'll definitely admit though that some of this is sort of selfish of me insofar as I suspect that a lot of the renaming work would fall on me and I'm not particularly eager to go do all that

view this post on Zulip Alex Crichton (Sep 15 2026 at 16:48):

but also I mean none of what I bring up is like a super strong objection, and it's definitely technically feasible to rename

view this post on Zulip Ryan Hunt (Sep 15 2026 at 16:56):

Sure I get that, not trying to add unreasonable work here, especially with all the stuff going on.

It sounds like eventually renaming things over makes sense, but it will just take a while. I wonder if instead of renaming the wasi-sdk repo, we could just create component-sdk as a mirror that automatically follows along with wasi-sdk. We could keep issues/PRs on wasi-sdk. Eventually when things are migrated over, we could switch from component-sdk being the mirror to being the development target. Or alternatively start with wasi-sdk being a mirror that is eventually disabled.

view this post on Zulip Ryan Hunt (Sep 15 2026 at 16:57):

My concern is to avoid fragmenting development here. I think the web.wit work and other things are going to need to happen in the same repo as the wasi target.

view this post on Zulip Alex Crichton (Sep 15 2026 at 16:58):

yeah IIRC that was the general conclusion, component-sdk would repackage wasi-sdk's artifacts (wasi-sdk would include wasm32-webp2) and would possibly include web.h and libweb.a or similar for a web-sdk-style-download

view this post on Zulip Alex Crichton (Sep 15 2026 at 16:58):

we should probably talk more in depth this week about web.h to hammer out a more concrete plan there

view this post on Zulip Ryan Hunt (Sep 15 2026 at 16:59):

Ah okay. I had heard an idea around having component-sdk embed wasi-sdk as a submodule. I think a true git mirror would be cleaner, because I'm not sure what would actually live in the repo besides just the submodule

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:00):

my rough assertion is that it's going to be best to not actually have parallel CI builds for anything since it takes so long to build everything

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:00):

there's no problem adding wasm32-webp2 of course to wasi-sdk, so the actual production of things is of no concern, it's basically around the optics and where things are downloaded

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:00):

that's where the thinking that (component-)web-sdk would repackage the wasi-sdk artifacts

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:01):

although this also touches on distribution of web.wit/web.h b/c I was thinking that wasi-sdk wouldn't ever want to include that

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:01):

another example was wasi-sdk not including bindings to wasi:http as an example

view this post on Zulip Ryan Hunt (Sep 15 2026 at 17:02):

I guess it depends on how libc bootstraps some of its API's. I was imagining it'd need access to a small subset of things like console.log/etc. Definitely doesn't need many web API's. But a few

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:03):

yeah building wasi-libc needs WITs for sure, but right now those bindings are internal to wasi-libc and aren't published

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:03):

or, well, actually they are published, but not necessarily easily accessible

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:03):

so wasi-libc would include browser.wit and bind things like performance.now or w/e for sure, but web.h is like "ok but if you actually do web development use this"

view this post on Zulip Ryan Hunt (Sep 15 2026 at 17:04):

Yeah that makes sense. In that case, web.h doesn't need to live with wasi-sdk/component-sdk. We probably could hand-craft a minimal web-libc.wit that has just the basics and include that there.

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:05):

partly this is where I think we should talk about web.h in more detail because personally I think it might make the most sense to not include that in a *-sdk download

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:06):

but this has a large impact on developer experience though so we'll definitely want to make an actual decision about this

view this post on Zulip Ben Visness (Sep 15 2026 at 17:07):

I would consider web.h to be the equivalent of a web-sys crate for C/C++ developers and not part of the "toolchain". It could live in the same repo as toolchain things but shouldn't be part of a toolchain release imo.

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:08):

agreed yeah, although I'd be concerned about living in the toolchain repo insofar as CI for a toolchain is typically quite expensive whereas CI for web.h in theory should be pretty cheap

view this post on Zulip Ben Visness (Sep 15 2026 at 17:08):

Depends on what triggers the CI, I guess?

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:09):

it's true, and I'm perhaps biased a bit here, but most repos I work on operate on the model of everything that merges runs the full CI of the repo to ensure nothing gets out of sync

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:09):

running a subset of CI checks makes sense for PRs IMO but when merging I personally don't trust filters much b/c they often miss subtle interactions

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:10):

but overall what I'm thinking is we should nail down web.h distribution, and that might re-shift things to biting the bullet and renaming wasi-sdk

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:10):

it also might not, iunno

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:10):

I suppose development & distribution of web.h

view this post on Zulip Ben Visness (Sep 15 2026 at 17:13):

I'm just torn between the idea of having a separate repo for browser.wit / web.h / other bindings artifacts (?) that can move at their own pace, and the idea of having a one-stop shop for the whole affair (incl. a natural place to centralize issues, since I imagine many might be cross-cutting)

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:15):

Along those lines the issue trackers of wasilibc and wasisdk are quite blurred yeah and not great being separate

view this post on Zulip Ben Visness (Sep 15 2026 at 17:16):

It might also be important to consider how interlinked web.h / web.a / etc. will be with the actual clang toolchains. If they need to remain in sync, then it might be best to release them together (sometimes releasing smaller updates to just web.h)

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:19):

If web.h were a separate repo, I'd personally say that the produced artifact should be *.{h,c} files (maybe *.{hh,cc} too) rather than *.a, and that should keep compat pretty orthgonal b/c then users don't have to align targets or we have to deal with abis or anything like that, just #ifdefs in a few places

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:20):

if web.h ships with the sdk though then that's all different, we'd be shipping libweb.a, but it'd also be a solved problem for clang compat then since it's only precompiled

view this post on Zulip Ben Visness (Sep 15 2026 at 17:27):

Honestly, it would be great to precompile as little as possible and distribute all the bindings SQLite style (one header, one impl file). Is that feasible or do the modded toolchains need object files with mystery magic in them somehow?

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:30):

oh that's true it'd also need the *.o that wit-bindgen generates

view this post on Zulip Ben Visness (Sep 15 2026 at 17:30):

I thought I remembered something funny there

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:30):

in theory it's it's just another "include this in your build" kind of file

view this post on Zulip Ben Visness (Sep 15 2026 at 17:30):

what does that object file do again?

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:31):

encodes the WIT in a custom section that wasm-component-ld later picks up to generate a component

view this post on Zulip Ben Visness (Sep 15 2026 at 17:32):

WIT or component binary stuff?

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:33):

elaborate on "component binary stuff"?

the object contains a custom section which is the WIT-encoded-as-wasm in wasm binary form, so sort of a wasm-component-in-a-custom-section-in-a-core-module

view this post on Zulip Ben Visness (Sep 15 2026 at 17:34):

just was wondering if wasm-component-ld literally had to re-parse WIT or if it saw the component binary format

view this post on Zulip Alex Crichton (Sep 15 2026 at 17:34):

ah yeah, component binary in that case

view this post on Zulip Ryan Hunt (Sep 24 2026 at 21:07):

Here we go!

https://github.com/WebAssembly/component-sdk
https://github.com/WebAssembly/component-web-bindings

view this post on Zulip Ben Visness (Sep 28 2026 at 14:22):

So now that these repos exist, what are the general next steps? Presumably for component-sdk we want to add a wasm32-webp2 target (to align with the Rust name) but that work happens in wasi-sdk first, right? I doubt there's much to do in the component-sdk repo until we get that taken care of first.

view this post on Zulip Ben Visness (Sep 28 2026 at 14:23):

And for the bindings, I assume we can just start adding some WIT and some scripts for generating language bindings?

view this post on Zulip Alex Crichton (Sep 28 2026 at 15:41):

The rough timeline in my head is:

  1. Fill out component-web-bindings with *.wit
  2. Setup CI to publish artifacts to that repo's releases, just some way for now to version the WIT to have it change over time. Artifacts would basically be a snapshot of the WITs. Git tags would probably also work for now
  3. Import some tag/artifact into wasi-libc's CI. Use this *.wit to bootstrap the wasm32-webp2 target in wasi-libc.
  4. Get wasi-libc's support landed, ideally involving tests somehow (that part TBD...)
  5. Update wasi-sdk to pull in an updated wasi-libc and additionally add wasm32-webp2 to the list of targets to build
  6. Get an experimental release out for wasi-sdk using this updated version
  7. Bootstrap component-sdk to (temporarily for now) pull artifacts from wasi-sdk, rename them/shuffle, and then republish on the component-sdk repo

then later assuming everything goes well

  1. Send notice to everyone that the wasi-sdk repository is being deprecated/archived
  2. Move all infrastructure from wasi-sdk to component-sdk, appropriately renaming things
  3. Archive the wasi-sdk repo in the long term and all future development happens in component-sdk
  4. Optionally rename wasi-libc to component-libc at some point in the future (this one should be fine to do with a github rename-the-repo)

view this post on Zulip Ben Visness (Sep 28 2026 at 19:33):

Does it actually make sense to make wasi-libc's web target depend on an artifact from component-web-bindings? Ryan and I were thinking that something more minimal might make more sense, e.g. hand-writing bindings that do exactly what you need for printing, time, randomness, etc.

view this post on Zulip Ben Visness (Sep 28 2026 at 19:33):

If you want, we could certainly do that in component-web-bindings and have an artifact for you to consume, but it seems like it would be nice one way or another to have some really concise bindings for that

view this post on Zulip Ben Visness (Sep 28 2026 at 19:33):

I guess I'm also curious to know what that artifact actually needs to look like

view this post on Zulip Alex Crichton (Sep 28 2026 at 19:34):

in the long-term I'd like to manage it similar to the WASI WITs where the artifact that wasi-libc consumes is some sort of published WIT, but no need for it to depend on C/H files or such, that'll get handled by wasi-libc's own wit-bindgen steps

view this post on Zulip Ben Visness (Sep 28 2026 at 19:34):

oh ok, so you literally only need WIT

view this post on Zulip Alex Crichton (Sep 28 2026 at 19:34):

in the meantime though if it's handwritten WIT I think that's totally fine, no need to jump to the end originally

view this post on Zulip Alex Crichton (Sep 28 2026 at 19:34):

yeah

view this post on Zulip Alex Crichton (Sep 28 2026 at 19:35):

and if it's easier to bootstrap by just copying/vendoring some files that's also fine IMO

view this post on Zulip Alex Crichton (Sep 28 2026 at 19:35):

just long-term I'd like it to be a curl-the-thing situation

view this post on Zulip Ben Visness (Sep 28 2026 at 19:35):

well that seems like a good way for me to get my feet wet one way or another

view this post on Zulip Ben Visness (Sep 28 2026 at 19:36):

Is there something I can build that will scream errors at me to guide me through this? Should I just take a crack at scaffolding a new target in wasi-libc somehow?

view this post on Zulip Alex Crichton (Sep 28 2026 at 19:37):

in theory the build steps should be cmake -S . -B build -DTARGET_TRIPLE=wasm32-webp2 -G Ninja && ninja -C build

view this post on Zulip Alex Crichton (Sep 28 2026 at 19:37):

and if you can get that working that's probably worth a PR heh

view this post on Zulip Ben Visness (Sep 28 2026 at 19:37):

we shall see what happens

view this post on Zulip Ben Visness (Sep 28 2026 at 20:24):

So...in this new world, we presumably don't have "command" or "reactor" interfaces at all anymore

view this post on Zulip Ben Visness (Sep 28 2026 at 20:25):

but that seems to be the first thing I'm crashing into with libc-bottom-half

view this post on Zulip Ben Visness (Sep 28 2026 at 20:25):

or would we exclusively be doing this "reactor"-style?

view this post on Zulip Ben Visness (Sep 28 2026 at 20:27):

I'm really not clear on why libc would care about such things

view this post on Zulip Alex Crichton (Sep 28 2026 at 20:31):

yeah that'd be my hunch -- you'd basically not include crt1-command.o and would only have crt1-reactor.o in the sysroot

view this post on Zulip Ben Visness (Sep 30 2026 at 13:55):

I'm making some progress but just slogging through cmake things. Trying to get to a point where it builds but literally everything is stubbed out to just trap.

view this post on Zulip Alex Crichton (Sep 30 2026 at 14:31):

makes sense yeah, and I figure that most functions are probably going to just return an error in the end

view this post on Zulip Ben Visness (Sep 30 2026 at 16:00):

well, time to pivot right back to wit-bindgen
image.png

view this post on Zulip Ben Visness (Sep 30 2026 at 17:48):

@Alex Crichton Could we cut a release of wasm-tools with getter/setter support?

view this post on Zulip Ben Visness (Sep 30 2026 at 17:49):

I can do the wit-bindgen updates right away...hopefully pretty easy since they're mostly just sugar for functions once they're validated

view this post on Zulip Alex Crichton (Sep 30 2026 at 17:52):

sure thing

view this post on Zulip Ben Visness (Sep 30 2026 at 17:55):

awesome! thanks

view this post on Zulip Ben Visness (Sep 30 2026 at 18:04):

What do I do with this new canonical_names parameter in wit-component? I'm having a hard time figuring out what it actually changes

view this post on Zulip Ben Visness (Sep 30 2026 at 18:04):

but it's showing up in a lot of places

view this post on Zulip Alex Crichton (Sep 30 2026 at 18:12):

set it to false

view this post on Zulip Alex Crichton (Sep 30 2026 at 18:13):

Yan Chen will work on plumbing that orthogonally

view this post on Zulip Ben Visness (Sep 30 2026 at 19:03):

of course now I find bugs in wasm-tools :upside_down:

view this post on Zulip Ben Visness (Sep 30 2026 at 19:04):

well...I will hack around locally and hopefully avoid multiple minor patches

view this post on Zulip Alex Crichton (Sep 30 2026 at 19:04):

cue disney animals signing a song about the circle of life

view this post on Zulip Ben Visness (Oct 03 2026 at 17:16):

Do we want any stdio in wasi-libc's webp2 mode? My gut says no, but then I look at all the occurrences of fprintf(stderr and just think...man, seems pretty stupid to ifdef every last one of them to console.error.

view this post on Zulip Ben Visness (Oct 03 2026 at 17:17):

But certainly we don't have stdin and the browser console is only vaguely like stdout.

view this post on Zulip Ben Visness (Oct 03 2026 at 17:17):

But also people will probably just want to printf.

view this post on Zulip Ben Visness (Oct 04 2026 at 04:00):

we are making PROGRESS
image.png

view this post on Zulip Ben Visness (Oct 04 2026 at 04:01):

through enough of the libc implementation to have linker errors for the various things I have stubbed out

view this post on Zulip Ben Visness (Oct 04 2026 at 04:01):

this has been a very pleasant little exercise so far, figuring out how to implement all the libc stuff we care about on top of web APIs

view this post on Zulip Ben Visness (Oct 04 2026 at 19:16):

[245/246] Generating sysroot/lib/wasm32-webp2/libc.a
mozilla@Bens-MacBook-Pro wasi-libc % echo $?
0

view this post on Zulip Alex Crichton (Oct 04 2026 at 22:48):

nice! FWIW I do think that stdio will want to get hooked up, at least stdout/stderr, as otherwise it's likely going to be a bit too overly onerous to port

view this post on Zulip Ben Visness (Oct 06 2026 at 14:13):

So I have a big TODO comment in there about how to handle entry points, and the upshot is that I think we need something that is halfway between Reactor and Command

view this post on Zulip Ben Visness (Oct 06 2026 at 14:13):

(eventually)

view this post on Zulip Ben Visness (Oct 06 2026 at 14:14):

Basically, importing a module should be allowed side effects, just like top-level code in JS today. That would naturally map to some kind of "main"-ish function in a language like C. But when that function exits the program isn't done and nothing should be torn down. Also it probably would have zero args.

view this post on Zulip Ben Visness (Oct 06 2026 at 14:15):

In my ideal world I imagine that in this reactor-plus-side-effects mode, the main function would get linked as a component-level start function with zero params and maybe at most a result<T> return value.

view this post on Zulip Alex Crichton (Oct 06 2026 at 14:26):

it might be worth seeing how Emscripten models this, and I agree that int main probably isn't the way to do this. The only thing I can think of is some sort of annotation which the toolchain slurps up, but that's not easy to implement AFAIK

view this post on Zulip Ben Visness (Oct 06 2026 at 14:27):

Right, and also I think a main function is the natural choice for code that "just runs", especially since we're moving toward a world where you can basically put an entire app in one wasm file. Maybe we should actually just figure out how to support command-style linking (and always provide argc=0)

view this post on Zulip Ben Visness (Oct 06 2026 at 14:28):

But also, if you are writing a game and your main function just goes into an infinite loop, idk how we're supposed to translate that to the web (something something JSPI?)

view this post on Zulip Ben Visness (Oct 06 2026 at 17:30):

So, I think I have wasi-libc far enough along to start moving on to clang itself. What roughly do I have to do there? I imagine clone wasi-sdk and just add some patches to somehow teach it about wasm32-webp2 and the new webp2 sysroot?

view this post on Zulip Ben Visness (Oct 06 2026 at 17:31):

(I don't think I'll actually attempt to merge my wasi-libc branch until I can validate that it works at all against a patched version of clang.)

view this post on Zulip Alex Crichton (Oct 06 2026 at 17:35):

yeah, the wasi-sdk build it split into "two cmakes" sort of where one builds clang and one builds the sysroot, so long as you're not changing clang you just need to build the sysroot where you specify your compiler as probably wasi-sdk-34

view this post on Zulip Alex Crichton (Oct 06 2026 at 17:35):

./ci/build.sh has everything combined together and you can tweak that script to run things locally

view this post on Zulip Ben Visness (Oct 06 2026 at 17:35):

Claude is telling me a clang patch will probably be necessary in order to teach it of the existence of a webp2 "OS"

view this post on Zulip Ben Visness (Oct 06 2026 at 17:36):

because of some jank about which paths it chooses to search

view this post on Zulip Alex Crichton (Oct 06 2026 at 17:36):

ah yeah that sounds about right

view this post on Zulip Alex Crichton (Oct 06 2026 at 17:36):

we currently model that with *.patch files which are applied to the submodule locally

view this post on Zulip Alex Crichton (Oct 06 2026 at 17:36):

it's a bit brittle

view this post on Zulip Alex Crichton (Oct 06 2026 at 17:36):

but you can just edit the submodule and make commits and worry about that at the end

view this post on Zulip Ben Visness (Oct 06 2026 at 17:37):

ah sure, that sounds good

view this post on Zulip Ben Visness (Oct 06 2026 at 18:05):

What is this config submodule within wasi-sdk? It's pulling from some gnu repo that isn't responding right now.

view this post on Zulip Ben Visness (Oct 06 2026 at 18:05):

Cloning into '/Users/mozilla/Developer/WebAssembly/wasi-sdk/src/config'...
fatal: unable to access 'https://git.savannah.gnu.org/git/config.git/': Failed to connect to git.savannah.gnu.org port 443 after 4055 ms: Couldn't connect to server
fatal: clone of 'https://git.savannah.gnu.org/git/config.git' into submodule path '/Users/mozilla/Developer/WebAssembly/wasi-sdk/src/config' failed

view this post on Zulip Alex Crichton (Oct 06 2026 at 18:25):

it's... honestly I have no idea

view this post on Zulip Alex Crichton (Oct 06 2026 at 18:25):

it's some thing for ./configure or something like that i never understood

view this post on Zulip Alex Crichton (Oct 06 2026 at 18:25):

I keep forgetting to turn that into a git subtree because that remote is super unreliable

view this post on Zulip Ben Visness (Oct 06 2026 at 18:25):

well I managed to build clang without it, so hopefully it's fine

view this post on Zulip Ben Visness (Oct 06 2026 at 21:10):

it's not fine

view this post on Zulip Ben Visness (Oct 06 2026 at 21:10):

I was able to do the initial set of clang updates, but I can't run the full wasi-sdk cmake unfortunately

view this post on Zulip Ben Visness (Oct 06 2026 at 21:10):

do you have a local checkout of the config stuff that you could zip up and send my way, or something?

view this post on Zulip Alex Crichton (Oct 06 2026 at 21:14):

if you try it now does it work? that server randomly goes offline and comes back up

view this post on Zulip Ben Visness (Oct 06 2026 at 21:14):

I have tried several times today with no success :/

view this post on Zulip Alex Crichton (Oct 06 2026 at 21:14):

config.tar.gz

view this post on Zulip Ben Visness (Oct 06 2026 at 21:14):

maybe I'm just unlucky

view this post on Zulip Alex Crichton (Oct 06 2026 at 21:14):

no it's a bad server lol

view this post on Zulip Ben Visness (Oct 06 2026 at 21:15):

I think that worked, thanks

view this post on Zulip Ben Visness (Oct 06 2026 at 21:18):

thankfully adding the target triple was easy

view this post on Zulip Ben Visness (Oct 07 2026 at 18:22):

Ben Visness said:

In my ideal world I imagine that in this reactor-plus-side-effects mode, the main function would get linked as a component-level start function with zero params and maybe at most a result<T> return value.

@Luke Wagner told me today that core wasm start functions should be sufficient for side effects, and that would probably remain compatible with the reactor approach generally. I remain a bit skeptical because what if the initialization work you want to do in some way depends on things that aren't yet instantiated in the component?

view this post on Zulip Ben Visness (Oct 07 2026 at 18:23):

It feels like a start function should run once the entire component is instantiated, although I can't actually think of an example right now

view this post on Zulip Alex Crichton (Oct 07 2026 at 18:30):

oh that actually might be core-wasm-start vs the _initialize export -- start isn't a great fit because when you run it your module's imports aren't hooked up yet (e.g. the indirect adapters needed for components), but the _initialize function is a toolchain convention that's run as soon as everything's hooked up, and as part of instantiation

view this post on Zulip Alex Crichton (Oct 07 2026 at 18:30):

so _initialize is run by a module's start section, just not the "main module"'s start section

view this post on Zulip Alex Crichton (Oct 07 2026 at 18:30):

IIRC ctors in C/C++ go into _initialize, but I could also be misremembering

view this post on Zulip Ben Visness (Oct 07 2026 at 18:31):

Alex Crichton said:

so _initialize is run by a module's start section, just not the "main module"'s start section

I don't quite follow, what's the difference? Is there one _initialize per core module in a component?

view this post on Zulip Alex Crichton (Oct 07 2026 at 18:32):

_initialize is a special core wasm export name recognized by wasm-tools component new (wit-component) which is handled specially by running it once the main module's imports are all hooked up

view this post on Zulip Alex Crichton (Oct 07 2026 at 18:33):

basically using start won't work b/c imports aren't hooked up (e.g. you couldn't call JS things), but using _initialize should work b/c imports are all hooked up

view this post on Zulip Ben Visness (Oct 07 2026 at 18:33):

What do you mean imports aren't hooked up? Core wasm start functions are perfectly capable of calling imported functions, aren't they?

view this post on Zulip Alex Crichton (Oct 07 2026 at 18:36):

it can yeah, but for example if you instantiate a core wasm module on the web it's generally not helpful to call imports from start b/c you can't have access to the exported memory of the module (instantiation hasn't finished yet). So in a sense while you can call imports in start that's not super useful.

For components when I say "hooked up" I mean the thing where if you import a component function that needs memory (e.g. returns or takes a string) then you have to instantiate the main module with a trapping shim first, and then afterwards you fill in the shim such that future calls work (the call_indirect table stuff). So when the main module is instantiated it has imports and can call them, but if they're called they all trap. Only after instantiation is the "fixup" module instantiated, and that module fills in all the shims where all future calls succeed

view this post on Zulip Luke Wagner (Oct 07 2026 at 19:12):

Ah, earlier I was saying that it was possible to call imports from start that use memory in pure WAT, which is technically true, but I forgot that wasm-tools component new does the call_indirect stuff instead which happens after start. So yeah, I guess you do want the _initialize after all; but it's called at component-instantiation-time, as-if it was a start function (I'm guessing via some helper core module that imports _initialize and calls it from its own start function) right?

view this post on Zulip Alex Crichton (Oct 07 2026 at 19:13):

right yeah

view this post on Zulip Ben Visness (Oct 07 2026 at 19:27):

Ok, that makes sense. I wasn't aware of _initialize but if that's already working for C++ constructors etc. then I don't see why it wouldn't work for general-purpose initialization too. Maybe we just need to designate how user code gets hooked up to _initialize.

view this post on Zulip Alex Crichton (Oct 07 2026 at 19:28):

double-check me on this, but I think C++ constructors in theory already "just work"

view this post on Zulip Ben Visness (Oct 07 2026 at 19:28):

That said, would a component start function allow us to elide the helper module with a core start function?

view this post on Zulip Alex Crichton (Oct 07 2026 at 19:28):

it would not

view this post on Zulip Alex Crichton (Oct 07 2026 at 19:28):

(still need the shim/fixup module to break the import cycle)

view this post on Zulip Ben Visness (Oct 07 2026 at 19:46):

Which import cycle is this?

view this post on Zulip Alex Crichton (Oct 07 2026 at 19:48):

canon lower needs a linear memory, the main module exports linear memory, the main module needs an import to be instantiated, the import is canon lower

view this post on Zulip Ben Visness (Oct 07 2026 at 19:49):

That makes sense generally, but I don't think I've seen that in my experiments...maybe I need to look again

view this post on Zulip Alex Crichton (Oct 08 2026 at 01:37):

oh man you're finding all the cranks to turn aren't you

view this post on Zulip Ben Visness (Oct 08 2026 at 01:37):

There are so many cranks

view this post on Zulip Ben Visness (Oct 08 2026 at 01:37):

and yet Claude would turn them all faster if it could

view this post on Zulip Ben Visness (Oct 08 2026 at 01:38):

I created a pre-push commit hook specifically to stop it from pushing on my behalf, and guess what it just did? It amended its commit to remove the Co-Authored-By line and pushed anyway

view this post on Zulip Ben Visness (Oct 08 2026 at 01:38):

all I want is for it to rebase and then NOT push before I review it

view this post on Zulip Ben Visness (Oct 08 2026 at 02:11):

Emscripten has support for not shutting down the program when main exits: https://emscripten.org/docs/tools_reference/settings_reference.html#exit-runtime

view this post on Zulip Ben Visness (Oct 08 2026 at 13:54):

So, one interesting point of jankness: because I am making the web builds default to the reactor model, main doesn't get executed, so main actually gets dropped most of the time in linking if provided, which is fine except that it totally breaks CMake's own checks like check_library_exists

view this post on Zulip Ben Visness (Oct 08 2026 at 13:54):

because apparently these functions just compile a tiny C file whose main calls a library function, and if it successfully links, it assumes the library exists

view this post on Zulip Ben Visness (Oct 08 2026 at 13:55):

but if main gets dropped, linking can succeed by accident even if the library does not exist, which can lead to bad cmake config

view this post on Zulip Ben Visness (Oct 08 2026 at 13:56):

I worked around this for the sysroot builds with:

-DCMAKE_EXE_LINKER_FLAGS=-Wl,--export-if-defined=main,--export-if-defined=__main_argc_argv

but it seems the same thing could affect general users of the webp2 target

view this post on Zulip Ben Visness (Oct 08 2026 at 13:56):

And it seems quite wrong to define such flags by default for normal SDK users

view this post on Zulip Ben Visness (Oct 08 2026 at 13:57):

...maybe this whole problem will just go away if I just hook up main to _initialize

view this post on Zulip Alex Crichton (Oct 08 2026 at 14:36):

I will say that the further the target diverges from looking like a posix-y thing the more readily issues like this are going to come up, this'll never be a fully posix-y target per se but some things will definitely be more major than others. Not that I know how to solve it per se, but we might want to brainstorm how best to keep at least the major things mostly posix-y

view this post on Zulip Ben Visness (Oct 08 2026 at 16:16):

For those wondering, the validation bug is that Firefox is complaining about a version suffix when an external ID is present (really when any attributes are present on the import name)

view this post on Zulip Ben Visness (Oct 08 2026 at 18:08):

we are instantiating!
image.png

view this post on Zulip Ben Visness (Oct 08 2026 at 18:15):

and crashing headlong into the lack of stdout

view this post on Zulip Ben Visness (Oct 08 2026 at 18:15):

all according to plan

view this post on Zulip Ben Visness (Oct 10 2026 at 04:51):

printf!
image.png

view this post on Zulip Ben Visness (Oct 12 2026 at 12:12):

printf that doesn't trap
image.png

view this post on Zulip Ben Visness (Oct 12 2026 at 14:38):

(I suspect this code is quite slow since it's some pretty naive UTF-8 code. It would be relatively easy to detect long runs of ASCII using simd and memcpy them.)

view this post on Zulip Ben Visness (Oct 12 2026 at 17:03):

Does anything in the component tooling run binaryen on the core modules inside the components?

view this post on Zulip Ben Visness (Oct 12 2026 at 17:03):

Surely people in the wasi space must do something like this?

view this post on Zulip Ben Visness (Oct 12 2026 at 17:05):

iostreams work but they bloat the component binary size to 3MB lol

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:07):

Nothing currently does, no

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:10):

The main reason IMO is that binary size matters far less in out-of-browser scenarios, not to the point of irrelevance but to the point that binaryen's wins haven't made it worth it to integrate. We've talked about possibilities in the past and have more-or-less never reached a state of "it's clearly worth it to do this".

view this post on Zulip Ben Visness (Oct 12 2026 at 17:11):

makes sense

view this post on Zulip Ben Visness (Oct 12 2026 at 17:11):

but, I might have to whip up a little wasm-component-opt wrapper

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:11):

the closest equivalent is to extract every core module, optimize, then put the core modules back -- but nothing automates this yet AFAIK. Components give a much more fine-grained liveness analysis for core wasm imports/exports which is also the next thing to hook up, so just the most naive version is still kind of far from what yu'd want

view this post on Zulip Ben Visness (Oct 12 2026 at 17:11):

mm, sure

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:12):

you should talk to @Till Schneidereit who's actually worked on precisely that and has a version somewhere which is IIRC LLM-coded and unreviewed but likely suitable for at least testing

view this post on Zulip Ben Visness (Oct 12 2026 at 17:12):

is there tooling yet that does that liveness analysis?

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:12):

not in wasm-tools, no

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:12):

and in general, probably not

view this post on Zulip Ben Visness (Oct 12 2026 at 17:12):

I've done similar for core modules themselves already actually

view this post on Zulip Ben Visness (Oct 12 2026 at 17:12):

https://github.com/bvisness/wasm-isolate

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:12):

it's not super difficult insofar as it's mostly just "you didn't alias out the thing therefore its dead", so in theory not too ocmplicated

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:13):

oh nice!

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:13):

IIRC binaryen has a similar command for extracting a function, but not as comprehensive as this and I haven't used the wasm-opt version in quite some time

view this post on Zulip Ben Visness (Oct 12 2026 at 17:13):

I forget what it does with imports and exports, it might just ignore those because I built it for testcase reduction

view this post on Zulip Ben Visness (Oct 12 2026 at 17:13):

but overall it's really quite simple

view this post on Zulip Ben Visness (Oct 12 2026 at 17:14):

and just uses wasm-tools' reencoding functionality

view this post on Zulip Ben Visness (Oct 12 2026 at 17:14):

if such a tool existed, would it make sense to integrate into the Rust tooling?

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:15):

I think that'd make a reasonable wasm-tools subcommand yeah

view this post on Zulip Ben Visness (Oct 12 2026 at 17:15):

oh, I meant the Rust toolchain support

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:15):

oh you mean wasm-opt?

view this post on Zulip Ben Visness (Oct 12 2026 at 17:15):

I know some wasm toolchains mysteriously auto-detect wasm-opt and run it when optimizations are enabled

view this post on Zulip Ben Visness (Oct 12 2026 at 17:16):

I can't say I like that but it is a thing they do

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:16):

yes that's what clang does, and AFAIK most of us consider that a bug and I've at least personally and intentionally not added that to rustc

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:16):

IMO wasm-opt should either unconditionally be run, or never run

view this post on Zulip Ben Visness (Oct 12 2026 at 17:16):

well then let's not reverse that decision :)

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:17):

but yeah in general there's no preexisting plan to add wasm-opt to rustc

view this post on Zulip Ben Visness (Oct 12 2026 at 17:17):

I think it's fine as a post-processing step or as part of a "bundler"

view this post on Zulip Ben Visness (Oct 12 2026 at 17:17):

tbh it would make perfect sense when slotted into typical web bundling workflows

view this post on Zulip Ben Visness (Oct 12 2026 at 17:17):

waaaay more sense there than in the compiler imo

view this post on Zulip Alex Crichton (Oct 12 2026 at 17:18):

that's what I've felt myself yeah

view this post on Zulip Ben Visness (Oct 13 2026 at 19:40):

what a wild suggestion
image.png

view this post on Zulip Alex Crichton (Oct 13 2026 at 19:41):

ezpz just write a browser

view this post on Zulip Ben Visness (Oct 13 2026 at 19:42):

It would be cool if eventually we can just run headless Firefox in CI or something, but obviously today is not that day

view this post on Zulip Ben Visness (Oct 13 2026 at 19:42):

or probably the SM shell would suffice

view this post on Zulip Alex Crichton (Oct 13 2026 at 19:42):

agreed yeah

view this post on Zulip Ben Visness (Oct 13 2026 at 19:44):

are we really about to implement clock_gettime on top of Date.now() on top of clock_gettime on top of whatever wasi does for clocks on top of clock_gettime?

view this post on Zulip Alex Crichton (Oct 13 2026 at 19:46):

:turtle: :turtle: :turtle: :turtle: :turtle: :turtle:

view this post on Zulip Till Schneidereit (Oct 13 2026 at 20:28):

I recently wrote my second fetch implementation in terms of wasi:http, which works in JCO's implementation on top of the browser's fetch implementation

view this post on Zulip Till Schneidereit (Oct 13 2026 at 20:30):

I guess that's two fewer layers, so clearly we should compile wasmtime to JS so we can run it in StarlingMonkey, complete with wasi:http

view this post on Zulip Alex Crichton (Oct 14 2026 at 18:30):

wit-bindgen is now published and should be usable in wasi-libc

view this post on Zulip Ben Visness (Oct 14 2026 at 19:40):

Great, will hopefully get that added soon. My mind is addled today for unknown reasons and I'm just trying to get through the testing stuff first.

view this post on Zulip Ben Visness (Oct 14 2026 at 20:54):

the current test failure is hurting my head and I think might be my main function decision coming back to bite me already

view this post on Zulip Ben Visness (Oct 14 2026 at 20:55):

it seems that, in a dynamic linking situation, the order of _initialize functions is currently determined by the order in which libraries were passed to wasm-component-ld (or wasm-tools component link or whatever)

view this post on Zulip Alex Crichton (Oct 14 2026 at 20:55):

oh are they all calling main?

view this post on Zulip Ben Visness (Oct 14 2026 at 20:57):

well possibly main is running more than once, which seems very bad, but also the actual issue right now seems to be:

view this post on Zulip Alex Crichton (Oct 14 2026 at 20:58):

oh yeah that'd do it

view this post on Zulip Ben Visness (Oct 14 2026 at 20:58):

it seems bad to depend on a particular order of _initialize

view this post on Zulip Ben Visness (Oct 14 2026 at 20:58):

so probably I shouldn't try and "fix" it that way

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:00):

one possible fix: undo the _initialize hack, go back to having crt1-command.o, use that for tests, but for the webp2 target it doesn't export anything it instead installs a static ctor

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:00):

some ctor w/ like a really low priority

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:01):

although hm I'm not sure that's right either...

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:02):

bah

view this post on Zulip Ben Visness (Oct 14 2026 at 21:03):

to clarify, the command model just exports a function called _start that the host is responsible for calling?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:03):

that's wasip1, for wasip2/3 it's a direct export of the component model wasi:cli/run function

view this post on Zulip Ben Visness (Oct 14 2026 at 21:03):

oh I see

view this post on Zulip Ben Visness (Oct 14 2026 at 21:04):

but still then the host will invoke that when it feels like it, it's not a start function

view this post on Zulip Ben Visness (Oct 14 2026 at 21:04):

and then there's no need for separate _initialize?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:04):

kinda yeah, _initialize is just a convention between toolchain/wit-component really

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:05):

interim fix is to probably just disable shared tests

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:05):

longer-term we probably want changes in wit-component to support this, for example _initialize priorities or some sort of _initialize_low_priority symbol

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:06):

although _initialize doesn't actually set anything up for libc.so it looks like?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:06):

it mostly exists to call __wasm_call_ctors but for libc.so that should be an empty function

view this post on Zulip Ben Visness (Oct 14 2026 at 21:07):

oh goodness crt1-reactor.o is being linked into libc.so

view this post on Zulip Ben Visness (Oct 14 2026 at 21:08):

which is why claude is badgering me about main running twice now

view this post on Zulip Ben Visness (Oct 14 2026 at 21:08):

this is all so dumb

view this post on Zulip Ben Visness (Oct 14 2026 at 21:11):

indeed libc.so has _initialize, which runs ctors:

  (func $__wasm_call_ctors (;189;) (type 0)
    call $__wasilibc_initialize_environ_eagerly
    call $__wasilibc_init_ssp
  )

and also calls __main_void again, which is clearly bad

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:14):

that might be the main bad part -- calling main twice - initializing the environment twice I think should be ok insofar as it should be somewhat idempotent

view this post on Zulip Ben Visness (Oct 14 2026 at 21:15):

well afaik the environment will only be initialized once because this code is owned by libc.so and therefore its version of __wasm_call_ctors is the only one that performs that

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:15):

true

view this post on Zulip Ben Visness (Oct 14 2026 at 21:15):

whereas __main_void is imported as "env" "__main_void"

view this post on Zulip Ben Visness (Oct 14 2026 at 21:16):

although confusingly libc.so does have its own __main_void

  (func $"#func203 __main_void" (@name "__main_void") (;203;) (type 8) (result i32)
    block ;; label = @1
      global.get $main
      br_if 0 (;@1;)
      i32.const 0
      return
    end
    i32.const 1
    global.get $__memory_base
    i32.const 205888
    i32.add
    call $main
  )

view this post on Zulip Ben Visness (Oct 14 2026 at 21:17):

(which is _not_ the one that gets called inadvertently from _initialize, this is a different one that is called at a time unclear to me)

view this post on Zulip Ben Visness (Oct 14 2026 at 21:18):

(actually this just ends up calling the imported __main_argc_argv, but it's not clear to me that anyone would ever call this particular __main_void?)

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:18):

there's some comments in libc-bottom-half/sources/__main_void.c for that I think

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:19):

so afaik that one's not called in libc.so typically

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:19):

in theory the import should somehow be tagged as a weak import for the dynamic linking conventions to kick in thre

view this post on Zulip Ben Visness (Oct 14 2026 at 21:25):

I think perhaps for a start I will pull away from running main in the reactor model and just tell people to use __attribute__((constructor)) for initialization / side effects. That will fix the "main runs twice" problem. Then we need to figure out how to keep cmake happy when it does its check_library_exists tests that require main to not be dropped from the executable...afaik we just need to ensure that it persists through linking, but not that it actually needs to be run. Then we will need to figure out how to rig up the test runner so that main does run, but presumably wasmtime can call an export or something.

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:27):

oh! how about this --

view this post on Zulip Ben Visness (Oct 14 2026 at 21:27):

command.o will still want to run dtors too though, no?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:28):

the webp2 target kind of doesn't have the concept of destructors really though

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:28):

so skipping that seems ok

view this post on Zulip Ben Visness (Oct 14 2026 at 21:28):

I'm actually just not sure what your second point means, does crt1-command.o even have _initialize? Or just wasi:cli/run?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:29):

not currently, it's just wasi:cli/run right now, but we've got the #ifdefs to do whatever in that file

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:29):

what I'm thinking is that it'd be a "special" _initialize

view this post on Zulip Ben Visness (Oct 14 2026 at 21:29):

will wasm-ld / wasm-component-ld plug in _initialize if it sees it?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:29):

yes

view this post on Zulip Ben Visness (Oct 14 2026 at 21:29):

I see

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:29):

(that's how it works with reactors right now)

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:30):

with your change every *.so tries to call main, but with this change only one will

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:30):

b/c crt1-command.o is in theory only linked once

view this post on Zulip Ben Visness (Oct 14 2026 at 21:30):

oh, because that's just a fundamental difference with -mexec-mode-command or whatever?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:31):

kinda yeah, it's basically a convention that only the "main program" gets crt1-command.o

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:31):

and everything else, if anything, gets crt1-reactor.o

view this post on Zulip Ben Visness (Oct 14 2026 at 21:31):

if we go back to command as the default for webp2, and even if we disable dtors, will that cause other problems with calling exports after "main" is finished?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:32):

in that situation, in theory at least, everyone's using a reactor

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:32):

or, well, hm, nah well in any case no

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:32):

we can construct it so it doesn't destroy state when main finishes in crt1-command.o

view this post on Zulip Ben Visness (Oct 14 2026 at 21:33):

from looking at the code I imagine that's just skipping __wasm_call_dtors()

view this post on Zulip Ben Visness (Oct 14 2026 at 21:33):

the rest is wasi-specific shutdown stuff we'd skip anyway

view this post on Zulip Ben Visness (Oct 14 2026 at 21:33):

oh, I'm looking at cli/run anyway

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:33):

yeah that sounds right to me

view this post on Zulip Ben Visness (Oct 14 2026 at 21:33):

I forgot we'd have a new function probably?

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:34):

convention with C is to add to the #ifdef soup (I jest)

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:34):

but realistically this'd just extend the #ifdefs to define the function

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:34):

and it'd be _initialize on webp2

view this post on Zulip Ben Visness (Oct 14 2026 at 21:34):

right instead of _start or cli/run

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:34):

and then dtors/exit would be only wasi targets

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:35):

in the limit what we'd ideally want is that if there are meaningful destructors then the component would export some sort of toolchain convention for "call me to invoke destructors"

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:35):

and that'd be opt-in-called if the embedding wanted to actually clean things out

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:35):

but that's pretty niche and can be deferred for later IMO

view this post on Zulip Ben Visness (Oct 14 2026 at 21:37):

so all this means I _can_ just keep using main for setup, huh

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:42):

and cmake-probes should all work by default too

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:42):

tests still have to hack around things to get wasi:cli/run exported but that's a wasm-tools compose bug

view this post on Zulip Ben Visness (Oct 14 2026 at 21:52):

error: failed to encode a component from modules

Caused by:
    0: library shared-compose-simple-resource-callee.wasm exports both `__wasm_call_ctors` and `_initialize`; expected at most one of the two

view this post on Zulip Ben Visness (Oct 14 2026 at 21:52):

this is when building tests...probably this is fixable

view this post on Zulip Ben Visness (Oct 14 2026 at 21:54):

I admit I don't know why __wasm_call_ctors is getting exported

view this post on Zulip Alex Crichton (Oct 14 2026 at 21:55):

yeah that seems... wrong

view this post on Zulip Ben Visness (Oct 14 2026 at 21:58):

I guess this is just what -shared does

view this post on Zulip Ben Visness (Oct 14 2026 at 21:59):

so the combination of dynamic linking and an explicit _initialize export is causing jank

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:01):

hm there's something else going on here though -- what about this is webp2 specific?

view this post on Zulip Ben Visness (Oct 14 2026 at 22:01):

explicitly exporting _start as _initialize

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:01):

but for libraries they shouldn't be using crt1-command.o

view this post on Zulip Ben Visness (Oct 14 2026 at 22:01):

like how it's exported as wasi:cli/run

view this post on Zulip Ben Visness (Oct 14 2026 at 22:01):

ah hm

view this post on Zulip Ben Visness (Oct 14 2026 at 22:02):

it could be leftover test framework jank

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:02):

that error itself is coming from wit-component it looks like

view this post on Zulip Ben Visness (Oct 14 2026 at 22:05):

I...I hate to do this, but can I just paste some claude output and you can tell me if it makes sense

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:07):

please do lol

view this post on Zulip Ben Visness (Oct 14 2026 at 22:07):

image.png

view this post on Zulip Ben Visness (Oct 14 2026 at 22:07):

ah I kind of thought this was built-in cmake stuff, but I see it is not

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:08):

hm... can you package this up and push it as a commit so I can repro/poke at it?

view this post on Zulip Ben Visness (Oct 14 2026 at 22:08):

pushed

view this post on Zulip Ben Visness (Oct 14 2026 at 22:09):

I feel we're probably very close one way or another, the whole library is building fine

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:10):

what cmake command to repro?

view this post on Zulip Ben Visness (Oct 14 2026 at 22:10):

here's my build script at the moment

#!/bin/bash
set -euxo pipefail

export CC=/opt/homebrew/opt/llvm/bin/clang

rm -rf build
cmake -S . -B build -G Ninja \
  -DTARGET_TRIPLE=wasm32-webp2 \
  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
  -DBUILD_TESTS=ON

ninja -C build bindings-webp2-edit
ninja -C build

view this post on Zulip Ben Visness (Oct 14 2026 at 22:11):

that export CC is probably a leftover :P

view this post on Zulip Ben Visness (Oct 14 2026 at 22:11):

this is an organically grown free-range build script

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:12):

bah I had to install a newer wit-bindgen

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:12):

well first I reset --hard to your wasi-sdk branch by accident

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:12):

error: no dependencies of component /home/alex/code/wasi-libc/build/p2web/test/compose-barge-in-caller.wasm were found

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:14):

ok nvmd fixed it

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:14):

well, got to the same error

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:20):

oh it's -fvisibility=default

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:20):

or not jk

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:29):

well I deleted the call to __wasm_call_ctors and it's still showing up

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:53):

ok so the issue seems to be that when wasm-ld is missing --entry=foo it just goes ahead and exports __wasm_call_ctors. That only became an issue with webp2 where it also exports _initialize. Passing --entry=_start seems to work because then wasm-ld doesn't auto-export __wasm_call_ctors.

There's one failing test with that where it directly references the environ symbol, and that's where things matter. Initialization of environ happens via a ctor, which means that libc's ctors must happen first, but the current test link order happens to run the main module's _initialize before libc's _initialize, and that means with the main module running main from _initialize it sees an uninitialized environ

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:55):

https://github.com/WebAssembly/wasi-libc/pull/883/changes/3f7379698ff8f2403f8eebf7f9494e51fb35f0f6 is an attempt

view this post on Zulip Alex Crichton (Oct 14 2026 at 22:55):

tbh these tests are built in a bit of a weird manner so reordering things isn't the end of the world

view this post on Zulip Ben Visness (Oct 14 2026 at 23:07):

Just as long as it doesn’t cause trouble for users, I guess

view this post on Zulip Alex Crichton (Oct 14 2026 at 23:21):

that's probably a bit TBD, but otherwise this I think is only related to dynamic linking which is already quite a reach goal for this iteration of webp2 I'd expect

view this post on Zulip Ben Visness (Oct 15 2026 at 21:11):

Ok, aside from utf-8 stuff, I think wasi-libc is in good shape

view this post on Zulip Ben Visness (Oct 15 2026 at 21:12):

did you have any particular desires for how the utf-8 stuff would be handled / merged with the existing validation in file_utils.c?

view this post on Zulip Alex Crichton (Oct 15 2026 at 21:13):

nah I mostly just wanted to flag it in case it duplicated things, how exactly it fits together I haven't thought too closely and would be happy to defer to you

view this post on Zulip Ben Visness (Oct 15 2026 at 21:14):

I'm not sure there's a very sensible way to unify them because validating and sanitizing are rather different logically and also both are less than 100 lines of code

view this post on Zulip Ben Visness (Oct 15 2026 at 21:14):

but maybe I can at least put them next to each other

view this post on Zulip Alex Crichton (Oct 15 2026 at 21:15):

that sounds reasonable yeah

view this post on Zulip Ben Visness (Oct 15 2026 at 21:31):

ok utf-8 stuff is now done too

view this post on Zulip Ben Visness (Oct 15 2026 at 21:32):

all the stdio was reworked to use the descriptor table, and now we support dup as well

view this post on Zulip Alex Crichton (Oct 15 2026 at 21:34):

nice I'll take a look probably tomorrow for review

view this post on Zulip Ben Visness (Oct 19 2026 at 16:36):

@Alex Crichton, what would you think of continuing to report errors to the browser console using reportError (which generates a stack trace + clearly says "not supported yet") but also trying to implement APIs with EINVAL returns and the like?

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:40):

Personally I'd prefer if that were gated behind some sort of -DFOO passed to CMake to make it conditional in the build of libc itself -- suitable for development of libc but not showing up for anyone else

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:40):

but that sounds ok otherwise

view this post on Zulip Ben Visness (Oct 19 2026 at 16:41):

Would the usual NDEBUG be acceptable?

view this post on Zulip Ben Visness (Oct 19 2026 at 16:41):

or is that really for other things

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:42):

personally I'd prefer a new one, and I'd frame it as not necessarily webp2-specific per se

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:42):

something like -DLOG_UNSUPPORTED_CALLS=ON or somethign

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:42):

and that'd just delegate to fprintf(stderr, "...")

view this post on Zulip Ben Visness (Oct 19 2026 at 16:43):

on all platforms or just non-webp2 platforms? because I really do want stack traces

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:44):

with a -D it's pretty flexible -- perhaps a trap on all platforms?

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:45):

basically I think by-default things should be libc/posix-ish, and then ideally target-specific code is minimized, and then after that it's kind of whatever works

view this post on Zulip Ben Visness (Oct 19 2026 at 16:47):

Yeah, that makes sense. Do you have any concerns about __wasilibc_report_error being consistently used for -DLOG_UNSUPPORTED_CALLS? I set that up early on in the wasi-libc work to just to go fprintf(stderr) on non-web platforms and reportError on web, which I feel gives the best ergonomics for each platform (as far as I know for wasi, anyway)

view this post on Zulip Ben Visness (Oct 19 2026 at 16:49):

The other thing I wanted to mention is that I'm actually going through and auditing what Emscripten does for various APIs so we can have that as a point of reference. I suspect mirroring Emscripten's behavior is the past of least breakage for this component preview, although some of their decisions are Very Interesting (e.g. stdin pops a dialog box using window.prompt apparently)

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:55):

yeah that I think makes sense to me, consistent __wasilibc_report_error with a target-specific definition

and yeah that sounds quite reasonable to audit against Emscripten!

view this post on Zulip Alex Crichton (Oct 19 2026 at 16:55):

whether or not we match everything perfectly... I think we could leave some of that to interpretation

view this post on Zulip Ben Visness (Oct 19 2026 at 18:06):

Alex Crichton said:

personally I'd prefer a new one, and I'd frame it as not necessarily webp2-specific per se

Hey what do you know, there are already calls that can make use of this
image.png

view this post on Zulip Alex Crichton (Oct 19 2026 at 18:07):

wat

view this post on Zulip Alex Crichton (Oct 19 2026 at 18:08):

I had no idea...


Last updated: Oct 31 2026 at 23:03 UTC