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