tinygo icon indicating copy to clipboard operation
tinygo copied to clipboard

tinygo wasm externref support

Open wuhuizuo opened this issue 3 years ago • 3 comments

Because reflect support issue, such as https://github.com/tinygo-org/tinygo/issues/2660 I try to import host func into wasm module,my steps:

define go import function:

//go:wasm-module json
//export ExternrefTest
func Marshal(data interface{}) ([]byte, error) {
   return []byte{'1'}, nil
}

build with wasi target, but got import func type: func (param i32 i32 i32)

I import the func with host's golang encoding/json.Marshal:

// ...
linker := wasmtime.NewLinker(store.Engine)
linker.DefineFunc(store, "json", "Marshal", json.Marshal)
// ...

but i got incompatible import error:

panic: incompatible import type for `json`

Caused by:
    0: instance export "Marshal" incompatible
    1: function types incompatible: expected func of type `(i32, i32, i32) -> ()`, found func of type `(externref) -> (externref, externref)` [recovered]
	panic: incompatible import type for `json`

Are there any milestones to support compiled to externref?

wuhuizuo avatar Mar 11 '22 03:03 wuhuizuo

I think main issue will be how to represent what should be an externref param unambiguously. Also, per spec they are supposed to be completely opaque from the perspective of the guest. So, if represented by any, it should be impossible to cast it to a real type.

codefromthecrypt avatar Sep 07 '22 07:09 codefromthecrypt

Right now we don't support externref. Also I don't see how this is going to help you: TinyGo interface values are different from Go interface values. They cannot be interchangeable. If they were, implementing the missing reflect functions would be trivial.

I don't see anything to do here right now.

aykevl avatar Sep 15 '22 12:09 aykevl

@aykevl externref is a way to opaquely pass a value the host has in a way that the wasm compiled by tinygo never uses. It is intentional that it isn't interchangeable in other words.

rust doesn't yet support externref either, hence a package like this: https://github.com/slowli/externref

The main thing you get with externref is for the host to be able to stash scoped objects either as globals or stack parameters. The example above is a host-defined sender. I've seen other things like host-defined memory as examples (sometimes string literals they don't want to actually wash through wasm).

codefromthecrypt avatar Sep 15 '22 22:09 codefromthecrypt