Coverage for wasmtime/_store.py: 84%

58 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-20 16:25 +0000

1from . import _ffi as ffi 

2from ctypes import byref, c_uint64, cast, c_void_p, CFUNCTYPE 

3import ctypes 

4from wasmtime import Engine, WasmtimeError, Managed 

5from . import _value as value 

6import typing 

7 

8if typing.TYPE_CHECKING: 

9 from ._wasi import WasiConfig 

10 

11 

12class Store(Managed["ctypes._Pointer[ffi.wasmtime_store_t]"]): 

13 __context: "typing.Optional[ctypes._Pointer[ffi.wasmtime_context_t]]" 

14 

15 def __init__(self, engine: typing.Optional[Engine] = None, data: typing.Optional[typing.Any] = None): 

16 

17 if engine is None: 

18 engine = Engine() 

19 elif not isinstance(engine, Engine): 

20 raise TypeError("expected an Engine") 

21 data_id = ffi.c_void_p(0) 

22 finalize = cast(0, CFUNCTYPE(None, c_void_p)) 

23 if data: 

24 data_id = value._intern(data) 

25 finalize = value._externref_finalizer 

26 self._set_ptr(ffi.wasmtime_store_new(engine.ptr(), data_id, finalize)) 

27 self.__context = ffi.wasmtime_store_context(self.ptr()) 

28 self.engine = engine 

29 

30 def _delete(self, ptr: "ctypes._Pointer[ffi.wasmtime_store_t]") -> None: 

31 ffi.wasmtime_store_delete(ptr) 

32 self.__context = None 

33 

34 def _context(self) -> "ctypes._Pointer[ffi.wasmtime_context_t]": 

35 if self.__context is None: 

36 raise ValueError('already closed') 

37 return self.__context 

38 

39 def data(self) -> typing.Optional[typing.Any]: 

40 """ 

41 TODO 

42 """ 

43 data = ffi.wasmtime_context_get_data(self._context()) 

44 if data: 

45 return value._unintern(data) 

46 else: 

47 return None 

48 

49 def gc(self) -> None: 

50 """ 

51 Runs a GC over `externref` values that have been passed into this Store, 

52 cleaning out anything that is no longer referenced. 

53 

54 This is not required to be run manually, but can be done so if you'd 

55 like more precise control over when unreferenced `externref` values are 

56 deallocated. 

57 """ 

58 ffi.wasmtime_context_gc(self._context()) 

59 

60 def set_fuel(self, fuel: int) -> None: 

61 """ 

62 Sets the amount of fuel in this store to `fuel`. 

63 

64 This is only relevant when `Config.consume_fuel` is configured. 

65 

66 This is a required call to ensure that the store has fuel to 

67 execute WebAssembly since otherwise stores start with zero fuel. 

68 

69 Raises a `WasmtimeError` if this store's configuration is not configured 

70 to consume fuel. 

71 """ 

72 err = ffi.wasmtime_context_set_fuel(self._context(), fuel) 

73 if err: 

74 raise WasmtimeError._from_ptr(err) 

75 

76 def get_fuel(self) -> int: 

77 """ 

78 Returns the amount of fuel left in the store. 

79 

80 This is only relevant when `Config.consume_fuel` is configured. 

81 

82 Raises a `WasmtimeError` if this store's configuration is not configured 

83 to consume fuel or if the store doesn't have enough fuel remaining. 

84 """ 

85 remaining = c_uint64(0) 

86 err = ffi.wasmtime_context_get_fuel(self._context(), byref(remaining)) 

87 if err: 

88 raise WasmtimeError._from_ptr(err) 

89 return remaining.value 

90 

91 def set_wasi(self, wasi: "WasiConfig") -> None: 

92 """ 

93 TODO 

94 """ 

95 error = ffi.wasmtime_context_set_wasi(self._context(), wasi._consume()) 

96 if error: 

97 raise WasmtimeError._from_ptr(error) 

98 

99 def set_epoch_deadline(self, ticks_after_current: int) -> None: 

100 """ 

101 Configures the relative epoch deadline, after the current engine's 

102 epoch, after which WebAssembly code will trap. 

103 """ 

104 ffi.wasmtime_context_set_epoch_deadline(self._context(), ticks_after_current) 

105 

106 def set_limits(self, 

107 memory_size: int = -1, 

108 table_elements: int = -1, 

109 instances: int = -1, 

110 tables: int = -1, 

111 memories: int = -1) -> None: 

112 """ 

113 Configures the limits of various items within this store. 

114 

115 * `memory_size` - the maximum size, in bytes, that linear memory is 

116 allowed to consume within this store. Setting this to a lower value 

117 will cause instantiation to fail if a module needs more memory. 

118 Additionally the `memory.grow` instruction will return -1 once this 

119 threshold is reached. 

120 

121 * `table_elements` - the maximum number of elements that can be stored 

122 within tables in this store. Currently each table element takes 8 

123 bytes. 

124 

125 * `instances` - the maximum number of WebAssembly instances that can 

126 be created. 

127 

128 * `tables` - the maximum number of WebAssembly tables that can 

129 be created. 

130 

131 * `memories` - the maximum number of WebAssembly linear memories that 

132 can be created. 

133 

134 If any limit is negative then the limit will not be set as a part of 

135 this invocation and it will be ignored. 

136 """ 

137 ffi.wasmtime_store_limiter(self.ptr(), memory_size, table_elements, instances, tables, memories) 

138 

139 

140if typing.TYPE_CHECKING: 

141 from ._func import Caller 

142 

143 

144Storelike = typing.Union[Store, "Caller"]