зеркало из https://github.com/golang/scratch.git
cherry/wasmtest: a test program for wasmexport
Change-Id: I54700d85b52e7be12f337fc72b39a479605dc38f Reviewed-on: https://go-review.googlesource.com/c/scratch/+/604235 TryBot-Bypass: Cherry Mui <cherryyz@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Родитель
6cf087efc7
Коммит
a6564155a7
|
@ -0,0 +1,5 @@
|
|||
module golang.org/x/scratch/cherry/wasmtest
|
||||
|
||||
go 1.22
|
||||
|
||||
require github.com/tetratelabs/wazero v1.7.3
|
|
@ -0,0 +1,2 @@
|
|||
github.com/tetratelabs/wazero v1.7.3 h1:PBH5KVahrt3S2AHgEjKu4u+LlDbbk+nsGE3KLucy6Rw=
|
||||
github.com/tetratelabs/wazero v1.7.3/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
|
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
func init() {
|
||||
println("init function called")
|
||||
}
|
||||
|
||||
var ch = make(chan float64)
|
||||
|
||||
//go:wasmexport E
|
||||
func E(a int64, b int32, c float64, d float32) { // various types of args, no result
|
||||
println("=== E ===")
|
||||
// goroutine
|
||||
go func() { ch <- float64(a) + float64(b) + c + float64(d) + 100 }()
|
||||
debug.PrintStack() // traceback
|
||||
grow([100]int{10}) // stack growth
|
||||
runtime.GC() // GC
|
||||
println("=== E end ===")
|
||||
}
|
||||
|
||||
//go:wasmexport F
|
||||
func F() int64 { // no arg, has result
|
||||
f := int64(<-ch * 100) // force a goroutine switch
|
||||
println("F =", f)
|
||||
return f
|
||||
}
|
||||
|
||||
//go:wasmexport G
|
||||
func G(x int32) {
|
||||
println("G", x)
|
||||
if x%2 == 0 {
|
||||
G(x - 1) // simple recursion within this module
|
||||
} else {
|
||||
J(x - 1) // mutual recursion between host and this module
|
||||
}
|
||||
println("G", x, "end")
|
||||
}
|
||||
|
||||
//go:wasmimport test I
|
||||
func I() int64
|
||||
|
||||
//go:wasmimport test J
|
||||
func J(int32)
|
||||
|
||||
func main() {
|
||||
println("hello")
|
||||
println("main: I =", I())
|
||||
}
|
||||
|
||||
func grow(x [100]int) {
|
||||
if x[0] == 0 {
|
||||
println("=== grow ===")
|
||||
debug.PrintStack()
|
||||
return
|
||||
}
|
||||
x[0]--
|
||||
grow(x)
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// A program for testing wasmexport.
|
||||
// This is the driver/host program, which provides the imports
|
||||
// and calls the exports. testprog is the source of the Wasm
|
||||
// module, which can be compiled to either an executable or a
|
||||
// library.
|
||||
//
|
||||
// To build it as executable:
|
||||
// GOARCH=wasm GOOS=wasip1 go build -o /tmp/x.wasm ./testprog
|
||||
//
|
||||
// To build it as a library:
|
||||
// GOARCH=wasm GOOS=wasip1 go build -buildmode=c-shared -o /tmp/x.wasm ./testprog
|
||||
//
|
||||
// Then run the driver (which works for both modes):
|
||||
// go run w.go /tmp/x.wasm
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/tetratelabs/wazero"
|
||||
"github.com/tetratelabs/wazero/api"
|
||||
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
|
||||
)
|
||||
|
||||
// exported from wasm
|
||||
var E func(a int64, b int32, c float64, d float32)
|
||||
var F func() int64
|
||||
var G func(int32)
|
||||
|
||||
func I() int64 {
|
||||
println("I start")
|
||||
E(20, 3, 0.4, 0.05)
|
||||
r := F() * 2
|
||||
G(4)
|
||||
println("I end =", r)
|
||||
return r
|
||||
}
|
||||
|
||||
func J(x int32) {
|
||||
println("J", x)
|
||||
if x > 0 {
|
||||
G(x)
|
||||
}
|
||||
println("J", x, "end")
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
r := wazero.NewRuntime(ctx)
|
||||
defer r.Close(ctx)
|
||||
|
||||
// provide import functions from host
|
||||
_, err := r.NewHostModuleBuilder("test").
|
||||
NewFunctionBuilder().WithFunc(I).Export("I").
|
||||
NewFunctionBuilder().WithFunc(J).Export("J").
|
||||
Instantiate(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
buf, err := os.ReadFile(os.Args[1])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
config := wazero.NewModuleConfig().
|
||||
WithStdout(os.Stdout).WithStderr(os.Stderr).
|
||||
WithStartFunctions() // don't call _start
|
||||
|
||||
wasi_snapshot_preview1.MustInstantiate(ctx, r)
|
||||
|
||||
m, err := r.InstantiateWithConfig(ctx, buf, config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// get export functions from the module
|
||||
E = func(a int64, b int32, c float64, d float32) {
|
||||
exp := m.ExportedFunction("E")
|
||||
_, err := exp.Call(ctx, api.EncodeI64(a), api.EncodeI32(b), api.EncodeF64(c), api.EncodeF32(d))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
F = func() int64 {
|
||||
exp := m.ExportedFunction("F")
|
||||
r, err := exp.Call(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
rr := int64(r[0])
|
||||
println("host: F =", rr)
|
||||
return rr
|
||||
}
|
||||
G = func(x int32) {
|
||||
exp := m.ExportedFunction("G")
|
||||
_, err := exp.Call(ctx, api.EncodeI32(x))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
entry := m.ExportedFunction("_start")
|
||||
if entry != nil {
|
||||
// Executable mode.
|
||||
fmt.Println("Executable mode: start")
|
||||
_, err := entry.Call(ctx)
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Library mode.
|
||||
entry = m.ExportedFunction("_initialize")
|
||||
fmt.Println("Library mode: initialize")
|
||||
_, err = entry.Call(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("\nLibrary mode: call export functions")
|
||||
I()
|
||||
}
|
Загрузка…
Ссылка в новой задаче