-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement reference types for .NET embeddings. #27
Comments
Once this is implemented, we can release a 0.19.0 NuGet package. |
FWIW, here is what it took to do this in the python API: bytecodealliance/wasmtime-py@b8532a4 We don't really integrate with the python reference counting collector, we just manually pin data that is referenced by an |
It'll be something similar for .NET, although we won't need to do any mapping ourselves. We'll allocate a |
I've got extern refs working for .NET embeddings, but I'm noticing that the finalizer isn't being invoked:
I haven't debugged it yet, so I'll take a look on Monday. |
So I'm seeing 5 increments and 4 decrements between a
The code: using var engine = new EngineBuilder()
.WithReferenceTypes(true)
.Build();
using var module = Module.FromText(engine, "externref", @"
(module
(import """" ""hello"" (func $.hello (param externref)))
(func (export ""run"") (param externref)
local.get 0
call $.hello
)
)");
using var host = new Host(engine);
host.DefineFunction(
"",
"hello",
(string name) => Console.WriteLine($"Hello from C#, {name}!")
);
using dynamic instance = host.Instantiate(module);
instance.run("Peter"); And the value is thereby "leaked" (actually held on to by Wasmtime). I'm capturing the ref count stacks now. |
increment: /home/peterhuene/src/wasmtime/crates/c-api/src/func.rs:213 (_wasmtime_func_call) decrement: /home/peterhuene/src/wasmtime/crates/c-api/src/ref.rs:142 (wasmtime_externref_data) Looks like there's no matching decrement for the clone in Func::call. Still digging. |
I see, I didn't expect the call arguments to end up in the activations table as the reference value is always rooted by the caller to @fitzgen thoughts on the above? |
I deleted the previous comment regarding a leak on dropping the store; there was actually a reference to the store alive from the .NET side because a |
We can add a FWIW, I didn't test GC reclaimation in |
Oh nevermind, just saw your update. |
Here is a PR to add a C API to do GC: bytecodealliance/wasmtime#2052 |
For my understanding, why are I think exposing a GC-triggering method in the .NET API and letting the users manually collect if desired (they'll know best when to do so given their use case) make the most sense. |
Yeah, this is due to the deferred reference counting for references inside Wasm frames, where we don't actually increment/decrement the ref counts. Instead we over-eagerly keep them alive until we do a GC, when we find the precise set that need to be alive, and reclaim the references that were in the over approximation. See https://github.com/bytecodealliance/wasmtime/blob/main/crates/runtime/src/externref.rs#L61-L100 for more details. |
The GC implementation makes sense. I guess what I'm getting at is that it would be nice if there were a mechanism to determine if the arguments need to end up in the activation table for a call to In this particular use case, there are no wasm frames on the stack when Indeed, the only way to call |
My very-surface-level understanding of your GC implementation aside, it isn't a big deal to let the .NET users know that if they pass .NET GC heap objects into Wasm then they'll always be kept alive until a Wasmtime GC is triggered, either automatically or manually. |
Yeah, if the reference is going to outlive the call, then we could do that optimization. This does mean that if the Wasm doesn't need the reference after some point, and the host doesn't actually need to use the reference again, then it can't be reclaimed eagerly at the next GC. With the I'm sure the trade off favors one approach or another depending on the specifics. |
Filed bytecodealliance/wasmtime#2056 to investigate taking advantage of this |
Sorry, I was basically just repeating myself there for no reason, so I deleted my last comment 😅. Thanks for filing the issue! |
Now that the reference types proposal is implemented in Wasmtime, let's implement it for .NET embeddings!
This means fully supporting the ref values, ref value types, handling reference types in host functions, handling reference types when invoking Wasm functions, and properly rooting .NET GC heap references when passing in and out of WebAssembly.
The text was updated successfully, but these errors were encountered: