Skip to content

Commit da545aa

Browse files
FIXES #137: make calling wasm from python 7x faster
1 parent 52a0f1d commit da545aa

File tree

1 file changed

+22
-14
lines changed

1 file changed

+22
-14
lines changed

wasmtime/_func.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616

1717
class Func:
1818
_func: ffi.wasmtime_func_t
19+
_ty: FuncType
1920
_params_n: int
2021
_results_n: int
2122
_params_str: list[str]
2223
_results_str: list[str]
24+
_results_str0: str
2325
_vals_raw_type: ctypes.Array[wasmtime_val_raw_t]
2426

2527
def __init__(self, store: Storelike, ty: FuncType, func: Callable, access_caller: bool = False):
@@ -36,19 +38,7 @@ def __init__(self, store: Storelike, ty: FuncType, func: Callable, access_caller
3638
raise TypeError("expected a Store")
3739
if not isinstance(ty, FuncType):
3840
raise TypeError("expected a FuncType")
39-
# init signature properties used by call
40-
self._ty = ty
41-
ty_params = ty.params
42-
ty_results = ty.results
43-
self._params_str = (str(i) for i in ty_params)
44-
self._results_str = (str(i) for i in ty_results)
45-
params_n = len(ty_params)
46-
results_n = len(ty_results)
47-
self._params_n = params_n
48-
self._results_n = results_n
49-
n = max(params_n, results_n)
50-
self._vals_raw_type = wasmtime_val_raw_t*n
51-
41+
self._init_call(ty)
5242
idx = FUNCTIONS.allocate((func, ty.results, access_caller))
5343
_func = ffi.wasmtime_func_t()
5444
ffi.wasmtime_func_new(
@@ -83,10 +73,26 @@ def _extract_return(self, vals_raw: ctypes.Array[wasmtime_val_raw_t]) -> Union[I
8373
if self._results_n==0:
8474
return None
8575
if self._results_n==1:
86-
return getattr(vals_raw[0], self._results_str[0])
76+
return getattr(vals_raw[0], self._results_str0)
8777
# we can use tuple construct, but I'm using list for compatability
8878
return [getattr(val_raw, ret_str) for val_raw, ret_str in zip(vals_raw, self._results_str)]
8979

80+
def _init_call(self, ty):
81+
"""init signature properties used by call"""
82+
self._ty = ty
83+
ty_params = ty.params
84+
ty_results = ty.results
85+
self._params_str = (str(i) for i in ty_params)
86+
self._results_str = (str(i) for i in ty_results)
87+
self._results_str0 = str(ty_results[0])
88+
params_n = len(ty_params)
89+
results_n = len(ty_results)
90+
self._params_n = params_n
91+
self._results_n = results_n
92+
n = max(params_n, results_n)
93+
self._vals_raw_type = wasmtime_val_raw_t*n
94+
95+
9096
def __call__(self, store: Storelike, *params: IntoVal) -> Union[IntoVal, Sequence[IntoVal], None]:
9197
"""
9298
Calls this function with the given parameters
@@ -101,6 +107,8 @@ def __call__(self, store: Storelike, *params: IntoVal) -> Union[IntoVal, Sequenc
101107
Note that you can also use the `__call__` method and invoke a `Func` as
102108
if it were a function directly.
103109
"""
110+
if getattr(self, "_ty", None) is None:
111+
self._init_call(self.type(store))
104112
params_n = len(params)
105113
if params_n > self._params_n:
106114
raise WasmtimeError("too many parameters provided: given %s, expected %s" %

0 commit comments

Comments
 (0)