This repository was archived by the owner on Nov 19, 2022. It is now read-only.
forked from bytecodealliance/wasmtime-go
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathinstance.go
More file actions
132 lines (122 loc) · 3.43 KB
/
instance.go
File metadata and controls
132 lines (122 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package wasmtime
// #include "shims.h"
import "C"
import (
"runtime"
"unsafe"
)
// Instance is an instantiated module instance.
// Once a module has been instantiated as an Instance, any exported function can be invoked externally via its function address funcaddr in the store S and an appropriate list val∗ of argument values.
type Instance struct {
val C.wasmtime_instance_t
}
// NewInstance instantiates a WebAssembly `module` with the `imports` provided.
//
// This function will attempt to create a new wasm instance given the provided
// imports. This can fail if the wrong number of imports are specified, the
// imports aren't of the right type, or for other resource-related issues.
//
// This will also run the `start` function of the instance, returning an error
// if it traps.
func NewInstance(store Storelike, module *Module, imports []AsExtern) (*Instance, error) {
importsRaw := make([]C.wasmtime_extern_t, len(imports), len(imports))
for i, imp := range imports {
importsRaw[i] = imp.AsExtern()
}
var val C.wasmtime_instance_t
err := enterWasm(store, func(trap **C.wasm_trap_t) *C.wasmtime_error_t {
var imports *C.wasmtime_extern_t
if len(importsRaw) > 0 {
imports = (*C.wasmtime_extern_t)(unsafe.Pointer(&importsRaw[0]))
}
return C.wasmtime_instance_new(
store.Context(),
module.ptr(),
imports,
C.size_t(len(importsRaw)),
&val,
trap,
)
})
runtime.KeepAlive(store)
runtime.KeepAlive(module)
runtime.KeepAlive(imports)
runtime.KeepAlive(importsRaw)
if err != nil {
return nil, err
}
return mkInstance(val), nil
}
func mkInstance(val C.wasmtime_instance_t) *Instance {
return &Instance{val}
}
// Type returns an `InstanceType` that corresponds for this instance.
func (i *Instance) Type(store Storelike) *InstanceType {
ptr := C.wasmtime_instance_type(store.Context(), &i.val)
runtime.KeepAlive(store)
return mkInstanceType(ptr, nil)
}
type externList struct {
vec C.wasm_extern_vec_t
}
// Exports returns a list of exports from this instance.
//
// Each export is returned as a `*Extern` and lines up with the exports list of
// the associated `Module`.
func (instance *Instance) Exports(store Storelike) []*Extern {
ret := make([]*Extern, 0)
var name *C.char
var name_len C.size_t
for i := 0; ; i++ {
var item C.wasmtime_extern_t
ok := C.wasmtime_instance_export_nth(
store.Context(),
&instance.val,
C.size_t(i),
&name,
&name_len,
&item,
)
if !ok {
break
}
ret = append(ret, mkExtern(&item))
}
runtime.KeepAlive(store)
return ret
}
// GetExport attempts to find an export on this instance by `name`
//
// May return `nil` if this instance has no export named `name`
func (i *Instance) GetExport(store Storelike, name string) *Extern {
var item C.wasmtime_extern_t
ok := C.wasmtime_instance_export_get(
store.Context(),
&i.val,
C._GoStringPtr(name),
C._GoStringLen(name),
&item,
)
runtime.KeepAlive(store)
runtime.KeepAlive(name)
if ok {
return mkExtern(&item)
}
return nil
}
// GetFunc attempts to find a function on this instance by `name`.
//
// May return `nil` if this instance has no function named `name`,
// it is not a function, etc.
func (i *Instance) GetFunc(store Storelike, name string) *Func {
f := i.GetExport(store, name)
if f == nil {
return nil
}
return f.Func()
}
func (i *Instance) AsExtern() C.wasmtime_extern_t {
ret := C.wasmtime_extern_t{kind: C.WASMTIME_EXTERN_INSTANCE}
C.go_wasmtime_extern_instance_set(&ret, i.val)
return ret
}