Coverage for wasmtime/_instance.py: 100%
56 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 ctypes import POINTER, byref
5from wasmtime import Module, WasmtimeError
6from ._extern import wrap_extern, get_extern_ptr
7from ._exportable import AsExtern
8from typing import Sequence, Optional, Iterator, Mapping
9from ._store import Storelike
10from ._func import enter_wasm
13class Instance:
14 _instance: ffi.wasmtime_instance_t
15 _exports: Optional["InstanceExports"]
17 def __init__(self, store: Storelike, module: Module, imports: Sequence[AsExtern]):
18 """
19 Creates a new instance by instantiating the `module` given with the
20 `imports` into the `store` provided.
22 The `store` must have type `Store`, the `module` must have type
23 `Module`, and the `imports` must be an iterable of external values,
24 either `Extern`, `Func`, `Table`, `Memory`, or `Global`.
26 Raises an error if instantiation fails (e.g. linking or trap) and
27 otherwise initializes the new instance.
28 """
30 imports_ptr = (ffi.wasmtime_extern_t * len(imports))()
31 for i, val in enumerate(imports):
32 imports_ptr[i] = get_extern_ptr(val)
34 instance = ffi.wasmtime_instance_t()
35 with enter_wasm(store) as trap:
36 error = ffi.wasmtime_instance_new(
37 store._context(),
38 module.ptr(),
39 imports_ptr,
40 len(imports),
41 byref(instance),
42 trap)
43 if error:
44 raise WasmtimeError._from_ptr(error)
45 self._instance = instance
46 self._exports = None
48 @classmethod
49 def _from_raw(cls, instance: ffi.wasmtime_instance_t) -> "Instance":
50 ty: "Instance" = cls.__new__(cls)
51 ty._exports = None
52 ty._instance = instance
53 return ty
55 def exports(self, store: Storelike) -> "InstanceExports":
56 """
57 Returns the exports of this module
59 The returned type can be indexed both with integers and with strings for
60 names of exports.
61 """
62 if self._exports is None:
63 self._exports = InstanceExports(store, self)
64 return self._exports
67class InstanceExports(Mapping[str, AsExtern]):
68 _extern_seq: Sequence[AsExtern]
69 _extern_map: Mapping[str, AsExtern]
71 def __init__(self, store: Storelike, instance: Instance):
72 self._extern_map = {}
74 extern_list = []
75 i = 0
76 item = ffi.wasmtime_extern_t()
77 name_ptr = ctypes.POINTER(ctypes.c_char)()
78 name_len = ctypes.c_size_t(0)
79 while ffi.wasmtime_instance_export_nth(
80 store._context(),
81 byref(instance._instance),
82 i,
83 byref(name_ptr),
84 byref(name_len),
85 byref(item)):
86 name = ffi.to_str_raw(name_ptr, name_len.value)
87 extern = wrap_extern(item)
88 extern_list.append(extern)
89 self._extern_map[name] = extern
90 i += 1
91 item = ffi.wasmtime_extern_t()
92 self._extern_seq = tuple(extern_list)
94 @property
95 def by_index(self) -> Sequence[AsExtern]:
96 return self._extern_seq
98 def __getitem__(self, idx: str) -> AsExtern:
99 return self._extern_map[idx]
101 def __len__(self) -> int:
102 return len(self.by_index)
104 def __iter__(self) -> Iterator[str]:
105 return iter(self._extern_map)