-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Importing and Exporting in WebAssembly #11941
Comments
When compiling to native binaries, all |
I think the issue is currently all top-level funs are implicitly exported, so if we simply adjust wasm's linker command it too will export everything, including e.g. our own re-implementations of compiler-rt. Thus there needs a mechanism to hide some top-level funs from the compiled object. This feature indeed is not exclusive to wasm. There is also a parallel between those "reactor" programs and I would not worry about exporting names until Crystal has the more general ability to build C-compatible shared libraries. |
So, for exporting we should actually go the other way around: every These reactor programs are very much like shared libraries, but in the case of wasm they are still complete programs and Crystal can already target those. Hiding symbols (not exporting a function) can be viewed as a kind of size optimization now, and binary size is quite important for wasm. Either way, I'll measure it, I think the impact isn't that big yet. Offtopic: @HertzDevil seeing now that you mentioned compiler-rt, I see that there are some functions that are not implemented for wasm and we are being forced to link against clang's compiler-rt. I'll check which of those are needed so that they can be implemented. |
this had something update yet? If export funciton works, people will can use crystal to generate wasm to use in python code, mean use This feature may attract more people to use crystal in other languages( example: |
Bump. There is a PR #11935 implementing this proposal. ImportThe proposal is aligned with other languages and fits well with the ExportExporting functions allows the embedder to call Crystal methods from outside, like exposing a WASM module to a Web page with JavaScript. The original proposal was to add a custom annotation to mark which As a proof of concept I implemented exporting methods in my require "js"
JS.export def print_hello(name : String)
puts "Hello, #{name}!"
end And the shard will generate a low level I would like some direction from the core team about this: It would be better to wait for more user demand before going forward? Or is there need for more detailed discussion before committing on a particular implementation? Or there are other priorities right now and this should just wait a little bit more? I'm good with any of these. |
Hello! @straight-shoota @HertzDevil approve this PR #11935 need more discussion among you and @lbguilherme or someone? This PR #11935 had been not active from April. I just want Crystal give more support for Webassembly... And the people which contribute mostly to Webassembly maybe @lbguilherme? If ture, how about you invite @lbguilherme to be one of Crystal Lang Team Core Member? That maybe will speed up the support of Webassembly... |
Closing as #11935 was merged 🚀 |
First of all, some introduction to the problem.
A Wasm Module can import and export functions and global variables. There are some other entities like tables and memories, but those aren't common and I won't focus on them.
A function signatures receive a tuple of integers/floats as arguments and returns a tuple of integers/floats as well. When importing them, they need a name and a module name. A wasm module defines many functions, some of them may be marked as exported, those must be named. Globals follow a similar logic to functions, but they are a single integer/float instead of a callable.
A compilation unit (or object file) is like a mini wasm module that the linker will work on. Its work is to merge all of them into a single wasm module. It does so in the following way:
"env"
module, it finds some exported function of the same name and match them. The signature must be identical._start
is exported if it exists.We can look for wasi-libc as an example of this. It imports the Wasi functions from
"wasi_snapshot_preview1"
and exports many of the standard functions of libc. Crystal then imports those functions from"env"
and the linker connects the two. Libpcre imports libc functions from"env"
and exports its functions and so on.For exporting a function on the final wasm module, its name needs to be specified as a cli flag to the linker.
Crystal currently imports only the wasi functions via wasi-libc and exports only
_start
, defined either with adding wasi-libc'scrt1.o
to the linker or by #11936. But there is need to both import and export functions on different scenarios.A wasm program can either behave as a "command" or a "reactor".
A command program has an exported function that serve as an entrypoint. It is the only exported function and it will be called only once by the runtime. These programs starts, runs, and finishes. For Wasi this function is called
_start
, but it may be named differently outside Wasi.Now reactor programs are a little different, they may export any number of functions, where one of them serves as the initialization and is invoked once by the runtime before any other. After that the other exported functions can be invoked any number of times. This is commonly used for plug-ins.
In any of these scenarios, the program may import functions provided by the runtime. Wasi-compliant runtimes (like wasmtime or wasmer) will expose the wasi standard functions, but other runtimes may expose any set of functions to be imported by the wasm module, this is also relevant for plug-ins.
This Crystal needs two functionalities to be able to fully support this:
"env"
)Importing
Rust has a
wasm_import_module
key on the link attribute:Docs: https://doc.rust-lang.org/reference/items/external-blocks.html#the-link-attribute
Original issue: rust-lang/rust#52090
I propose we use the same notation for Crystal:
This should apply to both functions and globals defined inside the lib.
See #11935 for a possible implementation of this.
Exporting
Rust uses the following notation to mark a function as explicitely exported:
We don't have a Crystal equivalent, so I suggest adding an annotation that can be applied to
fun
functions, something like this:It would have the effect of modifying the link command for wasm. Nothing needs to change on the LLVM output.
The text was updated successfully, but these errors were encountered: