call method
Calls the function with arguments and returns its results.
Arguments are coerced according to the signature; a single result is still returned as a one element list, use invoke for the ergonomic form.
Implementation
List<Object?> call(List<Object?> arguments) {
final signature = type;
if (arguments.length != signature.parameters.length) {
throw ArgumentError.value(
arguments,
'arguments',
'expected ${signature.parameters.length} arguments for $signature',
);
}
return scoped((arena) {
final args = arena<c.wasmtime_val_t>(signature.parameters.length);
for (var i = 0; i < arguments.length; i++) {
final kind = signature.parameters[i];
writeValue(args + i, kind, toNativeValue(kind, arguments[i]));
}
final results = arena<c.wasmtime_val_t>(signature.results.length);
final trapOut = arena<ffi.Pointer<c.wasm_trap_t>>();
clearHostException();
final error = c.wasmtime_func_call(
store.context,
_native(arena),
args,
arguments.length,
results,
signature.results.length,
trapOut,
);
if (error != ffi.nullptr || trapOut.value != ffi.nullptr) {
// A host function that threw is more informative than the trap.
rethrowHostException();
throwExecutionFailure(error, trapOut.value);
}
final out = <Object?>[];
for (var i = 0; i < signature.results.length; i++) {
final kind = signature.results[i];
out.add(toDartValue(store, kind, readValue(results + i)));
// Reference results arrive rooted and have to be released again.
unrootValue(results + i);
}
return out;
});
}