-
Notifications
You must be signed in to change notification settings - Fork 10.2k
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
[wasm] Add @_expose(wasm)
attribute for top-level functions
#68524
[wasm] Add @_expose(wasm)
attribute for top-level functions
#68524
Conversation
@swift-ci Please smoke test |
@swift-ci build toolchain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with Wasm but this looks like a good feature to me!
It's probably worth for @hyp to take a look as well, since he's the author of @_expose(Cxx)
attribute.
One comment I have is that we should probably support multiple expose attributes on a single decl, in case someone would like to e.g. expose a Swift function to C++ and Wasm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This overall is looking really solid. I agree with Egor. I would like to see the behavior for a function that is exported both for WASM and for C.
Another question, is the export of the function based on target triple? Like does it make sense for a C static archive to have WASM entries if we're not compiling for WASM? Or in the other direction, does it make sense to generate C entrypoints when we are compiling for WASM?
I'd assume in LLVM this is a no-op for non-Wasm triples.
Not in my understanding, Wasm exports are quite specific to Wasm object format, I don't think they'd be valid in any way in other object formats.
|
@egorzhdan Thank you for reviewing! It makes sense to me to unlock the combination of Cxx and Wasm exposure on a single decl (while we cannot accept multiple @etcwilde Thanks too :) The exposed entrypoint is generated only when lowering LLVM IR to Wasm object file, so the metadata attribute added in this PR is no-op on other targets. I'll leave a comment on the place where the metadata attribute is added regardless of the target triple. |
@egorzhdan @etcwilde It's quite different from the combination of cdecl and Wasm exposure because the C interface function is defined within the compilation unit. I'm not sure whether we should expose C++ interface function as Wasm entrypoint as we do in cdecl and Wasm combination, or we should expose Swift interface as Wasm entrypoint in C++ and Wasm case? (Or just prohibit the case for now?) WDYT? |
What I meant by exposing a function for both C++ and Wasm is: imagine you have a multiplatform Swift module that can be compiled for both Wasm (so the function is annotated with I don't know a use case for having multiple |
@egorzhdan Thank you for your elaboration. So if we have the following definition, @_expose(Cxx)
func exposeToCxxWasm(input: String) {} We have the following interop header: namespace foo SWIFT_PRIVATE_ATTR SWIFT_SYMBOL_MODULE("foo") {
SWIFT_INLINE_THUNK void exposeToCxxWasm(const swift::String& input) noexcept SWIFT_SYMBOL("s:3foo15exposeToCxxWasm5inputySS_tF") {
return _impl::$s3foo15exposeToCxxWasm5inputySS_tF(_impl::swift_interop_passDirect_foo_uint64_t_0_8_void_ptr_8_16(swift::_impl::_impl_String::getOpaquePointer(input)));
}
} // namespace foo If we simply add So I tried exposing a Wasm entrypoint with C++ calling convention, but I found adding |
|
@hyp Thank you Alex!
Actually, Wasm has two-level namespace to reference a function in an external image. In Clang, it's expressed by |
Can we leave C++ and Wasm combination as TODO until we come up with better solutions? |
That's fine with me! It sounds like this combination should just work without extra annotations, unless C++ and Swift pieces live in different WASM modules.
Is there a potential solution there? How does another Swift module know how to import another Wasm module if it can be changed dynamically? |
Yes! Linking within a single image works well as it is now!
Currently, we don't support Swift's However, both of them can limit future evolutions around dynamic linking, unfortunately. So I think it would be great to support it after we support dynamic linking in wasm. |
@swift-ci Please smoke test |
This attribute instructs the compiler that this function declaration should be "export"ed from this .wasm module. It's equivalent of Clang's `__attribute__((export_name("name")))`
But multiple @_expose with the same exposure kind are still invalid.
9a66053
to
ac440c3
Compare
@swift-ci Please test |
Today, there is no way to create an "export" from Swift. (The current workaround is using
@_cdecl
and linker option, or linking C source1).This PR adds a new variant of
@_expose
attribute withwasm
parameter (and optionally with custom name).This attribute instructs the compiler that this function declaration should be "export"ed from this .wasm module. It's equivalent of Clang's
__attribute__((export_name("name")))
The attribute doesn't have any effect on to function signature and calling convention but only adds LLVM meta attribute to the function. If it's applied with
@_cdecl
at the same time, only C thunk is exported.Radar: rdar://115502069
Footnotes
https://book.swiftwasm.org/examples/exporting-function.html ↩