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