-
Notifications
You must be signed in to change notification settings - Fork 80
/
functype.go
106 lines (91 loc) · 2.71 KB
/
functype.go
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
package wasmtime
// #include <wasm.h>
import "C"
import (
"runtime"
"unsafe"
)
// FuncType is one of function types which classify the signature of functions, mapping a vector of parameters to a vector of results.
// They are also used to classify the inputs and outputs of instructions.
type FuncType struct {
_ptr *C.wasm_functype_t
_owner interface{}
}
// NewFuncType creates a new `FuncType` with the `kind` provided
func NewFuncType(params, results []*ValType) *FuncType {
paramVec := mkValTypeList(params)
resultVec := mkValTypeList(results)
ptr := C.wasm_functype_new(¶mVec, &resultVec)
return mkFuncType(ptr, nil)
}
func mkValTypeList(tys []*ValType) C.wasm_valtype_vec_t {
vec := C.wasm_valtype_vec_t{}
C.wasm_valtype_vec_new_uninitialized(&vec, C.size_t(len(tys)))
base := unsafe.Pointer(vec.data)
for i, ty := range tys {
ptr := C.wasm_valtype_new(C.wasm_valtype_kind(ty.ptr()))
*(**C.wasm_valtype_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i))) = ptr
}
runtime.KeepAlive(tys)
return vec
}
func mkFuncType(ptr *C.wasm_functype_t, owner interface{}) *FuncType {
functype := &FuncType{_ptr: ptr, _owner: owner}
if owner == nil {
runtime.SetFinalizer(functype, func(functype *FuncType) {
functype.Close()
})
}
return functype
}
func (ty *FuncType) ptr() *C.wasm_functype_t {
ret := ty._ptr
if ret == nil {
panic("object has been closed already")
}
maybeGC()
return ret
}
func (ty *FuncType) owner() interface{} {
if ty._owner != nil {
return ty._owner
}
return ty
}
// Close will deallocate this type's state explicitly.
//
// For more information see the documentation for engine.Close()
func (ty *FuncType) Close() {
if ty._ptr == nil || ty._owner != nil {
return
}
runtime.SetFinalizer(ty, nil)
C.wasm_functype_delete(ty._ptr)
ty._ptr = nil
}
// Params returns the parameter types of this function type
func (ty *FuncType) Params() []*ValType {
ptr := C.wasm_functype_params(ty.ptr())
return ty.convertTypeList(ptr)
}
// Results returns the result types of this function type
func (ty *FuncType) Results() []*ValType {
ptr := C.wasm_functype_results(ty.ptr())
return ty.convertTypeList(ptr)
}
func (ty *FuncType) convertTypeList(list *C.wasm_valtype_vec_t) []*ValType {
ret := make([]*ValType, list.size)
base := unsafe.Pointer(list.data)
var ptr *C.wasm_valtype_t
for i := 0; i < int(list.size); i++ {
ptr := *(**C.wasm_valtype_t)(unsafe.Pointer(uintptr(base) + unsafe.Sizeof(ptr)*uintptr(i)))
ty := mkValType(ptr, ty.owner())
ret[i] = ty
}
return ret
}
// AsExternType converts this type to an instance of `ExternType`
func (ty *FuncType) AsExternType() *ExternType {
ptr := C.wasm_functype_as_externtype_const(ty.ptr())
return mkExternType(ptr, ty.owner())
}