예제 #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 __init__(self, module, imports):
        if not isinstance(module, Module):
            raise TypeError("expected a Module")

        import_types = module.imports()
        if len(imports) != len(import_types):
            raise RuntimeError("wrong number of imports provided")
        imports_ffi = (P_wasm_extern_t * len(import_types))()
        for i, ty in enumerate(import_types):
            val = imports[i]
            if isinstance(val, Extern):
                imports_ffi[i] = val.__ptr__
            elif isinstance(val, Func):
                imports_ffi[i] = val.as_extern().__ptr__
            elif isinstance(val, Memory):
                imports_ffi[i] = val.as_extern().__ptr__
            elif isinstance(val, Global):
                imports_ffi[i] = val.as_extern().__ptr__
            elif isinstance(val, Table):
                imports_ffi[i] = val.as_extern().__ptr__
            else:
                raise TypeError("expected an external item as an import")

        trap = P_wasm_trap_t()
        ptr = dll.wasm_instance_new(module.store.__ptr__, module.__ptr__,
                                    imports_ffi, byref(trap))
        if not ptr:
            if trap:
                raise Trap.__from_ptr__(trap)
            raise RuntimeError("failed to compile instance")
        self.__ptr__ = ptr
        self._module = module
예제 #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 instantiate(self, module):
     if not isinstance(module, Module):
         raise TypeError("expected a `Module`")
     trap = P_wasm_trap_t()
     ptr = dll.wasmtime_linker_instantiate(self.__ptr__, module.__ptr__,
                                           byref(trap))
     if not ptr:
         if trap:
             raise Trap.__from_ptr__(trap)
         raise RuntimeError("failed to instantiate")
     return Instance.__from_ptr__(ptr, module)
예제 #6
0
 def instantiate(self, module: Module) -> Instance:
     if not isinstance(module, Module):
         raise TypeError("expected a `Module`")
     trap = POINTER(ffi.wasm_trap_t)()
     instance = POINTER(ffi.wasm_instance_t)()
     error = ffi.wasmtime_linker_instantiate(self._ptr, module._ptr,
                                             byref(instance), byref(trap))
     if error:
         raise WasmtimeError._from_ptr(error)
     if trap:
         raise Trap._from_ptr(trap)
     return Instance._from_ptr(instance, module)
예제 #7
0
    def __init__(self, store: Store, name: str, config: WasiConfig):
        if not isinstance(store, Store):
            raise TypeError("expected a `Store`")
        if not isinstance(name, str):
            raise TypeError("expected a `str`")
        name_bytes = name.encode('utf-8')
        if not isinstance(config, WasiConfig):
            raise TypeError("expected a `WasiConfig`")
        ptr = config._ptr
        delattr(config, '_ptr')

        trap = POINTER(ffi.wasm_trap_t)()
        ptr = ffi.wasi_instance_new(store._ptr, c_char_p(name_bytes), ptr,
                                    byref(trap))
        if not ptr:
            if trap:
                raise Trap._from_ptr(trap)
            raise WasmtimeError("failed to create wasi instance")
        self._ptr = ptr
        self.store = store
예제 #8
0
    def __init__(self, store, name, config):
        if not isinstance(store, Store):
            raise TypeError("expected a `Store`")
        if not isinstance(name, str):
            raise TypeError("expected a `str`")
        name = name.encode('utf-8')
        if not isinstance(config, WasiConfig):
            raise TypeError("expected a `WasiConfig`")
        ptr = config.__ptr__
        delattr(config, '__ptr__')

        trap = P_wasm_trap_t()
        ptr = dll.wasi_instance_new(store.__ptr__, c_char_p(name), ptr,
                                    byref(trap))
        if not ptr:
            if trap:
                raise Trap.__from_ptr__(trap)
            raise RuntimeError("failed to create wasi instance")
        self.__ptr__ = ptr
        self.store = store
예제 #9
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
예제 #10
0
    def instantiate(self, module: Module) -> Instance:
        """
        Instantiates a module using this linker's defined set of names.

        This method will attempt to satisfy all the imports of the `module`
        provided with the names defined within this linker. If all names are
        defined then the module is instantiated.

        Raises an error if an import of `module` hasn't been defined in this
        linker or if a trap happens while instantiating the instance.
        """
        if not isinstance(module, Module):
            raise TypeError("expected a `Module`")
        trap = POINTER(ffi.wasm_trap_t)()
        instance = POINTER(ffi.wasm_instance_t)()
        error = ffi.wasmtime_linker_instantiate(
            self._ptr, module._ptr, byref(instance), byref(trap))
        if error:
            raise WasmtimeError._from_ptr(error)
        if trap:
            raise Trap._from_ptr(trap)
        return Instance._from_ptr(instance, None)
예제 #11
0
    def __init__(self, store: Store, module: Module, imports: Sequence[AsExtern]):
        """
        Creates a new instance by instantiating the `module` given with the
        `imports` into the `store` provided.

        The `store` must have type `Store`, the `module` must have type
        `Module`, and the `imports` must be an iterable of external values,
        either `Extern`, `Func`, `Table`, `Memory`, or `Global`.

        Raises an error if instantiation fails (e.g. linking or trap) and
        otherwise initializes the new instance.
        """

        if not isinstance(store, Store):
            raise TypeError("expected a Store")
        if not isinstance(module, Module):
            raise TypeError("expected a Module")

        imports_ptr = (POINTER(ffi.wasm_extern_t) * len(imports))()
        for i, val in enumerate(imports):
            imports_ptr[i] = get_extern_ptr(val)

        instance = POINTER(ffi.wasm_instance_t)()
        trap = POINTER(ffi.wasm_trap_t)()
        error = ffi.wasmtime_instance_new(
            store._ptr,
            module._ptr,
            imports_ptr,
            len(imports),
            byref(instance),
            byref(trap))
        if error:
            raise WasmtimeError._from_ptr(error)
        if trap:
            raise Trap._from_ptr(trap)
        self._ptr = instance
        self._module = module
        self._exports = None