Skip to content
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

Is it possible to dynamically link several wasm modules in Go host? #166

Closed
vlkv opened this issue Dec 12, 2022 · 6 comments
Closed

Is it possible to dynamically link several wasm modules in Go host? #166

vlkv opened this issue Dec 12, 2022 · 6 comments

Comments

@vlkv
Copy link
Contributor

vlkv commented Dec 12, 2022

Hello,

Is it possible to use dynamic linking in Go host, similar to this example https://docs.wasmtime.dev/examples-rust-linking.html (which demonstrates Rust host)?

@alexcrichton
Copy link
Member

Apologies I misunderstood your question in bytecodealliance/wasmtime#5415 as I thought it was related to static/dynamic linking of Wasmtime itself.

I think what you're looking for is here:

wasmtime-go/example_test.go

Lines 237 to 306 in 4b3a40c

func ExampleLinker() {
store := wasmtime.NewStore(wasmtime.NewEngine())
// Compile two wasm modules where the first references the second
wasm1, err := wasmtime.Wat2Wasm(`
(module
(import "wasm2" "double" (func $double (param i32) (result i32)))
(func (export "double_and_add") (param i32 i32) (result i32)
local.get 0
call $double
local.get 1
i32.add
)
)
`)
if err != nil {
log.Fatal(err)
}
wasm2, err := wasmtime.Wat2Wasm(`
(module
(func (export "double") (param i32) (result i32)
local.get 0
i32.const 2
i32.mul
)
)
`)
if err != nil {
log.Fatal(err)
}
// Next compile both modules
module1, err := wasmtime.NewModule(store.Engine, wasm1)
if err != nil {
log.Fatal(err)
}
module2, err := wasmtime.NewModule(store.Engine, wasm2)
if err != nil {
log.Fatal(err)
}
linker := wasmtime.NewLinker(store.Engine)
// The second module is instantiated first since it has no imports, and
// then we insert the instance back into the linker under the name
// the first module expects.
instance2, err := linker.Instantiate(store, module2)
if err != nil {
log.Fatal(err)
}
err = linker.DefineInstance(store, "wasm2", instance2)
if err != nil {
log.Fatal(err)
}
// And now we can instantiate our first module, executing the result
// afterwards
instance1, err := linker.Instantiate(store, module1)
if err != nil {
log.Fatal(err)
}
doubleAndAdd := instance1.GetFunc(store, "double_and_add")
result, err := doubleAndAdd.Call(store, 2, 3)
if err != nil {
log.Fatal(err)
}
fmt.Print(result.(int32))
// Output: 7
}

@vlkv
Copy link
Contributor Author

vlkv commented Dec 13, 2022

Yes, thank you. This is exactly what I was asking for.

Can I please ask you a related question? Well, in wasm we have basic entities which are functions, global variables or memories. And we can import/export (i.e. dynamically link) them between wasm modules. But in the real-life project we may have a library written either in Rust or TinyGo and it has not just functions, but OOP entities like classes (or Go structs with methods, etc). Is it possible at all to accomplish the same thing in such a case. I mean to have a library in Rust/TinyGo with classes and another main module in Rust/TinyGo with code that uses those classes. Both the library and main module are compiled separately to wasm and dynamically linked together at runtime in the same manner as shown in the example above?

@alexcrichton
Copy link
Member

While technically possible it's not easily done. You'd need to have some form of wrapping/compat in both languages to get everything hooked up correctly. That being said the component model will enable more seamless integration of a scenario that you're describing.

@vlkv
Copy link
Contributor Author

vlkv commented Dec 13, 2022

Thank you for your help!

@vlkv vlkv closed this as completed Dec 13, 2022
@vlkv
Copy link
Contributor Author

vlkv commented Dec 13, 2022

Wait just a minute... What if, in my case both the library and the main modules will be implemented in the same language (both in TinyGo, or both in Rust) - does this change the situation to any better?

@alexcrichton
Copy link
Member

Unfortunately, no, not that I'm aware of.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants