alexcrichton requested fitzgen for a review on PR #10897.
alexcrichton opened PR #10897 from alexcrichton:refactor-func-representation to bytecodealliance:main:
This commit rewrites the internals of
wasmtime::Func. TheStoredtype is no longer used meaning that it's now free to create awasmtime::Funcat any time. It is effectively a store-taggedNonNull<VMFuncRef>. This required a few internal changes to how functions are passed around:
Previously the insertion of a
wasm_call-lessVMFuncRefwas deferred until the raw pointer was loaded. Now the insertion happens immediately as soon as the function is placed within a store. This is done to ensure that aFunccorresponds to one exactVMFuncRefand that's it, and lazily filled in versions within the store are still lazily filled in but they're more eagerly allocated. This isn't expected to have much of an impact perf-wise since all these lazily allocated functions were already almost guaranteed to get lazily allocated anyway.Filling in "holes" in
VMFuncRef, notably thewasm_callfield, no longer happens lazily when theVMFuncRefis demanded. Instead during instantiation a pass is made to fill in holes with the new module being instantiated (after registration). Additionally when a lazily-allocatedVMFuncRefis created the module registry is checked immediately. This means that all store-localVMFuncRefvalues are either filled in immediately or filled in during instantiation. This notably means that the previous logic inFunc::vmimportis now "just" an.unwrap()with a lot of comments saying why the unwrap shouldn't panic.To implement this commit a previous optimization for the
FuncAPI was removed as well, namelyFunc::callwill become slower after this commit. TheFunc::callAPI is a dynamically-typed API which requires run-time type-checking of arguments. Previously aFuncTypewas loaded into a cache once-per-Funcwhich helped amortize the cost of usingFunc::callrepeatedly. Now, though, there's no natural place to put such a cache sinceFuncno longer has dedicated storage within aStore. Historically this optimization was added for the C API before the*_call_uncheckedAPIs existed, but nowadays the*_call_uncheckedAPIs should suffice for performance-critical applications where needed. In the future it might also be possible to have a hash map in theStoreof aVMSharedTypeIndextoFuncTypewhich is lazily populated based on calls toFunc::call, but that feels a bit overkill nowadays for a possibly rarely-used map.The no-longer-necessary
RootedHostFunctype is now gone as its unsafety and various contracts are subsumed by other preexistingunsafeblocks.The specific drop order between
StoreOpaque::store_dataandStoreOpaque::rooted_host_funcsis removed. Therooted_host_funcsfield now lives in thefunc_refsfield and theFuncKindtype, where the destructors came from before, is no more.The
func_refsfield has grown storage locations for a variety of "keep this thing alive as long as the store" related to functions and such.Closes #10868
<!--
Please make sure you include the following information:
If this work has been discussed elsewhere, please include a link to that
conversation. If it was discussed in an issue, just mention "issue #...".Explain why this change is needed. If the details are in an issue already,
this can be brief.Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.htmlPlease ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->
alexcrichton requested wasmtime-core-reviewers for a review on PR #10897.
alexcrichton commented on PR #10897:
I'll also note that this is split out of https://github.com/bytecodealliance/wasmtime/pull/10870/commits/b228b9718ab0c7e405ff98f62207d63f0e8484a7
alexcrichton edited a comment on PR #10897:
I'll also note that this is split out of https://github.com/bytecodealliance/wasmtime/pull/10870
alexcrichton updated PR #10897.
fitzgen created PR review comment:
Kind of an aside but should all of these assertions actually live in the
wasmtime-c-apicrate so that we don't need to have a dummy struct which itself needs to be kept in sync with the struct that we actually care about? We've removed one syncing problem but added another, so we haven't really changed anything. I guess the only assertion that would remain in thewasmtimecrate would be the one for the offset of thestorefield.
fitzgen created PR review comment:
/// Attempts to fill the `wasm_call` field of `func_ref` given `modules` /// registered and returns `true` if the field was filled, `false` otherwise.
fitzgen created PR review comment:
Sooooooo nice to get rid of
FuncKind
fitzgen submitted PR review:
Very nice!!
fitzgen created PR review comment:
Just to clarify, since there isn't any
assert!here:// Note that this is a load-bearing `unwrap` here, but is
alexcrichton updated PR #10897.
alexcrichton updated PR #10897.
alexcrichton submitted PR review.
alexcrichton created PR review comment:
Oh I think you might be assuming there's a
struct wasmtime_func_t { ... }in Rust incrates/c-apibut that doesn't exist. In that sense thisstruct Cis the only C-version-written-in-Rust anywhere in the codebase, and I figured here was a good as place as any to test things out.
alexcrichton has enabled auto merge for PR #10897.
fitzgen submitted PR review.
fitzgen created PR review comment:
Ah, I was indeed
alexcrichton merged PR #10897.
Last updated: Dec 06 2025 at 07:03 UTC