Stream: compiler development

Topic: zig compiler - WASM


view this post on Zulip Luke Boswell (Mar 19 2025 at 00:20):

I think we should add a CI test that builds the compiler for a WASM target -- to ensure we maintain this as an option for embedding roc in future.

Currently we can't build for WASM due to using realpath, but it's only in a few places -- in coordinate I think.

I've somewhat isolated those using a (very average) abstraction, but it would be good to sort this out now because it might get painful later to change.

Is this something anyone would like to look at?

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:14):

Wasm in this case should be wasm32-freestanding-none?

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:17):

Or are we targetting wasm32-wasi-musl and something like wasmer js sdk

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:17):

I'm not sure. For embedding the roc compiler in WASM -- we would need a way to provide things like files etc.

I guess we could compile to WASI...

My concern is that we add more features over time and it becomes harder to embed the compiler in a WASM context.

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:18):

I'm not sure we need to fully abstract things like files now, but we at least want to isolate those somehow.

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:18):

If the goal is the web repl, we don't need files at all.

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:18):

Yeah, I can imagine things like REPL or interpreter running in WASM

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:18):

Though I guess it might be nice to import from github via the web repl

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:19):

Or even the formatter, or eventual LSP maybe.

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:19):

Anyway, I think we have to work via wasm32-freestanding-none if we want to run in the browser with no dependencies. In that case, roc won't be an executable at all. It will be a library and js will have to fill in filesystem hooks.

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:20):

Yeah, not sure how we do that. Or would that just be libroc?

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:21):

Yeah, we probably want to make a root.zig and a library form of roc.

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:21):

Looks likes all issues today are around filesystems and time measurement

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:23):

Oh, though timing is for the cli, so it won't be in the library at all

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:23):

So yeah, I think it is just either making the library level not interact with the filesystem (assume all data is already loaded), or make it abstract away the filesystem (likely nicer and more flexible).

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:24):

So shouldn't be too bad

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:24):

Yeah, it was the filesystem and also specifically our use of "paths" that I'm concerned about

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:29):

I guess porting the formatter to the filesystem api, making a dummy filesystem for wasm (can be totally unimplemented), and adding wasm to ci, would at least stop any new problematic code from being created.

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:30):

Yeah something like that was what I was thinking.

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:31):

Though I'm not sure what the right api to cut for wasm is. Like can the current api reasonably be implemented in a browser?

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:32):

The API for the (internal) compiler functionality?

view this post on Zulip Luke Boswell (Mar 19 2025 at 01:33):

Like load and typecheck this roc module? or format this file?

view this post on Zulip Brendan Hansknecht (Mar 19 2025 at 01:54):

The file api. Cause we expect that it will be implemented in the browser by js

view this post on Zulip Brendan Hansknecht (Jul 10 2025 at 02:22):

We might want to seriously consider getting roc check and roc format working in the browser now. That likely will help with a lot of pain that would come later.

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:44):

I was literally just thinking about posting this also

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:45):

I was thinking about moving our Filesystem abstraction into a toplevel file called io.zig and isolating all IO must go through that.

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:45):

And to prove to myself it works, I was going to make a WASM build of the compiler

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:45):

I was thinking WASI for ease of use, but WASM should be doable also

view this post on Zulip Richard Feldman (Jul 10 2025 at 02:47):

yeah WASM seems best

view this post on Zulip Richard Feldman (Jul 10 2025 at 02:47):

e.g. for roc repl and the playground

view this post on Zulip Richard Feldman (Jul 10 2025 at 02:47):

WASI feels like a leaky abstraction we shouldn't need to depend on

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:48):

It's easy to build a WASI binary though and share a .wasm file that anyone could run using a WASI runner like wasmer etc

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:48):

I was just thinking for validating the implementation, not adding a new compile target or setting up anything in CI

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:49):

Though... I wonder how hard it would be to parse S-expressions in JS land ... :think-smart:

view this post on Zulip Brendan Hansknecht (Jul 10 2025 at 02:49):

not adding a new compile target or setting up anything in CI

We definitely should setup a build once it works so it doesn't regress.

view this post on Zulip Brendan Hansknecht (Jul 10 2025 at 02:50):

And yeah, wasmer as a starter target so you don't have to mock all the api's sounds reasonable, but doesn't wasi just give you standard io primitives, so it won't guarantee all io goes through io.zig?

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:52):

It doesn't guarantee that everything foes through io.zig, but it would ensure everything is working. To prevent regressions I was thinking a simple lint or script that looks for anything std.io, std.fs, std.posix etc that isn't in src/io.zig and fails CI

view this post on Zulip Brendan Hansknecht (Jul 10 2025 at 02:53):

I don't think it is just std io. But that is the core of it.

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:54):

Yeah, I think we're on the same page.

view this post on Zulip Brendan Hansknecht (Jul 10 2025 at 02:54):

also threading and I believe atomics and mutex and such.

view this post on Zulip Luke Boswell (Jul 10 2025 at 02:55):

Also I've wondered if there's good debug tooling out there in WASM land that might help us understand / isolate memory issues and the like.

view this post on Zulip Brendan Hansknecht (Jul 10 2025 at 02:56):

Anyway, yeah, cut it however you like. I still think. any new supported target should be added here 100%:
https://github.com/roc-lang/roc/blob/c3f320e58be57d21e12ccc82246ff738cb647f91/.github/workflows/ci_zig.yml#L139-L148

view this post on Zulip Kiryl Dziamura (Jul 10 2025 at 10:26):

debug tooling in wasm land

In our company we work on wasm obfuscator in rust. Recently we came across a super subtle bug in memory obfuscation in prod builds. Turned out we missed an operation in memory encryption on wasm pages boundaries. It was a needle in haystack. A week of work of three developers. The only thing helped us is reproduction in debug build (we had to randomize obfuscation seed in a loop till bug is reproduced) so we kept only memory obfuscation. We had a pretty readable wat and just stepped trough the bug. I'm sure dwarf could also help but we found the root cause sooner.
Long story short we didn't find anything meaningful that could help us with memory analysis of wasm. Only browser devtools. But we're tied to browser environment with gluecode in js so we didn't have many options to explore.


Last updated: Jul 26 2025 at 12:14 UTC