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
Panic about missing trampolines with subtyping in signatures #8432
Comments
As discussed offline, we should look up the trampoline based on the import signature, not the wrapped function's type (which can be a subtype of the import signature). |
also happens when application note: unsafe fn |
I started poking at this. Things are a bit hairy because we update I think the best way to move forward is to center that invariant, and not make it an accidental after thought, by
|
I like the sound of that yeah and it makes sense to me! |
(I've been working on a patch, still have a few kinks to work out) |
Previously, we would look up a wasm-to-native trampoline in the Wasm module based on the host function's type. With Wasm GC and subtyping, this becomes problematic because a Wasm module can import a function of type `T` but the host can define a function of type `U` where `U <: T`. And if the Wasm has never defined type `U` then it wouldn't have a trampoline for it. But our trampolines don't actually care, they treat all reference values within the same type hierarchy identically. So the trampoline for `T` would have worked in practice. But once we find a trampoline for a function, we cache it and reuse it every time that function is used in the same store again. Even if the function is imported with its precise type somewhere else. So then we would have a trampoline of the wrong type. But this happened to be okay in practice because the trampolines happen not to inspect their arguments or do anything with them other than forward them between calling convention locations. But relying on that accidental invariant seems fragile and like a gun aimed at the future's feet. This commit makes that invariant non-accidental, centering it and hopefully making it less fragile by doing so, by making every function type have an associated "trampoline type". A trampoline type is the original function type but where all the reference types in its params and results are replaced with the nullable top versions, e.g. `(ref $my_struct)` is replaced with `(ref null any)`. Often a function type is its own associated trampoline type, as is the case for all functions that don't have take or return any references, for example. Then, all trampoline lookup begins by first getting the trampoline type of the actual function type, or actual import type, and then only afterwards finding for the pre-compiled trampoline in the Wasm module. Fixes bytecodealliance#8432 Co-Authored-By: Jamey Sharp <jsharp@fastly.com>
Previously, we would look up a wasm-to-native trampoline in the Wasm module based on the host function's type. With Wasm GC and subtyping, this becomes problematic because a Wasm module can import a function of type `T` but the host can define a function of type `U` where `U <: T`. And if the Wasm has never defined type `U` then it wouldn't have a trampoline for it. But our trampolines don't actually care, they treat all reference values within the same type hierarchy identically. So the trampoline for `T` would have worked in practice. But once we find a trampoline for a function, we cache it and reuse it every time that function is used in the same store again. Even if the function is imported with its precise type somewhere else. So then we would have a trampoline of the wrong type. But this happened to be okay in practice because the trampolines happen not to inspect their arguments or do anything with them other than forward them between calling convention locations. But relying on that accidental invariant seems fragile and like a gun aimed at the future's feet. This commit makes that invariant non-accidental, centering it and hopefully making it less fragile by doing so, by making every function type have an associated "trampoline type". A trampoline type is the original function type but where all the reference types in its params and results are replaced with the nullable top versions, e.g. `(ref $my_struct)` is replaced with `(ref null any)`. Often a function type is its own associated trampoline type, as is the case for all functions that don't have take or return any references, for example. Then, all trampoline lookup begins by first getting the trampoline type of the actual function type, or actual import type, and then only afterwards finding for the pre-compiled trampoline in the Wasm module. Fixes bytecodealliance#8432 Co-Authored-By: Jamey Sharp <jsharp@fastly.com>
* wasmtime(gc): Fix wasm-to-native trampoline lookup for subtyping Previously, we would look up a wasm-to-native trampoline in the Wasm module based on the host function's type. With Wasm GC and subtyping, this becomes problematic because a Wasm module can import a function of type `T` but the host can define a function of type `U` where `U <: T`. And if the Wasm has never defined type `U` then it wouldn't have a trampoline for it. But our trampolines don't actually care, they treat all reference values within the same type hierarchy identically. So the trampoline for `T` would have worked in practice. But once we find a trampoline for a function, we cache it and reuse it every time that function is used in the same store again. Even if the function is imported with its precise type somewhere else. So then we would have a trampoline of the wrong type. But this happened to be okay in practice because the trampolines happen not to inspect their arguments or do anything with them other than forward them between calling convention locations. But relying on that accidental invariant seems fragile and like a gun aimed at the future's feet. This commit makes that invariant non-accidental, centering it and hopefully making it less fragile by doing so, by making every function type have an associated "trampoline type". A trampoline type is the original function type but where all the reference types in its params and results are replaced with the nullable top versions, e.g. `(ref $my_struct)` is replaced with `(ref null any)`. Often a function type is its own associated trampoline type, as is the case for all functions that don't have take or return any references, for example. Then, all trampoline lookup begins by first getting the trampoline type of the actual function type, or actual import type, and then only afterwards finding for the pre-compiled trampoline in the Wasm module. Fixes #8432 Co-Authored-By: Jamey Sharp <jsharp@fastly.com> * Fix no-std build --------- Co-authored-by: Jamey Sharp <jsharp@fastly.com>
This program:
compiled against the
main
branch currently runs as:cc @fitzgen
The text was updated successfully, but these errors were encountered: