示例#1
0
    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
示例#2
0
    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
示例#3
0
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
示例#4
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
示例#5
0
 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)
示例#6
0
 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
示例#7
0
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
示例#8
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
示例#9
0
    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
示例#10
0
    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
示例#11
0
    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
示例#12
0
    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")
示例#13
0
 def set(self, val):
     val = Val.__convert__(self.type().content(), val)
     dll.wasm_global_set(self.__ptr__, byref(val.__raw__))
示例#14
0
 def get(self):
     raw = wasm_val_t()
     dll.wasm_global_get(self.__ptr__, byref(raw))
     return Val(raw).get()