Копировать данные в память WebAssembly (например, адрес памяти WebAssembly 0):
a := []int32{10, 20, 30, 40}
// Copy data to wasm memory:
bytes := instance.Memory.Data()
for i, v := range a {
binary.LittleEndian.PutUint32(bytes[4*i:], uint32(v))
}
Получить экспортированную функцию bar
из экземпляра WebAssembly:
bar := instance.Exports["bar"]
Вызов, который был экспортирован функция с адресом и длиной памяти WebAssembly:
result, err := bar(0, 4)
if err != nil {
panic(err)
}
fmt.Println(result)
Файл main.go
:
package main
import (
"encoding/binary"
"fmt"
wasm "github.com/wasmerio/go-ext-wasm/wasmer"
)
func main() {
// Instantiate the module.
wasmbyte, err := wasm.ReadBytes("test.wasm")
if err != nil {
panic(err)
}
instance, err := wasm.NewInstance(wasmbyte)
if err != nil {
panic(err)
}
defer instance.Close()
hasmemory := instance.HasMemory()
fmt.Println("it has memory:", hasmemory)
a := []int32{10, 20, 30, 40}
// Copy data to wasm memory:
bytes := instance.Memory.Data()
for i, v := range a {
binary.LittleEndian.PutUint32(bytes[4*i:], uint32(v))
}
bar := instance.Exports["bar"]
result, err := bar(0, 4)
if err != nil {
panic(err)
}
fmt.Println(result)
}
Выход (go run main.go
):
it has memory: true
100
И следующий src/lib.rs
файл имеет тот же двоичный файл wasm (поскольку срез Rust имеет только указатель и длину):
#[no_mangle]
pub extern "C" fn bar(slice: &[i32]) -> i32 {
slice.iter().sum()
}
Преобразовать в test.wasm
:
rustc --target wasm32-unknown-unknown -O --crate-type=cdylib src/lib.rs -o test.wasm
Вывод преобразован в test.wat
(wasm2wat test.wasm -o test.wat
), чтобы увидеть функцию $bar
аргументы (param i32 i32
):
(module
(type (;0;) (func (param i32 i32) (result i32)))
(func $bar (type 0) (param i32 i32) (result i32)
(local i32)
block ;; label = @1
local.get 1
br_if 0 (;@1;)
i32.const 0
return
end
local.get 1
i32.const 2
i32.shl
local.set 2
i32.const 0
local.set 1
loop ;; label = @1
local.get 0
i32.load
local.get 1
i32.add
local.set 1
local.get 0
i32.const 4
i32.add
local.set 0
local.get 2
i32.const -4
i32.add
local.tee 2
br_if 0 (;@1;)
end
local.get 1)
(table (;0;) 1 1 funcref)
(memory (;0;) 16)
(global (;0;) (mut i32) (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(global (;2;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "bar" (func $bar))
(export "__data_end" (global 1))
(export "__heap_base" (global 2)))