...
1
2
3
4
5
6
7
8
9
10
11
12
13 package emscripten
14
15 import (
16 "context"
17 "strings"
18
19 "github.com/tetratelabs/wazero"
20 "github.com/tetratelabs/wazero/api"
21 internal "github.com/tetratelabs/wazero/internal/emscripten"
22 "github.com/tetratelabs/wazero/internal/wasm"
23 )
24
25 const i32 = wasm.ValueTypeI32
26
27
28
29
30
31
32
33 func MustInstantiate(ctx context.Context, r wazero.Runtime) {
34 if _, err := Instantiate(ctx, r); err != nil {
35 panic(err)
36 }
37 }
38
39
40
41
42
43
44
45
46
47
48
49 func Instantiate(ctx context.Context, r wazero.Runtime) (api.Closer, error) {
50 builder := r.NewHostModuleBuilder("env")
51 NewFunctionExporter().ExportFunctions(builder)
52 return builder.Instantiate(ctx)
53 }
54
55
56
57
58
59
60
61
62 type FunctionExporter interface {
63
64
65 ExportFunctions(wazero.HostModuleBuilder)
66 }
67
68
69
70 func NewFunctionExporter() FunctionExporter {
71 return &functionExporter{}
72 }
73
74 type functionExporter struct{}
75
76
77 func (functionExporter) ExportFunctions(builder wazero.HostModuleBuilder) {
78 exporter := builder.(wasm.HostFuncExporter)
79 exporter.ExportHostFunc(internal.NotifyMemoryGrowth)
80 }
81
82 type emscriptenFns []*wasm.HostFunc
83
84
85
86 func InstantiateForModule(ctx context.Context, r wazero.Runtime, guest wazero.CompiledModule) (api.Closer, error) {
87
88 exporter, err := NewFunctionExporterForModule(guest)
89 if err != nil {
90 return nil, err
91 }
92
93
94 env := r.NewHostModuleBuilder("env")
95 exporter.ExportFunctions(env)
96 return env.Instantiate(ctx)
97 }
98
99
100
101 func NewFunctionExporterForModule(guest wazero.CompiledModule) (FunctionExporter, error) {
102 ret := emscriptenFns{}
103 for _, fn := range guest.ImportedFunctions() {
104 importModule, importName, isImport := fn.Import()
105 if !isImport || importModule != "env" {
106 continue
107 }
108 if importName == internal.FunctionNotifyMemoryGrowth {
109 ret = append(ret, internal.NotifyMemoryGrowth)
110 continue
111 }
112 if importName == internal.FunctionThrowLongjmp {
113 ret = append(ret, internal.ThrowLongjmp)
114 continue
115 }
116 if !strings.HasPrefix(importName, internal.InvokePrefix) {
117 continue
118 }
119
120 hf := internal.NewInvokeFunc(importName, fn.ParamTypes(), fn.ResultTypes())
121 ret = append(ret, hf)
122 }
123 return ret, nil
124 }
125
126
127 func (i emscriptenFns) ExportFunctions(builder wazero.HostModuleBuilder) {
128 exporter := builder.(wasm.HostFuncExporter)
129 for _, fn := range i {
130 exporter.ExportHostFunc(fn)
131 }
132 }
133
View as plain text