def __call__(self, *params): ty = self.type() param_tys = ty.params() if len(param_tys) != len(params): raise TypeError("wrong number of parameters") param_ffi = (wasm_val_t * len(params))() for i, param in enumerate(params): val = Val.__convert__(param_tys[i], param) param_ffi[i] = val.__raw__ result_tys = ty.results() result_ffi = (wasm_val_t * len(result_tys))() trap = dll.wasm_func_call(self.__ptr__, param_ffi, result_ffi) if trap: raise Trap.__from_ptr__(trap) results = [] for i in range(0, len(result_tys)): results.append(extract_val(Val(result_ffi[i]))) if len(results) == 0: return None elif len(results) == 1: return results[0] else: return results
def __getitem__(self, idx: int) -> Optional[Any]: """ Gets an individual element within this table. Returns `None` for null references in the table (i.e. a null `funcref` or a null `externref). Returns a `Func` for non-null `funcref` table elements. Returns the wrapped extern data for non-null `externref` table elements. Raises an `WasmtimeError` if `idx` is out of bounds. """ if idx >= self.size: raise WasmtimeError("table index out of bounds") if self.type.element == ValType.externref(): val = Val.externref(None) elif self.type.element == ValType.funcref(): val = Val.funcref(None) else: raise WasmtimeError("unsupported table element type") val._unwrap_raw().of.ref = ffi.wasm_table_get(self._ptr, idx) return val.value
def invoke(idx, params_ptr, results_ptr, params): func, param_tys, result_tys, store = FUNCTIONS.get(idx) try: for i in range(0, len(param_tys)): params.append(extract_val(Val(params_ptr[i]))) results = func(*params) if len(result_tys) == 0: if results is not None: raise RuntimeError( "callback produced results when it shouldn't") elif len(result_tys) == 1: val = Val.__convert__(result_tys[0], results) results_ptr[0] = val.__raw__ else: if len(results) != len(result_tys): raise RuntimeError("callback produced wrong number of results") for i, result in enumerate(results): val = Val.__convert__(result_tys[i], result) results_ptr[i] = val.__raw__ except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() fmt = traceback.format_exception(exc_type, exc_value, exc_traceback) trap = Trap(store, "\n".join(fmt)) ptr = trap.__ptr__ delattr(trap, '__ptr__') return cast(ptr, c_void_p).value return 0
def __call__(self, *params: IntoVal) -> Union[IntoVal, Sequence[IntoVal], None]: """ Calls this function with the given parameters Parameters can either be a `Val` or a native python value which can be converted to a `Val` of the corresponding correct type Returns `None` if this func has 0 return types Returns a single value if the func has 1 return type Returns a list if the func has more than 1 return type Note that you can also use the `__call__` method and invoke a `Func` as if it were a function directly. """ ty = self.type param_tys = ty.params if len(params) > len(param_tys): raise WasmtimeError( "too many parameters provided: given %s, expected %s" % (len(params), len(param_tys))) if len(params) < len(param_tys): raise WasmtimeError( "too few parameters provided: given %s, expected %s" % (len(params), len(param_tys))) param_vals = [ Val._convert(ty, params[i]) for i, ty in enumerate(param_tys) ] params_ptr = (ffi.wasm_val_t * len(params))() for i, val in enumerate(param_vals): params_ptr[i] = val._unwrap_raw() result_tys = ty.results results_ptr = (ffi.wasm_val_t * len(result_tys))() trap = POINTER(ffi.wasm_trap_t)() error = ffi.wasmtime_func_call(self._ptr, params_ptr, len(params), results_ptr, len(result_tys), byref(trap)) if error: raise WasmtimeError._from_ptr(error) if trap: raise Trap._from_ptr(trap) results = [] for i in range(0, len(result_tys)): results.append(Val(results_ptr[i]).value) if len(results) == 0: return None elif len(results) == 1: return results[0] else: return results
def value(self, val: IntoVal) -> None: """ Sets the value of this global to a new value """ val = Val._convert(self.type.content, val) error = ffi.wasmtime_global_set(self._ptr, byref(val._unwrap_raw())) if error: raise WasmtimeError._from_ptr(error)
def __init__(self, store, ty, val): if not isinstance(store, Store): raise TypeError("expected a Store") if not isinstance(ty, GlobalType): raise TypeError("expected a GlobalType") val = Val.__convert__(ty.content(), val) ptr = dll.wasm_global_new( store.__ptr__, ty.__ptr__, byref(val.__raw__)) if not ptr: raise RuntimeError("failed to create global") self.__ptr__ = ptr self.__owner__ = None
def invoke(idx, params_ptr, results_ptr, params): # type: ignore func, param_tys, result_tys, store = FUNCTIONS.get(idx or 0) try: for i in range(0, len(param_tys)): params.append(Val._value(params_ptr[i])) results = func(*params) if len(result_tys) == 0: if results is not None: raise WasmtimeError( "callback produced results when it shouldn't") elif len(result_tys) == 1: if isinstance(results, Val): # Because we are taking the inner value with `_into_raw`, we # need to ensure that we have a unique `Val`. val = results._clone() else: val = Val._convert(result_tys[0], results) results_ptr[0] = val._into_raw() else: if len(results) != len(result_tys): raise WasmtimeError( "callback produced wrong number of results") for i, result in enumerate(results): # Because we are taking the inner value with `_into_raw`, we # need to ensure that we have a unique `Val`. if isinstance(result, Val): val = result._clone() else: val = Val._convert(result_tys[i], result) results_ptr[i] = val._into_raw() except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() fmt = traceback.format_exception(exc_type, exc_value, exc_traceback) trap = Trap(store, "\n".join(fmt)) ptr = trap._ptr delattr(trap, '_ptr') return cast(ptr, c_void_p).value return 0
def __init__(self, store: Store, ty: GlobalType, val: IntoVal): if not isinstance(store, Store): raise TypeError("expected a Store") if not isinstance(ty, GlobalType): raise TypeError("expected a GlobalType") val = Val._convert(ty.content, val) ptr = POINTER(ffi.wasm_global_t)() error = ffi.wasmtime_global_new(store._ptr, ty._ptr, byref(val._unwrap_raw()), byref(ptr)) if error: raise WasmtimeError._from_ptr(error) self._ptr = ptr self._owner = None
def value(self) -> IntoVal: """ Gets the current value of this global Returns a native python type """ raw = ffi.wasm_val_t() ffi.wasm_global_get(self._ptr, byref(raw)) val = Val(raw) if val.value: return val.value else: return val
def grow(self, amt: int, init: IntoVal) -> int: """ Grows this table by the specified number of slots, using the specified initializer for all new table slots. Raises a `WasmtimeError` if the table could not be grown. Returns the previous size of the table otherwise. """ init_val = Val._convert(self.type.element, init) ok = ffi.wasm_table_grow(self._ptr, c_uint32(amt), init_val._unwrap_raw().of.ref) if not ok: raise WasmtimeError("failed to grow table") return self.size - amt
def __init__(self, store: Store, ty: TableType, init: IntoVal): """ Creates a new table within `store` with the specified `ty`. """ if not isinstance(store, Store): raise TypeError("expected a `Store`") if not isinstance(ty, TableType): raise TypeError("expected a `TableType`") init_val = Val._convert(ty.element, init) ptr = ffi.wasm_table_new(store._ptr, ty._ptr, init_val._unwrap_raw().of.ref) if not ptr: raise WasmtimeError("Failed to create table") self._ptr = ptr self._owner = None
def __setitem__(self, idx: int, val: IntoVal) -> None: """ Sets an individual element within this table. `idx` must be an integer index. The `val` specified must be convertible into this table's element type. I.e. for a `funcref` table, `val` must either be a `Func` or `None`, and for an `externref` table, `val` may be any arbitrary external data. Raises a `WasmtimeError` if `idx` is out of bounds. """ if idx >= self.size: raise WasmtimeError( "Index out of bounds when setting table element") value = Val._convert(self.type.element, val) ok = ffi.wasm_table_set(self._ptr, idx, value._unwrap_raw().of.ref) if not ok: raise WasmtimeError("Failed to set table element")
def set(self, val): val = Val.__convert__(self.type().content(), val) dll.wasm_global_set(self.__ptr__, byref(val.__raw__))
def get(self): raw = wasm_val_t() dll.wasm_global_get(self.__ptr__, byref(raw)) return Val(raw).get()