-
Notifications
You must be signed in to change notification settings - Fork 291
Adjust allocation strategy for TinyGo-derived modules so they don't immediately crash. #2243
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
base: main
Are you sure you want to change the base?
Conversation
ae8999b
to
e0b816e
Compare
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
0986d4b
to
77891db
Compare
…mmediately crash. You can run the TinyGo empty project in Viceroy now (once Viceroy is updated to depend on the new wit-component herein); it immediately crashed before. It serves a request and returns a 0 exit code, somewhat obscured by a backtrace because an empty project doesn't implement a Reactor. The crux of this update is that the GC phase of adapter application now takes a `ReallocScheme` arg to its `encode()` method. This represents slightly richer advice on how to find or construct a `realloc()` function for the adapter to use to allocate its state. Before, it took only an `Option`: `None` meant "use `memory.grow`", and `Some(such_and_such)` meant "use a realloc function called `such_and_such`, provided in the module being adapted". Now we can also say "construct a realloc routine using the given malloc routine found in the module being adapted". This lets us communicate to TinyGo's GC that we have reserved some RAM, so it doesn't stomp on us later.
…loc if the former is provided. This allows TinyGo programs to take control over reallocation if they desire, elevating an explicit API over the heuristic identification of `malloc()`. It turns out it was already doing this, through the call to `realloc_to_import_into_adapter()`, which returns an (even more specific) `cabi_realloc_adapter()` if there is one and otherwise `cabi_realloc`.
In this case, we have no non-crashing way of allocating memory for the adapter state.
77891db
to
be6af98
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you detail a bit more here why this is necessary? We've so far survived with zero language-specific configurations/hacks (AFAIK) throughout component toolchain tooling and personally I'd like to see it remain that way. More specifically, why can't this be fixed in the Go-specific tooling? Or why can't this be an opt-in option that the Go tooling passes?
Absolutely! Basically, we would like to run existing TinyGo-compiled modules as components. So, while an upstream fix would be ideal for the future, we have a back catalog of compiled artifacts to somehow make work. TinyGo makes an assumption in its memory management that violates no specs but conflicts with assumptions made by the The fix for new code should be something like having TinyGo export a Of course, it would be perfectly possible to pre-process our TinyGo modules outside wit-component: we could inject the same manufactured
Alternative solutions are most welcome! But others we could gin up were ickier, and hopefully WASIp2 will relegate all this to an historical footnote. |
I agree this is probably the best place to solve this, but to put this into context as a reviewer:
It unfortunately also doesn't help that the This can then also all be coupled with the fact that while we all want components to work generally there's still a needle to thread in what's supported where. While I don't believe this PR is doing this, at one extreme it's not reasonable to saddle an open source project with all the legacy burdens and baggage of a specific embedding. The other extreme of blissfully ignoring reality is also not appropriate for an open source project as well, and inevitably the balance is going to be somewhere in the middle. At the end of the day if no one knows how or is willing to update the TinyGo toolchain that's an extremely burdensome requirement to carry. Support for a new platform like components is almost always best done with a give-and-take style approach where embedders, toolchains, languages, etc, are all in a balance of what concerns are handled where. If a toolchain cannot budge from a single position then it, in my opinion, needs to be an extremely high value target to justify saddling everyone else with that burden. Basically this is my rationale for "I think this is best done with an opt-in flag". I don't want the baggage here to proliferate to other toolchains and other languages by default. We already have a means of solving the problems you're encountering for other languages and for a variety of reasons it sounds like TinyGo and/or the surrounding support isn't going to implement those solutions. Given that, I at least personally believe that from an open source project perspective the best way to support this is to land this here but behind an off-by-default flags the explicitly requires users to activate. That's where documentation can be updated etc. On the slightly more technical front, I'm more-or-less taking you at face value that this is the best place to solve this. I do not personally have the energy to boot up on everything TinyGo-related and see if I have a different way forward for this. From my current understanding I don't know, for example, if this is a temporary hack for preexisting modules or a permanent feature intended for all future productions of TinyGo modules. If the former, just for preexisting modules, that feels understandable to me. If the latter, all future modules, I don't really have any intuition for why that is the case. |
Tests are on the way! I had hoped to have them laid in before anyone got around to reviewing, but they proved trickier than expected, and my attention was divided. I apologize for the delay. Please feel free to look away while I finish them. I will turn this back into a Draft until then. For this PR's motivation and problem statement, beyond what's in the initial commit message, I'd reference this comment block in I share your concern that
It's just for preexisting modules. New builds should target WASIp2, e.g.
The TinyGo wasm toolchain is well maintained, having p1 and p2 support as well as a dedicated maintainer on Fastly's staff. I think any ambiguity about the allocation of responsiblity among tools is an accident of timing. As I understand it, providing
Me neither. That's why the baggage is so narrowly scoped. It activates only (1) if TinyGo is in the producers section and (2) no Let me know if I can fill in more details about anything, and I'm eager to hear your feedback either way. (Take your time, as I'll be out Thursday and Friday.) Thanks! |
Should fix fastly/Viceroy#491. Please see that (plus commit messages) for context.