16 ms·
Rust: Enable WebAssembly backend by default
- vincentriemer 9y agoMaybe I just can't find it, but the largest blocker for using Rust on the web for me is a lack of a exposure/binding system (like embind). I'm not particularly interested in writing entire webapps in Rust but I do see it being useful for smaller self-contained modules inside a larger JS app. Not having a robust binding API makes that difficult. EDIT: But unrelated criticisms aside, congrats on the progress! I'm excited to see more first class support of WASM from languages other than C/C++.
- arbie 9y agoI am excited for WASM for the same reason; not for wholesale migration, but targeted optimization. Hope documentation for this (likely very popular use-case) improves as WASM matures.
- cormacrelf 9y agoCan anyone describe the (overhead) cost of calling into WASM code in the implementations so far? A lot of optimize-able areas are things like RxJS or Promise implementations (eg Bluebird), or generally libraries making the stack trace like [userspace code] -> [library code, approx 20 stack frames] -> [more userspace]. Should we think of the WASM-JS bridge cost like system calls, or like inline assembly?
- skybrian 9y agoYou need to look at serialization overhead for exchanging data. For example, I don't think web assembly has direct access to JavaScript strings? What about JSON? Seems like you're either converting a lot of strings (which wastes memory) or calling lots of JavaScript string methods from web assembly, which is not likely to be fast in an inner loop.
- cormacrelf 9y agoTo be clear, I haven't done anything serious in WASM that would hit any limits here.
- josephg 9y agoI'm curious about this too. I hand-wrote a perlin noise generation function in asmjs when that was the future. Then I called my noise function from a loop in javascript to paint an image (1 call per pixel - about 1M calls). Running the perlin noise code with the asmjs engine in Firefox turned out to be a bit slower than running all the code through FF's regular javascript engine. The asmjs code ran fast, but the FFI overhead at the boundary between JS and asmjs made the system slower overall. Given how easy it looks, I might try the same experiment with Rust & WASM to see where we're at. That said, this is the sort of thing which can definitely be improved over time.
- Crespyl 9y agoThese days it's probably possible to use a buffer in the asmjs/WASM side and generate the image data there, only exporting back to the JS side after the job is complete. That should significantly cut down on the overhead.
- Matthias247 9y agoI guess it will depend heavily on the type of your exchanged parameters. If it's a few integers then it's no problem since both JS and the WASM side can easily read those. However for complex objects (like Javascript objects, strings or DOM objects) objects you need a serialization mechanism for those. That might be similar to what typical system call implementations do. However system calls mostly have a very simply set of parameters, so transferring Javascript objects might be far worse. If you would want to share Javascript objects on both sides you would also need some kind of reference-counted handles, which can identify the objects. I haven't done anything with WASM yet, but I'm pretty sure the domains you mentioned (promises, asynchronous programming and also DOM handling) are the ones which will least likely benefit from WASM. Lower level math algorithms might however benefit a lot.
- themihai 9y agoI think the real issue is the lack of DOM access rather than binding to JS.
- tyingq 9y agoSupposedly they are adding things like polymorphic inline cache, garbage collection, threads, etc, that would make it more like a VM. Perhaps enough that Python, PHP, Ruby, or similar languages could run in WASM without downloading the whole runtime. That plus native DOM access might make the front end web as diverse as the back end web. I'm curious whether the fragmentation that would bring on is a net add, or a net drain on the web as a whole.
- themihai 9y agoI wouldn't say that fragmentation on the backend is a net drain as a whole...
- ralfn 9y agoIsn't the point of the whole architecture that from a security perspective all IO will always be through JavaScript. Replicating the attack surface of the browser in JavaScript land in WebAssembly land goes against the whole design of it. It's for the community to make nice libraries that expose the browser features to WebAssembly land in JavaScript. It's also the right place to deal with cross browser differences.
- themihai 9y agoWell the IO is ultimately handled/sandboxed by the browser not by JavaScript so as far as security is concerned JavaScript and WASM should have the same access to IO/Web APIs. I think the attack surface you are talking about is really a implementation detail and browsers could use a common middleware that both JavaScript and WASM can use. In a distant future I would see JavaScript actually compiled to WASM(maybe the browser would pipe it directly into a WASM compiler before to execute it) to reduce the maintenance costs and perhaps also the attack surface you are talking about. The whole point of WASM was to cut off the middle man (i.e. JavaScript) so that we can reach native-like performance. WASM should be the ultimate dominator not JavaScript. >> It's for the community to make nice libraries that expose the browser features to WebAssembly land in JavaScript. It's also the right place to deal with cross browser differences. I believe the community could make nice libraries compiled to WASM that anyone can use regardless of the programming language. JavaScript would be just another language(albeit a popular one, at least due legacy reasons).
- kenOfYugen 9y agoWhat do you mean by 'first class support' of WASM in C/C++? Is it somehow possible to produce wasm binaries without utilizing emscripten?
- RX14 9y agoYes, llvm has built in wasm support for a while now.
- buu700 9y agoThe plan for emscripten is actually to replace its own wasm compiler with LLVM, and possibly drop its asm.js compiler in favor of running wasm2asm on LLVM's wasm output: https://github.com/kripken/emscripten/issues/5827 https://github.com/kripken/emscripten/issues/5827 Aside from keeping emscripten's code smaller / more maintainable and allowing the team to focus more on its role as high-level tooling, this should improve the size and performance of emscripten output since IIRC it's currently missing out on a lot of optimization opportunity by producing wasm as transpiled asm.js.
- azakai 9y ago> IIRC it's currently missing out on a lot of optimization opportunity by producing wasm as transpiled asm.js. That's actually not true: the asm.js => wasm path emits better code (smaller, faster) than the wasm backend path currently. However, the wasm backend path is being improved, and should eventually get to parity.
- buu700 9y agoAh okay, interesting. Is it because wasm doesn't yet add any new functionality over asm.js that using asm.js as an intermediary step isn't inherently worse? In that case, it sounds like the LLVM backend will only yield clear user-facing benefits when new features like pthreads are introduced?
- 9y ago
- steveklabnik 9y agoI agree that the best use-case here isn't full apps in Rust, but writing high-performance modules. The webpack team is working on stuff so you can just drop a rust file into your proejct, and it will do everything needed for super easy integration. https://crates.io/crates/stdweb https://crates.io/crates/stdweb sort of gives you the bindings you want, by the way.
- bluejekyll 9y agoThis makes me so excited! Great job to Alex and the entire team getting this done. I know Rust is not the most perfect language for some. For me, it’s really exciting that there is finally a high level language which can scale for every potential use case. Rust is great for kernels and the embedded space; Excels in the systems space; Is gaining traction in the native application space; Has great tooling for web backends; and, now, with WASM, it’s capable of targeting the web (Yes, without DOM access this is limited, but my understanding is that is coming at some point in the future). Are there any other runtime free, memory safe languages that can target all of those use cases?
- tyingq 9y ago"Rust is great for kernels and the embedded space" I'm no expert, but from a layperson's perspective, the rust usage in these areas depends on a lot of "unsafe" blocks, fighting the borrow checker, etc. Does that ratchet it down from "great" for this space to something like "ok" or "usable"? Or is this just the best we can do in terms of a memory safe language for kernel and/or bare metal embedded?
- geofft 9y agoThe point of unsafe blocks is to contain unsafety. In a language like C, the natural pattern is to expose raw pointers through the entire codebase and document how to use them correctly, when they can be mutated, who's responsible for freeing them, etc. In Rust, the natural pattern is to implement wrapper types and other abstractions that themselves make heavy use of unsafe blocks but whose APIs are safe. This isn't unique to kernels. The standard heap-allocated vector type in Rust (on which the standard string type is based) is full of unsafe blocks: https://doc.rust-lang.org/src/alloc/vec.rs.html https://doc.rust-lang.org/src/alloc/vec.rs.html The problem of implementing a heap-allocated vector, with some elements uninitialized but available for use and with the ability to reallocate the entire vector and copy the members, is not a problem that lends itself well to the borrow checker's view of the world, so raw pointers are a fine way to solve it. Use of vectors themselves, their iterators, references to items in the vectors, etc. does match the borrow checker's view of the world, so the average Rust program running in userspace doesn't have to care that the standard library itself isn't implemented in safe Rust. So copious usage of the "unsafe" keyword in a codebase can be a sign that the code as a whole is more safe: instead of having large portions of the code be unsafe (or instead of having the code pretend it's containing unsafety when it's not), only the parts that need raw memory access use it, and they maintain invariants used by the rest of the code. It is certainly possible to do better - there are no machine-checked proofs that unsafe code does what it claims and upholds the invariants it claims to uphold. There could be, and I'm really interested to see what people do with languages that lend themselves better to proofs (usually dependently-typed, Turing-incomplete-but-very-powerful languages). But right now the state of the art is that such languages are a pain to use and writing proofs is even more of a pain. I think that's where the compromise is right now. The borrow checker is, arguably, a system for proving things about your code; it just only knows how to prove specific things. (Way more than C's type system proves, but way less than you'd prove in a perfect world.)
- knowThySelfx 9y agoGreat. I like the way Rust is going on about.
- phkahler 9y agoSo when will servo become a webapp so we can run it inside firefox? To clarify, this is sarcasm. What I really want to say is when can we run firefox inside firefox? But it's not entirely written in Rust. The point of that question is to illuminate some of the absurdity of web apps. i.e. what function does the outer browser serve in this scenario and why do we need it? Edit: All the answers point to the outer browser as providing a sandbox. I contend that is supposed to be an OS function. I also think that tabs in the browser came about because OSes didn't provide a decent way to handle multiple instances of applications. See what's happening here?
- deleted 9y ago[deleted]
- jonreem 9y agoIt still serves as a sandboxed interpreter/GUI framework and as a frontend for finding and loading apps, regardless of how complex the apps are.
- a_humean 9y agoIsolation. WASM is a target that allows users to effortlessly download and run arbitrary code from the web on all platforms with a modern web browser; an environment that is sandboxed such that arbitrary file system access or other system access is relatively safe and limited even without knowing the intentions of the author. This is why javascript is so popular with its current monopoly on the web. No other language can do that, but with WASM other languages, such as Rust, can be part of the picture.
- dullgiulio 9y agoI don't want to attack Rust or WASM, as I am pretty excited about this, but it's not that easy. That anything that runs into the browser is isolated sandboxed and whatnot is irrelevant. It's still arbitrary code running on often unwilling clients. Don't believe me? Think about ad-blockers.
- 9y ago
- steveklabnik 9y agoI'm so so so excited to see this land! I have a little hello world demo: https://gist.github.com/steveklabnik/d86491646b9e3e420f8806a286ec8e92 https://gist.github.com/steveklabnik/d86491646b9e3e420f8806a... To give you an idea of file sizes, the above produces a 116 byte wasm file. If you leave off the no-std stuff it produces a 3059 byte wasm file. EDIT: I'm actually being told that there was a bug in wasm-gc that's since been fixed, even with libstd it should be able to eliminate all of it and get the tiny file now.
- josephg 9y agoThat’s gorgeous. How much bigger does it grow if you heap allocate? Does it include 2mb of extra code like in normal desktop builds?
- steveklabnik 9y agoI’m away from my computer right now, so may take a while to give you an exact number, but when I first did this, I forgot to turn on optimizations, and the libstd version was 173kb pre-gzip. So I’d imagine it’s similar to that, or at least, that gives you an order of magnitude.
- killercup 9y agoThis Rust code [1] heap allocates some things (e.g., a string with `String::from`), and results in this [2] WASM file, which is 65kB, or 25kB after `gzip -9`. [1]: https://github.com/killercup/wasm-experiments/blob/bf3b30eed6ca73bfc7809f1d87b6604901d3a0b1/examples/hello.rs https://github.com/killercup/wasm-experiments/blob/bf3b30eed... [2]: https://github.com/killercup/wasm-experiments/blob/bf3b30eed6ca73bfc7809f1d87b6604901d3a0b1/hello-wasm.gc.wasm https://github.com/killercup/wasm-experiments/blob/bf3b30eed...
- azakai 9y agoIt should be possible to reduce that a bunch more, 65kB sounds high. Running the binaryen optimizer on that wasm shrinks it by 6%. Probably more can be done on the Rust side.
- xstartup 9y agoWe switched from Go to Rust in production. After the initial ramp-up time, it's really a lot more productive than Go for us, at least.
- qualitytime 9y agoMay I ask what "production" is?
- zimzim 9y agothe actual product environment, not development research or testing.
- GolDDranks 9y agoWhat area of computing you are talking about?
- xstartup 9y agoReal-time fraud detection as service for adtech companies. We started with Java but got tired of GC pauses, perhaps due to an inexperienced team but we were not able to tame it. Then we moved to Go and now we are in Rust.
- gtaylor 9y agoThat is a lot of language swapping. How long of a period did this happen over?
- make3 9y agothat sounds like data science. why aren't you in python?
- kenhwang 9y agoHe mentioned GC pauses being an issue. Python's GC is significantly less sophisticated than Java/Go, which were also not satisfactory enough.
- drhodes 9y agoHas anyone given any thought to dynamic linking wasm objects to save bandwidth?
- steveklabnik 9y agoIt totally works, it's just not particularly easy to do. wasm modules have import and export sections; you'd instantiate the std module first, the instantiate the module that depends on it, pointing its imports at std's exports. I don't know of any tooling that makes this super easy at the moment though, you basically have to do it by hand as far as I know.
- kodablah 9y agoI don't think you can at runtime from wasm though. Imports are resolved at load time. Sure there are call indirect that let you dynamically change the function index but not the import/export. Now if you were willing to reload, you could use the JS API to create modules at runtime with dynamically downloaded pieces, but once created, that's it I think.
- steveklabnik 9y agoSure, I'm talking about "instantiate one big module" vs "instantiate several smaller modules, then finally the last module". Which is a bit different than what you're talking about; you're right that after you've instantiated, you can't change imports.
- drhodes 9y agogreat, thanks, that clarifies things quite a bit.
- deleted 9y ago[deleted]
- ainar-g 9y agoI would prefer compilers that produce compact statically linked "binaries".
- doiwin 9y agoI would like to code WebAssembly by hand. Are there any good tools / tutorials on this?
- kodablah 9y agoProbably not any good tools or tutorials, but the wast format is not that hard [0][1] and most compilers accept that format. Just gotta keep the values on the stack in mind while you write. 0 - http://webassembly.org/docs/text-format/ http://webassembly.org/docs/text-format/ 1 - https://webassembly.github.io/spec/text/index.html https://webassembly.github.io/spec/text/index.html
- lj3 9y agoDo you mean something like this? https://mbebenita.github.io/WasmExplorer/ https://mbebenita.github.io/WasmExplorer/
- idibidiart 9y agoHow does the performance of WASM compare to JIT'd JS code?
- amelius 9y agoThis makes me wonder: does WASM allow a JIT (specializer)? I.e., does WASM allow self-modifying code or code to write code? If not, then JIT'ed JS could still be faster than WASM.
- steveklabnik 9y agoWasm code is normally JIT-ed by the JS VM. That is, browser implementations don’t have an entire separate VM for wasm.
- amaranth 9y agoIt's going to be heavily dependent on what you're doing. WASM can be as fast as native code but is more likely to be 1/2 the speed of native on realistic benchmarks. However, the overhead of moving between WASM and JS is quite large so in practical use your WASM version might be slower than a pure JS version. WASM vs JS benchmarks I've seen show WASM anywhere from 40x faster than pure JS to 10x slower than pure JS, due to this overhead. If you're doing a large amount of CPU intensive work that can be isolated from the rest of the code that is an ideal scenario for WASM. You have the translation overhead of JS->WASM once, then do the computation, then WASM->JS once to get the result. A small function or code that needs to call back into JS (for DOM access, to query some state in your app, etc) is going to have a lot of those translations so won't see much or any benefit.
- steveklabnik 9y agoYou might enjoy this thread https://www.reddit.com/r/programming/comments/7fm66l/astro_programming_language_a_new_language_under/dqczcm6/ https://www.reddit.com/r/programming/comments/7fm66l/astro_p...
- JepZ 9y agoActually, I don't know why so many people are so excited about webassembly. Yes, it is faster than JS, but JS itself is not that slow and on the other hand we loose the open nature of the human readable web.
- Kwastie 9y agoMinifiers don't output any readable JavaScript anyway. Yes, it can be "decompiled" back to something readable, but so can WASM.
- JepZ 9y agoActually, with minified JS you do not have to "decompile" anything. It is just pressing the pretty print button in your dev-tools and you can use your normal debugger (just without propper names) to step through the code.
- poizan42 9y agoIs it even faster? There is no particular reason why asm.js should be slower besides the initial parsing time.
- flohofwoe 9y agoYou are absolutely right (don't know why you are downvoted). On most browsers, WebAssembly is only a tiny bit faster than asm.js (except Safari on iOS11 where wasm is about 3x faster, but this mainly because their Javascript performance is so bad compared to the other browsers). But that just shows how good asm.js already is. The only major thing that WebAssembly currently has over asm.js is proper support for 64-bit integers. The "initial parsing time" advantage of WebAssembly shouldn't be underestimated though, this is important for bigger code bases, and WebAssembly binaries are also a bit smaller (after compression) than the same code as asm.js.
- JepZ 9y agoYou seem like someone who actually knows something about WASM and is polite enough to articulate an answer. Why do you think that WASM is a good way to go? Why is it better than JS and do you think using it does not endanger the open source nature of the web? So far I only read, it is as accessible as minifed JS, but actually I know how to read a lot of high level languages, but assemblers look to me much less accessible as high level languages (probably the reason why high level languages were invented in the first place). So far I understand that WASM is faster during execution and that parsing times are shorter compared to asm.js (and probably JS too).
- souenzzo 9y agoOnce rust is implemented in rust, I can run rustc in browser and get binaries for windows, for example?
- steveklabnik 9y agoRust is written in Rust, with the exception of LLVM. C++ can be compiled to wasm too though, so that's not the blocker. The bigger issue is that rustc uses features that aren't in wasm yet, like threads and file loading and such. It'll happen eventually, but not just yet...
- 0799243445 9y agoCho kri
- 0799243445 9y agoRust: Khaled web assembly bleue
- stcredzero 9y agoWhat is the Rusty way of handling memory management for a game engine client deployed on WebAssembly? When a program is running a game loop, there are certain entities which will stick around across frames, and there are certain entities which definitely will not. Is there a way to enforce that most of the implementation of the game reside in pure functions, while making memory management nearly bulletproof?
- steveklabnik 9y agoNothing about this is specific to WebAssembly; you’d write the same Rust code as you would for any other target.
- stcredzero 9y agoIn that case, what's the Rusty way to handle a game loop, in which one wants to encourage the use of pure functions? I must confess: I'm thinking of using Rust and a few other languages as a compiler target for a unified Web Client + Server game engine. Is there a particular way in which Rust could support this better than other languages compiling to WebAssembly?
- steveklabnik 9y agoRust is not super worried about purity. That said, Rust is also more pure-ish than not; the large control over mutability and sharing helps. Controlling allocations is also generally easy, as there's no special things that are doing allocation behind your back. Arenas/memory pools are well supported too. > better than other languages compiling to WebAssembly? The best supported languages for this are C, C++, and Rust. So that's really the comparison here, IMO.
- api 9y agoRust glued to React Native or the latter actually ported to Rust sounds like Nirvana.
- fleetfox 9y agoAnd webrender as rendering layer for desktop apps to replace electron
- substack 9y agoAnd there is already a browserify transform to compile inline rust to webassembly for browser code: https://github.com/browserify/rustify https://github.com/browserify/rustify
- alex_duf 9y agoSuch a great news! I'm looking forward DOM integration with wasm, and potentially a way to compile from scala native to wasm.