Stream: general

Topic: Advice on merging/composing modules for a DSL targeting wasm


view this post on Zulip Nathaniel Cook (Aug 22 2025 at 20:42):

I am building a DSL (domain specific language) that targets WASM directly. I need some direction on the module system within the language itself. I am struggling to find a solution to compile each module and combine them into a final root component.

My basic approach so far has been to compile each source file of the DSL to it's own core wasm module. From there I see three paths forward.

Convert each core module to a component and use straightforward composition. Aka dynamic linking to construct the root component.

Link each core module in a shared everything linking approach and then make a new component from this linked module.

Write custom code to merge core modules making assumption unique to my DSL. This is vague and not entirely sure where I'd start.

I have tried the first two and ran into challenges that made me think I am going about this incorrectly.

For the component composition strategy this means I need a WIT for each source file of the DSL. I can derive this but found it difficult as it seems I need to generate wit text programmatically and then immediately parse it. Additionally my DSL has generics and monomorphization so depending the program there will be unique wit definitions. Given that I believe my language features are amenable to link directly in a shared everything mode this approach seems backwards.

However for the dynamic linking approach I ran into issues about the GC proposal not being supported. I use basic structs etc from the GC proposal. Is there anything fundamental about GC features that means a shared everything linking strategy will not work? Or is it simply not implementing yet? I am using the Rust wit-component crate.

Anyone have some general advice on how to think about this challenge? I am new to many of these concepts so any good reading would also be appreciated.

view this post on Zulip Chris Fallin (Aug 22 2025 at 20:46):

Ordinarily/usually, components are seen as a trust boundary, and the copying semantics across the boundary means that they might not be the best fit for "individual module in source language": my expectation as a developer with most languages is that I can freely refactor code into modules and submodules and move things around with ~zero impact on the cost function. So personally I'd rule out the component-per-source-module approach unless you have some fairly unique requirements

view this post on Zulip Chris Fallin (Aug 22 2025 at 20:47):

I suspect that you'll want to address the "separate compilation" question in general first -- i.e., decide what processing can happen per module and what needs to happen when you see the whole program. That can have some surprising subtleties, especially around things like generics/monomorphization, or inlining, or ...

Then once you know this, you'll have a better idea whether you want "just a Wasm linker, but one that understands GC" (that seems like a thing that should exist and probably the gaps just haven't been filled in yet?) or "LTO step that does more custom stuff"

view this post on Zulip Pat Hickey (Aug 22 2025 at 20:48):

clang uses a special .o format for wasm that is, internally, a wasm module with custom sections describing relocations, and clang's wasm-ld links those into a single module

view this post on Zulip Nathaniel Cook (Aug 22 2025 at 20:48):

Thanks, I agree and to be clear there will be a separation between source files and modules but left those details for simplicity

view this post on Zulip Pat Hickey (Aug 22 2025 at 20:49):

and chris is probably about to explain this but theres WIP for creating a canonical abi for GC proposal types. until then, you cant use gc types at component boundaries, you'd have to serialize into a memory and then use memory for canonical abi

view this post on Zulip Chris Fallin (Aug 22 2025 at 20:49):

That as well! (fitzgen has been leading that -- won't tag him but feel free to if questions)

view this post on Zulip Nathaniel Cook (Aug 22 2025 at 20:50):

Is there anything written up yet that I can read?

view this post on Zulip Chris Fallin (Aug 22 2025 at 20:50):

that probably falls under "tag him if questions" -- I'm not aware of any public writeups yet

view this post on Zulip Pat Hickey (Aug 22 2025 at 20:51):

https://github.com/WebAssembly/component-model/issues/525

Pre-Proposal: Wasm GC Support in the Canonical ABI This issue proposes extensions to the Component Model's Canonical ABI for Wasm GC support and describes some of the motivation for particular choi...

view this post on Zulip Chris Fallin (Aug 22 2025 at 20:51):

if this is all in one trust domain, though, I'd gently nudge away from that and toward shared-everything linking with GC -- to your question

Is there anything fundamental about GC features that means a shared everything linking strategy will not work? Or is it simply not implementing yet?

it should be possible to merge GC type sections the same way wasm-ld merges data, functions, and other entities -- likely it's "just" a matter of extending it, nothing fundamental.

view this post on Zulip Nathaniel Cook (Aug 22 2025 at 20:54):

Ok excellent, yeah it's all one trust domain and using shared everything seems simpler in my case. I'll give it a try. Thanks for the advice and context


Last updated: Dec 06 2025 at 05:03 UTC