Open lann opened 2 months ago
@ospencer it looks like I could use some of those pointers... :sweat_smile:
Unfortunately due to #2152 I can't run with --debug
, but manually poking around at the names section it looks like:
<wasm function 5> -> _ZN136_$LT$wasi_snapshot_preview1..bindings..wasi..io..streams..InputStream$u20$as$u20$wasi_snapshot_preview1..bindings.._rt..WasmResource$GT$4drop4drop17h2cb53bfcb8abc006E
<wasm function 19> -> wasi:cli/run@0.2.0#run
(82 and 83 don't have names)
Edit: Wrong symbols here; ignore this
Ah this is two separate errors smushed together:
GrainExceptionError: failed to run main module `hello.component.wasm`
GrainException
(from the Grain runtime) + Error: failed to run ...
(from Wasmtime)
I was helping @lann debug this a bit and I'm definitely new here to Grain so take this with a grain of salt. From the component/adapter side of things, however, one major thing that the adapter will do which Grain may not be expecting is that it will use memory.grow
to allocate a wasm page for itself to place all its intermediate data within. This happens before Grain is invoked because at the component level the adapter is the entrypoint and then that delegates to Grain itself.
It looks like Grain's allocator will use memory.size
to determine the initial size of the heap which, if this is true, ends up being incompatible with the adapter. This can be solved by either (a) exporting a cabi_realloc
function from the core Grain module (which the adapter will call to allocate memory and then that'd initialize everything correctly) or (b) updating the malloc implementation to have a different heuristic for determining the initial size of the heap. With LLVM and wasm-ld
the (b) solution looks like using the __heap_end
symbol as the end of the heap. This solution though is wasm-ld
specific and may not be easily applicable to Grain, however.
@lann I've got this repository here which has a couple of examples of Grain components: a basic command component, a wasi:http/proxy one, and a wasi:http/imports one. https://github.com/ospencer/grain-components
Each of the subfolders has a basic README with instructions on how to compile the Grain modules and then the right wasm-tools
invocation.
@alexcrichton is exactly right—the compiler doesn't export cabi_realloc
itself, but if bindings are generated through wit-bindgen it will. There's an experimental grain
branch on this fork that you can use to generate bindings from wit: https://github.com/grain-lang/wit-bindgen/tree/grain
Finishing up the bindgen/documenting it all/baking it into the toolchain has been on the TODO list for awhile 😅
But this should all work!
Ah this is two separate errors smushed together:
GrainExceptionError: failed to run main module `hello.component.wasm`
GrainException
(from the Grain runtime) +Error: failed to run ...
(from Wasmtime)
This'll happen because Grain's initialization code runs as a part of _start
. --use-start-section
will instead move it to a start section to guarantee it's called at the right time. IIRC Rust and some other languages will just make sure any initialization code has been run whenever an export is called. We've discussed this but haven't implemented anything just yet.
If you run into other issues, feel free to ping me here or on Discord/Slack!