-
Notifications
You must be signed in to change notification settings - Fork 59
/
Copy path_table.py
105 lines (84 loc) · 3.71 KB
/
_table.py
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
from . import _ffi as ffi
from ctypes import *
from wasmtime import TableType, Store, WasmtimeError, Val
from typing import Optional, Any
from ._store import Storelike
class Table:
_table: ffi.wasmtime_table_t
def __init__(self, store: Store, ty: TableType, init: Any):
"""
Creates a new table within `store` with the specified `ty`.
"""
init_val = Val._convert_to_raw(store, ty.element, init)
table = ffi.wasmtime_table_t()
error = ffi.wasmtime_table_new(store._context(), ty.ptr(), byref(init_val), byref(table))
ffi.wasmtime_val_unroot(store._context(), byref(init_val))
if error:
raise WasmtimeError._from_ptr(error)
self._table = table
@classmethod
def _from_raw(cls, table: ffi.wasmtime_table_t) -> "Table":
ty: "Table" = cls.__new__(cls)
ty._table = table
return ty
def type(self, store: Storelike) -> TableType:
"""
Gets the type of this table as a `TableType`
"""
ptr = ffi.wasmtime_table_type(store._context(), byref(self._table))
return TableType._from_ptr(ptr, None)
def size(self, store: Storelike) -> int:
"""
Gets the size, in elements, of this table
"""
return ffi.wasmtime_table_size(store._context(), byref(self._table))
def grow(self, store: Storelike, amt: int, init: Any) -> int:
"""
Grows this table by the specified number of slots, using the specified
initializer for all new table slots.
Raises a `WasmtimeError` if the table could not be grown.
Returns the previous size of the table otherwise.
"""
init_val = Val._convert_to_raw(store, self.type(store).element, init)
prev = c_uint64(0)
error = ffi.wasmtime_table_grow(store._context(), byref(self._table), c_uint64(amt), byref(init_val), byref(prev))
ffi.wasmtime_val_unroot(store._context(), byref(init_val))
if error:
raise WasmtimeError._from_ptr(error)
return prev.value
def get(self, store: Store, idx: int) -> Optional[Any]:
"""
Gets an individual element within this table.
Returns `None` for null references in the table (i.e. a null `funcref`
or a null `externref).
Returns a `Func` for non-null `funcref` table elements.
Returns the wrapped extern data for non-null `externref` table elements.
Returns `None` if `idx` is out of bounds.
"""
raw = ffi.wasmtime_val_t()
ok = ffi.wasmtime_table_get(store._context(), byref(self._table), idx, byref(raw))
if not ok:
return None
val = Val._from_raw(store, raw)
if val.value:
return val.value
else:
return val
def set(self, store: Store, idx: int, val: Any) -> None:
"""
Sets an individual element within this table.
`idx` must be an integer index.
The `val` specified must be convertible into this table's element
type. I.e. for a `funcref` table, `val` must either be a `Func` or
`None`, and for an `externref` table, `val` may be any arbitrary
external data.
Raises a `WasmtimeError` if `idx` is out of bounds.
"""
value = Val._convert_to_raw(store, self.type(store).element, val)
error = ffi.wasmtime_table_set(store._context(), byref(self._table), idx, byref(value))
ffi.wasmtime_val_unroot(store._context(), byref(value))
if error:
raise WasmtimeError._from_ptr(error)
def _as_extern(self) -> ffi.wasmtime_extern_t:
union = ffi.wasmtime_extern_union(table=self._table)
return ffi.wasmtime_extern_t(ffi.WASMTIME_EXTERN_TABLE, union)