-
Notifications
You must be signed in to change notification settings - Fork 705
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
wasm2c's wasm-rt.h documentation #1949
Comments
Sounds reasonable that we should at least document this. For (1): Perhaps we should phrase it as "these are the compilers and environments where wasm2c is know build/run". Currently the would be mac, linux and windows and building with clang, gcc, msvc. Try to target any other OS/environment or use any other compiler and you may face porting efforts. Obviously if you want to add another environment "the linux kernel" that would be great! For (2): I guess this is just a matter of fleshing out the current README For (3): I think all we can /should do is to build and test in our supported targets/environments. If you are using an unsupported environment it would be up you to deal with any changes introduced by new wasm2c versions (or pin an older version until the new version is ported). As we make changes to wasm2c we would work to ensure that that new code works on all the know/supported targets, but I don't think we can make guarantees about targets we don't know about. |
Thanks for the quick answer :)
I would be quite happy to do that provided that my experiment succeeds and that I can actually use wasm2c for what I need. The actual use case is:
The reason I was investigating wasm2c rather than just making rustc output a static archive and linking to the module is to be able to build the module without a rust compiler. This is because the said module is compiled "dynamically" by a Python environment, and I'd like to avoid breaking users flow by requiring a recent rust toolchain: The challenges are:
Most of these problems can be solved if wasm2c's generated code calls/includes a user-implementable helper instead of libc functions directly, but the last one seems like a blocker. Either:
// Function returns type T
struct bar_res {
bool excep;
T value;
};
struct bar_res bar() {
if (1)
// "raise" an exception
return ((struct bar_res){.excep = true});
else
// return a value in the normal path
return ((struct bar_res){.value = 42});
}
struct foo_res {
bool excep;
T2 value;
};
struct foo_res foo() {
struct bar_res x = bar();
if (x.excep)
// "re-raise" the exception, with the right type
return ((struct foo_res){.excep = true});
T _x = x.value;
// proceed as usual
} Since C does not have generics or templates, this requires generating a "struct res" type for each possible return/exception types combination. An extra annoyance is that C does not have any usable zero-sized type that could be used to annihilate the struct overhead in case the function does not raise any excep. Either we use a small type like Another simpler solution if there is no threading or coroutines is to just have a global "exception" variable and return plain values. The check can be elided for functions known not to raise. When it comes to CI, building a hello world kernel module for the booted kernel is pretty easy on most distro so that should not add a lot of burden. We just need to enable enough warnings as errors to ensure we don't call any function without prototype. Otherwise the module will link successfully but fail to load because of missing symbols (which we probably won't test as it requires root and is likely forbidden on container-based CIs) EDIT: fix code formatting |
My understanding is that the runtime files included in the wasm2c directory (https://github.com/WebAssembly/wabt/tree/main/wasm2c), i.e. wasm-rt.h, wasm-rt-impl.h, and wasm-rt-impl.c, are meant to be taken as an example runtime that demonstrates how to host the wasm2c output on a basically-POSIX or Win32 user environment. E.g., wasm2c's generated output itself doesn't depend on setjmp/longjmp/malloc/free or I agree we should keep the README up-to-date about what the wasm2c-generated output requires from the runtime, which I agree is nonobvious today (e.g. if exceptions are enabled, right now the wasm2c output expects the runtime to define something called a "jmp_buf") but I think what we want to be documenting here, and the spirit of the existing README, is the interface between the wasm2c output and the runtime, not the interface between the included runtime (wasm-rt.h, wasm-rt-impl, etc.) and the OS. |
So after a bit more investigation:
|
Once you get it working you would wrap those includes in |
wasm-rt.h is not fully documented on the following points, which is an issue when evaluating wasm2c for embedded targets (or any project that cannot rely on wasm-rt-impl.c):
What headers generated code and wasm-rt.h are depending on ? E.g. currently wasm-rt.h depends on
#include <setjmp.h>
. While standard, embedded targets such as linux kernel modules do not provide such facilities.What will the generated code require from wasm-rt.h exactly ? The doc lists some of them, but the actual header declares extra functions such as
wasm_rt_set_unwind_target()
Backward compatibility promise (or lack of) for all of the above. If tomorrow wasm2c generated code starts depending on new headers/functions, that can break a whole workflow without hope of repair. In the linux kernel module case, anything that would require an arch-specific implementation (e.g setjmp.h) is out of scope for most projects as the maintenance burden would be way to high.
Just to be clear, I'm not saying that wasm2c should promise any of the above if it's not possible to (e.g. future evolutions of wasm/wasm2c capabilities) but having a statement either way would help people evaluating the use of wasm2c for a project.
The text was updated successfully, but these errors were encountered: