wasmexec icon indicating copy to clipboard operation
wasmexec copied to clipboard

example with custom import

Open codefromthecrypt opened this issue 3 years ago • 2 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

codefromthecrypt avatar Jun 05 '22 11:06 codefromthecrypt

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.

prep avatar Jun 06 '22 12:06 prep

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

codefromthecrypt avatar Jun 06 '22 12:06 codefromthecrypt