Coverage for wasmtime/_table.py: 100%
51 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 16:25 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-20 16:25 +0000
1from . import _ffi as ffi
2from ctypes import *
3from wasmtime import TableType, Store, WasmtimeError, Val
4from typing import Optional, Any
5from ._store import Storelike
8class Table:
9 _table: ffi.wasmtime_table_t
11 def __init__(self, store: Store, ty: TableType, init: Any):
12 """
13 Creates a new table within `store` with the specified `ty`.
14 """
16 init_val = Val._convert_to_raw(store, ty.element, init)
18 table = ffi.wasmtime_table_t()
19 error = ffi.wasmtime_table_new(store._context(), ty.ptr(), byref(init_val), byref(table))
20 ffi.wasmtime_val_unroot(store._context(), byref(init_val))
21 if error:
22 raise WasmtimeError._from_ptr(error)
23 self._table = table
25 @classmethod
26 def _from_raw(cls, table: ffi.wasmtime_table_t) -> "Table":
27 ty: "Table" = cls.__new__(cls)
28 ty._table = table
29 return ty
31 def type(self, store: Storelike) -> TableType:
32 """
33 Gets the type of this table as a `TableType`
34 """
36 ptr = ffi.wasmtime_table_type(store._context(), byref(self._table))
37 return TableType._from_ptr(ptr, None)
39 def size(self, store: Storelike) -> int:
40 """
41 Gets the size, in elements, of this table
42 """
43 return ffi.wasmtime_table_size(store._context(), byref(self._table))
45 def grow(self, store: Storelike, amt: int, init: Any) -> int:
46 """
47 Grows this table by the specified number of slots, using the specified
48 initializer for all new table slots.
50 Raises a `WasmtimeError` if the table could not be grown.
51 Returns the previous size of the table otherwise.
52 """
53 init_val = Val._convert_to_raw(store, self.type(store).element, init)
54 prev = c_uint64(0)
55 error = ffi.wasmtime_table_grow(store._context(), byref(self._table), c_uint64(amt), byref(init_val), byref(prev))
56 ffi.wasmtime_val_unroot(store._context(), byref(init_val))
57 if error:
58 raise WasmtimeError._from_ptr(error)
59 return prev.value
61 def get(self, store: Store, idx: int) -> Optional[Any]:
62 """
63 Gets an individual element within this table.
65 Returns `None` for null references in the table (i.e. a null `funcref`
66 or a null `externref).
68 Returns a `Func` for non-null `funcref` table elements.
70 Returns the wrapped extern data for non-null `externref` table elements.
72 Returns `None` if `idx` is out of bounds.
73 """
74 raw = ffi.wasmtime_val_t()
75 ok = ffi.wasmtime_table_get(store._context(), byref(self._table), idx, byref(raw))
76 if not ok:
77 return None
78 val = Val._from_raw(store, raw)
79 if val.value:
80 return val.value
81 else:
82 return val
84 def set(self, store: Store, idx: int, val: Any) -> None:
85 """
86 Sets an individual element within this table.
88 `idx` must be an integer index.
90 The `val` specified must be convertible into this table's element
91 type. I.e. for a `funcref` table, `val` must either be a `Func` or
92 `None`, and for an `externref` table, `val` may be any arbitrary
93 external data.
95 Raises a `WasmtimeError` if `idx` is out of bounds.
96 """
97 value = Val._convert_to_raw(store, self.type(store).element, val)
98 error = ffi.wasmtime_table_set(store._context(), byref(self._table), idx, byref(value))
99 ffi.wasmtime_val_unroot(store._context(), byref(value))
100 if error:
101 raise WasmtimeError._from_ptr(error)
103 def _as_extern(self) -> ffi.wasmtime_extern_t:
104 union = ffi.wasmtime_extern_union(table=self._table)
105 return ffi.wasmtime_extern_t(ffi.WASMTIME_EXTERN_TABLE, union)