call method

List<Object?> call(
  1. List<Object?> arguments
)

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;
  });
}