aboutsummaryrefslogtreecommitdiff
path: root/cmd/hlang/run
diff options
context:
space:
mode:
authorXe <me@christine.website>2023-01-01 23:04:07 -0500
committerXe <me@christine.website>2023-01-01 23:04:07 -0500
commite763c835a35d0a52acb9d3fde6e37a4b260b2100 (patch)
treef40de600ebdcf2d2e8852d0ea262cbc963735f54 /cmd/hlang/run
parentf58bd3056a1bb00801aedb6ebe6916978c043ee2 (diff)
downloadx-e763c835a35d0a52acb9d3fde6e37a4b260b2100.tar.xz
x-e763c835a35d0a52acb9d3fde6e37a4b260b2100.zip
cmd/hlang: move run to its own package
Signed-off-by: Xe <me@christine.website>
Diffstat (limited to 'cmd/hlang/run')
-rw-r--r--cmd/hlang/run/run.go67
-rw-r--r--cmd/hlang/run/run_test.go17
-rw-r--r--cmd/hlang/run/testdata/h.wasmbin0 -> 69 bytes
3 files changed, 84 insertions, 0 deletions
diff --git a/cmd/hlang/run/run.go b/cmd/hlang/run/run.go
new file mode 100644
index 0000000..5526df4
--- /dev/null
+++ b/cmd/hlang/run/run.go
@@ -0,0 +1,67 @@
+package run
+
+import (
+ "context"
+ "time"
+
+ "github.com/tetratelabs/wazero"
+ "github.com/tetratelabs/wazero/api"
+)
+
+type Process struct {
+ Output []byte
+}
+
+func (p *Process) Putchar(ctx context.Context, stack []uint64) {
+ x := api.DecodeI32(stack[0])
+ p.putchar(x)
+}
+
+func (p *Process) putchar(char int32) {
+ p.Output = append(p.Output, byte(char))
+}
+
+func Run(bin []byte) (*ExecResult, error) {
+ ctx := context.Background()
+ r := wazero.NewRuntime(ctx)
+ defer r.Close(ctx)
+
+ p := &Process{}
+
+ env, err := r.NewHostModuleBuilder("h").
+ NewFunctionBuilder().
+ WithGoFunction(api.GoFunc(p.Putchar), []api.ValueType{api.ValueTypeI32}, nil).
+ Export("h").
+ Instantiate(ctx, r)
+ if err != nil {
+ return nil, err
+ }
+ defer env.Close(ctx)
+
+ code, err := r.CompileModule(ctx, bin)
+ if err != nil {
+ return nil, err
+ }
+
+ mod, err := r.InstantiateModule(ctx, code, wazero.NewModuleConfig())
+ if err != nil {
+ return nil, err
+ }
+ defer mod.Close(ctx)
+
+ t0 := time.Now()
+ if _, err = mod.ExportedFunction("h").Call(ctx); err != nil {
+ return nil, err
+ }
+ runTime := time.Since(t0)
+
+ return &ExecResult{
+ Output: string(p.Output),
+ ExecTime: runTime,
+ }, nil
+}
+
+type ExecResult struct {
+ Output string `json:"out"`
+ ExecTime time.Duration `json:"exec_duration"`
+}
diff --git a/cmd/hlang/run/run_test.go b/cmd/hlang/run/run_test.go
new file mode 100644
index 0000000..5e2fdae
--- /dev/null
+++ b/cmd/hlang/run/run_test.go
@@ -0,0 +1,17 @@
+package run
+
+import (
+ _ "embed"
+ "testing"
+)
+
+//go:embed testdata/h.wasm
+var bin []byte
+
+func BenchmarkRun(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ if _, err := Run(bin); err != nil {
+ b.Fatal(err)
+ }
+ }
+}
diff --git a/cmd/hlang/run/testdata/h.wasm b/cmd/hlang/run/testdata/h.wasm
new file mode 100644
index 0000000..6a0d90d
--- /dev/null
+++ b/cmd/hlang/run/testdata/h.wasm
Binary files differ