prep / wasmexec

Implementation of wasm_exec.js for Go Wasm runtimes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

example with custom import

codefromthecrypt opened this issue · comments

Users can define their own "go" module function imports by defining a func
without a body in their source and a%_wasm.s or %_js.s file that uses the
CallImport instruction.

The compiler chooses a naming prefix of "main.$funcName", if defined in the
main package, or a fully-qualified based on the module, if elsewhere.

For example, given func logString(msg string) and the below assembly:

#include "textflag.h"
TEXT ·logString(SB), NOSPLIT, $0
CallImport
RET

If the package was main, the WebAssembly function name would be
"main.logString". If it was util and your go.mod module was
"github.com/user/me", the WebAssembly function name would be
"github.com/prep/user/me/util.logString"

You may want to add an example of this, so that you can see the impact
to the various runtimes. It is the same as the other "go".

Note that you will need to put this in a separate directory so you can
compile . or ./... and get the .s file. Also, the func has to be called, or
the compiler will skip writing it!

Here's an example which would work the same way in user-code as go's
source tree

https://github.com/golang/go/blob/master/src/syscall/js/js.go#L569
https://github.com/golang/go/blob/master/src/syscall/js/js_js.s#L63-L65

I've been playing with this for a bit and I wonder how useful this really is 🤔 You cannot really break out of the go module so it has be to included in those imports. This takes a true waPC implementation off the table, for example.

I did find out that you can override the package name, though. For example, you can do this:

//go:linkname exampleImport foo.exampleImport
func exampleImport() int32

and this:

#include "textflag.h"

TEXT foo·exampleImport(SB), NOSPLIT, $0
  CallImport
  RET

To change the import to foo.exampleImport in the go module.

oh.. sorry I should have elaborated. At least in wazero, I had planned to allow folks to configure custom host functions. I think translating from the go stack semantics to a normal signature is automatable also, but at least dealing with stack pointers should work.

Ex. in worst case:

wasm_exec.NewBuilder().ExportFunction("main.logString", func(ctx context.Context, api.Module, sp uint32) {...})

Ex. in best case we mechanically do the stack pointer thing given the signature we receive (via reflection)

wasm_exec.NewBuilder().ExportFunction("main.logString", func(ctx context.Context, api.Module, offset, len uint32) {...})

In any case, you are right. Unless something allows changing the host functions in the "go" package, either directly, or via ImportRenamer, it wouldn't work