-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ergonomics for codegen #169
Comments
Sorry for the delay, but PRs for these would definitely be welcome! FWIW |
Happy to work on this (exploring using walrus as a compiler backend as well). There's already a We will have to emit a proper error on trying to emit an uninitialized function instead of panicking, as it's now a valid error. If that sounds good, I'll start a PR |
After looking at the code some more, the error handling is actually the tricky bit. Right now |
Bump @alexcrichton |
Motivation
Hi again, I'm continuing my use-
walrus
-as-a-compiler-backend adventure, and there's a couple things that have caused me some grief. After thinking about it more it feels like this is becausewalrus
is currently mostly designed to take some existing wasm module as input and do stuff to it, and less to generate these modules from whole cloth. However, it's currently still the best crate available for generating wasm, as unlike most it a) is actually up to date and feels like the developers actually use it, and to a lesser extent b) is really nice because it does a lot of the accounting of identifiers and stuff for you.However, this accounting has also caused me grief a few times. Most notably:
FunctionId
's before I have a body for the function, for example to do forward references. Iffoo()
callsbar()
andbar()
isn't yet defined, it's a lot easier for the compiler to do a pre-population pass through the code and say "I know aboutbar()
, here's the type andFunctionId
for it" than it is to then go back and fix up every reference tobar()
with a real address/FunctionId
. But the only way to do that I've found is to create aFunctionBuilder
, finish it immediately to get theFunctionId
, and then re-acquire theFunctionBuilder
from theFunction
and carry on actually generating code for it... but theFunctionBuilder
then mutably borrows part of theModule
, and working around that gets rather painful rather fast. Possible, but painful. Other ID types tend to have the same problem to a lesser extent.Table
and populating it with functions is a pain, mainly just 'cause you're doing everything by hand and have to juggle two or three different sections -- functions, tables and elements. I expect creating memory and data segments to be similarly annoying. Having a builder type or such for those would make life a lot easier.Proposed Solution
I'd happily try to make a PR for a
TableBuilder
andMemoryBuilder
type, if you wanted. Seems easy enough, even if I have no idea whatElementKind
actually is -- can't find any references to that in the wasm spec, so I assume it's newer stuff that hasn't been finalized yet. My existing code is halfway there already.As for the function stuff, I'm not sure what the best course of action is. One could make a function to reserve a
FunctionId
and then use it later to actually build the function. You could make it possible to kindasorta "disconnect" aFunctionBuilder
from a particularFunction
, changing the reference into anRc
or something, or perhaps more simply just make it possible to create aFunction
, then later replace its body with a new, freshFunctionBuilder
you've created. Actually this might be possible withInstrSeq
, but I don't quite understand how that portion ofwalrus
works yet.Alternatives
Don't do this, I guess? This is work I need to do anyway, so I might as well design it to be upstreamed if you guys want it. I could contribute some extra docs or examples if you prefer, since the existing ones are a little minimal.
The text was updated successfully, but these errors were encountered: