-
Notifications
You must be signed in to change notification settings - Fork 80
/
table.go
109 lines (98 loc) · 3.33 KB
/
table.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
107
108
109
package wasmtime
// #include "shims.h"
import "C"
import (
"errors"
"runtime"
)
// Table is a table instance, which is the runtime representation of a table.
//
// It holds a vector of reference types and an optional maximum size, if one was
// specified in the table type at the table’s definition site.
// Read more in [spec](https://webassembly.github.io/spec/core/exec/runtime.html#table-instances)
type Table struct {
val C.wasmtime_table_t
}
// NewTable creates a new `Table` in the given `Store` with the specified `ty`.
//
// The `ty` must be a reference type (`funref` or `externref`) and `init`
// is the initial value for all table slots and must have the type specified by
// `ty`.
func NewTable(store Storelike, ty *TableType, init Val) (*Table, error) {
var ret C.wasmtime_table_t
var raw_val C.wasmtime_val_t
init.initialize(store, &raw_val)
err := C.wasmtime_table_new(store.Context(), ty.ptr(), &raw_val, &ret)
C.wasmtime_val_unroot(store.Context(), &raw_val)
runtime.KeepAlive(store)
runtime.KeepAlive(ty)
if err != nil {
return nil, mkError(err)
}
return mkTable(ret), nil
}
func mkTable(val C.wasmtime_table_t) *Table {
return &Table{val}
}
// Size returns the size of this table in units of elements.
func (t *Table) Size(store Storelike) uint64 {
ret := C.wasmtime_table_size(store.Context(), &t.val)
runtime.KeepAlive(store)
return uint64(ret)
}
// Grow grows this table by the number of units specified, using the
// specified initializer value for new slots.
//
// Returns an error if the table failed to grow, or the previous size of the
// table if growth was successful.
func (t *Table) Grow(store Storelike, delta uint64, init Val) (uint64, error) {
var prev C.uint64_t
var raw_val C.wasmtime_val_t
init.initialize(store, &raw_val)
err := C.wasmtime_table_grow(store.Context(), &t.val, C.uint64_t(delta), &raw_val, &prev)
C.wasmtime_val_unroot(store.Context(), &raw_val)
runtime.KeepAlive(store)
if err != nil {
return 0, mkError(err)
}
return uint64(prev), nil
}
// Get gets an item from this table from the specified index.
//
// Returns an error if the index is out of bounds, or returns a value (which
// may be internally null) if the index is in bounds corresponding to the entry
// at the specified index.
func (t *Table) Get(store Storelike, idx uint64) (Val, error) {
var val C.wasmtime_val_t
ok := C.wasmtime_table_get(store.Context(), &t.val, C.uint64_t(idx), &val)
runtime.KeepAlive(store)
if !ok {
return Val{}, errors.New("index out of bounds")
}
return takeVal(store, &val), nil
}
// Set sets an item in this table at the specified index.
//
// Returns an error if the index is out of bounds.
func (t *Table) Set(store Storelike, idx uint64, val Val) error {
var raw_val C.wasmtime_val_t
val.initialize(store, &raw_val)
err := C.wasmtime_table_set(store.Context(), &t.val, C.uint64_t(idx), &raw_val)
C.wasmtime_val_unroot(store.Context(), &raw_val)
runtime.KeepAlive(store)
if err != nil {
return mkError(err)
}
return nil
}
// Type returns the underlying type of this table
func (t *Table) Type(store Storelike) *TableType {
ptr := C.wasmtime_table_type(store.Context(), &t.val)
runtime.KeepAlive(store)
return mkTableType(ptr, nil)
}
func (t *Table) AsExtern() C.wasmtime_extern_t {
ret := C.wasmtime_extern_t{kind: C.WASMTIME_EXTERN_TABLE}
C.go_wasmtime_extern_table_set(&ret, t.val)
return ret
}