Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upstd: Add a new wasm32-unknown-unknown target #45905
Conversation
This comment has been minimized.
This comment has been minimized.
|
I'd also like to doubly and triply emphasize how this target is a work in progress. The precise semantics of how it works and how everything gets hooked up will likely change over time, but I feel that it's also beneficial if we can get more testing of this backend and more testing of the integration, and hopefully start seeing some neat projects leveraging these benefits! |
alexcrichton
force-pushed the
alexcrichton:add-wasm-target
branch
from
df2c76e
to
7552aa5
Nov 10, 2017
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton I just want to say how exciting it is to see so much progress toward making wasm work well with Rust :) Thanks for doing all of this! |
shepmaster
added
C-enhancement
O-wasm
S-waiting-on-review
T-compiler
labels
Nov 10, 2017
This comment has been minimized.
This comment has been minimized.
|
Let's pick a reviewer... r? @eddyb |
rust-highfive
assigned
eddyb
Nov 10, 2017
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton you've some tidy failures:
|
This comment has been minimized.
This comment has been minimized.
|
LGTM but this is a pretty large change. cc @rust-lang/compiler @rust-lang/libs |
nagisa
reviewed
Nov 10, 2017
| @@ -39,8 +38,7 @@ unsafe impl<'a> Alloc for &'a A { | |||
| static GLOBAL: A = A; | |||
|
|
|||
| fn main() { | |||
| env::set_var("FOO", "bar"); | |||
| drop(env::var("FOO")); | |||
| println!("hello!"); | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Nov 10, 2017
Author
Member
Nah this is just intended to force an allocation somewhere that LLVM can't optimize away
NikVolf
reviewed
Nov 10, 2017
| //! | ||
| //! Right now we don't support this, so this is just stubs | ||
|
|
||
| #![allow(private_no_mangle_fns)] |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Out of curiosity, how does this work? Is there an allocator runtime? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
jasondavies
commented
Nov 10, 2017
•
|
This is great!
If I simply clone this branch, run
Edit: I managed to build successfully using LLVM 5, using the |
konstin
reviewed
Nov 10, 2017
| url = https://github.com/alexcrichton/dlmalloc-rs | ||
| [submodule "src/binaryen"] | ||
| path = src/binaryen | ||
| url = https://github.com/WebAssembly/binaryen |
This comment has been minimized.
This comment has been minimized.
konstin
Nov 10, 2017
There's a small inconsistency here: All the other crates use https://github.com/owner/repo.git instead of https://github.com/owner/repo
alexcrichton
force-pushed the
alexcrichton:add-wasm-target
branch
from
7552aa5
to
dde8f95
Nov 10, 2017
This comment has been minimized.
This comment has been minimized.
|
@SimonSapin indeed there is! Wasm actually has memory allocation instructions which the allocator runtime leverages to implement a runtime allocator. |
alexcrichton
force-pushed the
alexcrichton:add-wasm-target
branch
from
dde8f95
to
f483780
Nov 10, 2017
This comment has been minimized.
This comment has been minimized.
|
@jasondavies oops sorry! Was pinned to the wrong commit of dlmalloc-rs, I believe it should work now. |
alexcrichton
force-pushed the
alexcrichton:add-wasm-target
branch
from
f41e64f
to
f483780
Nov 10, 2017
This comment has been minimized.
This comment has been minimized.
ElvishJerricco
commented
Nov 11, 2017
|
Does https://github.com/WebAssembly/lld/tree/wasm have to be merged upstream before you can just use the WebAssembly port of LLD? |
This comment has been minimized.
This comment has been minimized.
|
New tidy errors:
|
alexcrichton
force-pushed the
alexcrichton:add-wasm-target
branch
from
f483780
to
9bdb989
Nov 11, 2017
This comment has been minimized.
This comment has been minimized.
|
@ElvishJerricco "just use the WebAssembly port of LLD" is actually quite involved, so I wanted to get something working (aka this PR) before starting on a new venture to discover even more integration and/or LLD bugs. This is the final state, though, to use LLD to link WebAsembly (AFAIK) |
This comment has been minimized.
This comment has been minimized.
|
FYI: If someone wants to play with this branch and WASM in Node, I've pushed some of my experiments to this repo: https://github.com/killercup/wasm-experiments |
This comment has been minimized.
This comment has been minimized.
|
|
alexcrichton
force-pushed the
alexcrichton:add-wasm-target
branch
2 times, most recently
from
3a89d09
to
ea0b568
Nov 12, 2017
This comment has been minimized.
This comment has been minimized.
Luckily enough, a lot of things can still work with the current state |
This comment has been minimized.
This comment has been minimized.
|
@badboy Mostly just math works, yeah, but for real app that interacts with filesystem etc. you will need JS runtime. |
This comment has been minimized.
This comment has been minimized.
|
Just passed by and wanted to note that WASM (despite it's name) is not only for the Web. By it's nature WASM, have no ABI and have no notion of filesystem and networking. So this statement
have a lot of sense for me. For all other things there is Emscripten : ) |
This comment has been minimized.
This comment has been minimized.
Heh, so does x86, it doesn't mean they're not needed for apps :) |
This comment has been minimized.
This comment has been minimized.
|
Yeah, Wasm (as x86) is just an ISA. fs and stuff like that is just a different level of abstraction. For me wasm32-unknown-unknown seems more like a bare metal environment (like Arm MCU). “apps” for mcus doesnt require (and usually doesnt have a notion of) fs and networking. So is wasm Also, as I mentioned before, you can use Rust with |
This comment has been minimized.
This comment has been minimized.
|
Please, again, I'm not trying to diminish the importance of this addition, no need to try and prove to me how awesome it is |
This comment has been minimized.
This comment has been minimized.
|
Let's work together and provide the missing pieces then (either as JavaScript shims or Rust-side implementations of functionality). I don't know how easy it will be to extract this stuff from Emscripten. Anyway, this is not the place to discuss it. |
This comment has been minimized.
This comment has been minimized.
It seemed like the best place (as it's related to the context of PR), but if you have other suggestions, sure. |
This comment has been minimized.
This comment has been minimized.
|
My point is that many things from the standart library shouldn't get any bindings to host environment. For example, what means to spawn a process in wasm? What character should be used as a path seperator? How
I didn't even think of that! |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Well other environments might provide own implementations of these system bindings if they need to. |
This comment has been minimized.
This comment has been minimized.
A better place would be #44006 . It is a bit underused sadly :/ |
This comment has been minimized.
This comment has been minimized.
lilianmoraru
commented
Nov 21, 2017
|
@alexcrichton Now, the linker has some support for wasm: https://reviews.llvm.org/rL318539 |
This comment has been minimized.
This comment has been minimized.
|
Thank you @est31 ! I've moved discussion there |
OpenGG
added a commit
to OpenGG/docker-rust-wasm
that referenced
this pull request
Nov 21, 2017
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton You mention LLVM 5. Where is your branch and how do I use it? I'm playing with the wasm target but get a segfault during compilation. Before I dig deeper I'd like to try a more recent LLVM as it might be fixed already. |
This comment has been minimized.
This comment has been minimized.
Dessix
commented
Nov 26, 2017
|
@RReverser the option of not having the extra libraries and runtimes bolted on enables use of this for embedded systems where including additional support code is unnecessary or even undesirable. Ensuring that remains an option would be an important consideration for at least these scenarios. |
This comment has been minimized.
This comment has been minimized.
|
@Dessix One absolutely doesn't contradict another, you can always just not include runtime and not use anything that requires it. But anyway, this discussion was moved to another issue, please see above. |
alexcrichton
referenced this pull request
Nov 27, 2017
Merged
ci: Start running wasm32 tests on Travis #46291
This comment has been minimized.
This comment has been minimized.
|
I've now also opened a PR to start running tests on CI over at #46291 |
This comment has been minimized.
This comment has been minimized.
|
Since this is basically the same as #37133, I wouldn't have expected this to get merged in this state in light of the comments there and in https://internals.rust-lang.org/t/refactoring-std-for-ultimate-portability/4301. Will you reconsider #37133 for merging if I rebase that? |
This comment has been minimized.
This comment has been minimized.
|
@jethrogb it's definitely worth revisiting, yes. Note that the wasm target is a somewhat special case, since it exists at the liballoc level and will eventually include some of the libstd layer as well (e.g. threads). It's also a specific (highly desired) platform, so the motivation was pretty different. For #37133, is the motivation primarily to have a kind of "template" for tackling other, similar cases? re: the PAL, AFAIK not much has happened there, and I think the whole story should be rebooted. In particular, we should take into account (and implement...) the portability lint, which in the long term may allow us to do away with the core/std layering altogether. In any case, before rebasing, I'd suggest at least an internals thread laying out the motivation and attempting to reach some consensus there. You could ping me, @alexcrichton and @sfackler on the thread to ensure visibility. |
bennyyip
referenced this pull request
Dec 2, 2017
Merged
add rust-nightly-wasm32-unknown-unknown #586
aochagavia
reviewed
Dec 3, 2017
| pub fn cosh(n: f64) -> f64; | ||
| #[link_name = "Math_expm1"] | ||
| pub fn expm1(n: f64) -> f64; | ||
| pub fn fdim(a: f64, b: f64) -> f64; |
This comment has been minimized.
This comment has been minimized.
aochagavia
Dec 3, 2017
Contributor
Looks like you forgot to add a #[link_name = "Math_fdim"] attribute
This comment has been minimized.
This comment has been minimized.
alexcrichton
Dec 3, 2017
Author
Member
Unfortunately Math.fdim isn't actually a function, and hopefully none of these will be necessary in the future regardless, it's mostly a bug that they're all here in the first place.
alexcrichton commentedNov 10, 2017
This commit adds a new target to the compiler: wasm32-unknown-unknown. This target is a reimagining of what it looks like to generate WebAssembly code from Rust. Instead of using Emscripten which can bring with it a weighty runtime this instead is a target which uses only the LLVM backend for WebAssembly and a "custom linker" for now which will hopefully one day be direct calls to lld.
Notable features of this target include:
HashMap,Vec, etc).#[no_std]crate should be 100% compatible with this new target.This target is currently somewhat janky due to how linking works. The "linking" is currently unconditional whole program LTO (aka LLVM is being used as a linker). Naturally that means compiling programs is pretty slow! Eventually though this target should have a linker.
This target is also intended to be quite experimental. I'm hoping that this can act as a catalyst for further experimentation in Rust with WebAssembly. Breaking changes are very likely to land to this target, so it's not recommended to rely on it in any critical capacity yet. We'll let you know when it's "production ready".
Building yourself
First you'll need to configure the build of LLVM and enable this target
Next you'll want to remove any previously compiled LLVM as it needs to be rebuilt with WebAssembly support. You can do that with:
And then you're good to go! A
./x.py buildshould give you a rustc with the appropriate libstd target.Test support
Currently testing-wise this target is looking pretty good but isn't complete. I've got almost the entire
run-passtest suite working with this target (lots of tests ignored, but many passing as well). Thecoretest suite is still getting LLVM bugs fixed to get that working and will take some time. Relatively simple programs all seem to work though!In general I've only tested this with a local fork that makes use of LLVM 5 rather than our current LLVM 4 on master. The LLVM 4 WebAssembly backend AFAIK isn't broken per se but is likely missing bug fixes available on LLVM 5. I'm hoping though that we can decouple the LLVM 5 upgrade and adding this wasm target!
But the modules generated are huge!
It's worth nothing that you may not immediately see the "smallest possible wasm module" for the input you feed to rustc. For various reasons it's very difficult to get rid of the final "bloat" in vanilla rustc (again, a real linker should fix all this). For now what you'll have to do is:
And then
bar.wasmshould be the smallest we can get it!In any case for now I'd love feedback on this, particularly on the various integration points if you've got better ideas of how to approach them!