-
Notifications
You must be signed in to change notification settings - Fork 56
Description
I'm currently looking into using wasmtime-dotnet in a Unity game. Generally in Unity you want to reduce allocations as much as possible to prevent any GC stuttering down the line. As it stands any time you invoke a wasm function there is some unavoidable boxing of primitive arguments because the arguments are passed as params object[] (the ReadOnlySpan<object> variant of the call avoids the allocation of the params array, but not the allocation caused by boxing all of the individual arguments).
I can see two possible workaround for this.
Generic Invoke
Define a large number of overloads for Invoke with varying numbers of generic arguments:
public object? Invoke<TA>(IStore store, TA arg1);
public object? Invoke<TA, TB>(IStore store, TA arg1, TB arg2);
public object? Invoke<TA, TB, TC>(IStore store, TA arg1, TB arg2, TC arg3);
// etc up to as many arguments as you want to supportFor the sake of sanity, writing this would probably require code generation!
Struct Boxing
An alternative option would be to define a new struct which works in basically the same way as the ValueUnion struct (let's call it ArgBox) and to have implicit casts from the various supported types into this new struct. Then there just need to be two new methods defined:
public object? Invoke(IStore store, params ArgBox?[] args);
public object? Invoke(IStore store, ReadOnlySpan<ArgBox?> args);This is essentially just the same boxing operation that is already going on, but without the need for silent heap allocations.
Interest?
Does this proposal sound reasonable and would you be interested in merging a PR that contained something like this (and if so, which one)? I'm willing to write it if so.