Hello wasm-pack
hacks.mozilla.org
hacks.mozilla.org
Edit: https://hacks.mozilla.org/2018/04/javascript-to-rust-and-bac...
> "The wasm-bindgen code generation has been designed with the future host bindings proposal in mind from day 1. As soon as that’s a feature available in WebAssembly, we’ll be able to directly invoke imported functions without any of wasm-bindgen‘s JS shims. Furthermore, this will allow JS engines to aggressively optimize WebAssembly manipulating the DOM as invocations are well-typed and no longer need the argument validation checks that calls from JS need. At that point wasm-bindgen will not only make it easy to work with richer types like strings, but it will also provide best-in-class DOM manipulation performance."
V8 generates little wrappers for these, with inline conversions. It does not currently inline the little wrapper functions, nor use ICs for the conversions inside, since branches are generally enough to get the interesting fast cases.
The idea of a super-expensive call is therefore a bit of a myth. You can try to measure the cost yourself, but be careful! Most microbenchmarks will end up comparing the difference between an inlined JS call (as low as zero overhead) versus a non-inlined WASM->JS or JS->WASM call. The proper comparison would be instead with a non-inlined JS->JS call. Defeating inlining for JS->JS calls is tricky. You can do it with cross-realm calls, or by trying manipulating polymorphism. In either case, it's pretty tricky, so good luck.
function thunk(x){ return function() { x() } }
const thunkFoo = thunk(foo)
const thunkBar = thunk(bar)
for(var i = 0; i < 10000; i++) {
thunkFoo()
thunkBar()
}
This is why the "Maybe you don't need Rust to speed up your JS" author was creating functions dynamically using `new Function()`.Maybe you cal get away with
function call(x){ x() }
for(var i = 0; i < 10000; i++) {
call(foo)
call(bar)
}
I didn't test the latter though, whereas the former is empirically slower if you call more than one thunk in your benckmark loop (a single thunk will have the call inlined).https://mrale.ph/blog/2018/02/03/maybe-you-dont-need-rust-to...
PS: link to demo: http://floooh.github.io/oryol/asmjs/DrawCallPerf.html
There is some overhead but it seems acceptable. I get drops when calling a wasm function with a lot parameters (see .set).
[0] https://maierfelix.github.io/glmw/mat4/
Note: This benchmark is far from perfect but hopefully can provide some insights
https://hackernoon.com/im-harvesting-credit-card-numbers-and...
For anything serious, read the source code, at the very least check your dependencies.
To do that well, it would be someone's fulltime job to read and do security audits on all those dependencies.
The idea was though that you'd feed them your package.json and they'd let you know of any vulnerabilities, iirc. Or maybe they had a private repo of packages they'd checked? Can't remember.
If it's trying to be sneaky, you _cannot_ understand it, in general. If you think you can, that is false confidence that is best gotten rid of.
Let's hope exactly the other way around will happen. I would rather like to see better interop between different languages using wasm than wasm + js.
Even the WebAssembly authors seem to agree that it's not foremost a managed language compile target - The Overview text from http://webassembly.org/ says "Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications."
JS is a high level language. I don't see many people compiling to managed languages outside of the browser. Wonder why is that? Few target JVM...but I don't see many(if any) compiling to Java, C#, Ruby or Lua or PHP. I've never seen anyone compiling JavaScript either unless they had to run it in a browser. This should tell you how good JS is when it has to compete on merit as compiler target.
>> Also, "transpile" is just another word for "compile"
Well, I prefer to use the "transpile" term when the target is a high level language.
JavaScript is a high level language. It seems some smart folks decided that a new "language/IR" is needed (wasm) so that people can use other languages on the web. Now let's make this new IR a first class citizen on the web.
WebAssembly is a refinement of asm.js, which started as a mechnism to enable C/C++ code to run in browsers. Other, managed languages aren't forced to go the asm.js route because their semantics aren't tightly married to a byte addressable, untyped program heap.
- code size - a runtime for a managed language is much bigger if you have to reimplement & ship the primitives you get from the JS platform.
- implementation complexity: a LLVM-webassembly-toolchain along with your own GC is much harder and more work than a JS backend, and would need to have a rather good payoff to be worth investing in.
- poor cross-browser development tooling support to have a good debugging experience
- GC implementation complexity and performance - firstly, there is no GC support currently and no timeline about when/if something materalizes. The current "future GC" support in webassembly[1] doesn't provide a GC implemnetation, just hooks to peacefully coexist with JS GC.
- JS interop
- browser support
Now, it may be that some of these get solved eventually - but they would all have to be solved, with high quality solutions, to beat JS as a managed language compile target.
[1] https://github.com/WebAssembly/reference-types/blob/master/p...
I strongly disagree. Wonder why no language(managed or unmanaged languages) designer uses this gem named JavaScript as compile target?(web stuff excluded)
It seems your whole argument revolves around the fact that JS has better support than WASM in browser. We already know this. WASM is a work in progress. It's not ready yet for prime time. This year we will get some managed languages compiled to WASM. Next year we might get GC. I believe in some distant future javascript will be compiled to wasm either by the client or by the browser itself(for backward compatibility). JavaScript is JIT-ed in the browser anyway.
Really? Can you please point me to some documentation about this? I can't mange to find out how to use a wasm compiled library (compiled from C) in C#/mono project (which also compiles to wasm )
The WASM will replace JavaScript argument exists not for any valid technology reasoning, because people desperately need it to (only for personal reasons) and don't understand how web technologies work on the front end.
The goal of WASM was never to replace JavaScript, but to replace Flash (before Adobe announced the death of Flash) in a language agnostic way.
At this time, and for the foreseeable future, there are no plans with active code in development to implement WASM as a JavaScript replacement, at least to my knowledge.
> Issues have been opened for native DOM bindings in WASM, but I am not sure if that work ever started.
I didn't say work had started on it. I just said that it is planned. See here for proof: http://webassembly.org/docs/high-level-goals/
> access browser functionality through the same Web APIs that are accessible to JavaScript
By passing data.
So what would a DOM API exposed to WASM look like? COM is the only example that comes to mind.
These two things aren't contradictory. wasm is typed.
What did you won with Flash being replaced?
If there are no competitors, JavaScript wins by default, just like C ffi did on server and desktop.
That said, none of this means “replacing” JavaScript, no matter what the parent says. It’s a non-goal.
I believe a better term would be "skipping" javascript than "replacing" javascript. There won't be many rewrites but I'm sure that many people would skip JS on new projects if they would have that option. Why would a Python, Go, Ruby developer choose JavaScript over Python given that their language of choice would compile to WASM(along with DOM/webAPI access)? The ecosystem may be a reason but that's only a matter of time(i.e. 1 -2 years).
Another good reason is that, regardless of what you read on Reddit and Hacker News, a lot of people actually really like JavaScript.
Yeah, that's true now though I don't think there is something that stops browsers to host a runtime(i.e. a pre-loaded std wasm library + wasm-gc) to help the languages compiled to wasm to reduce their compilation size. The question is really whether the browsers want to make WASM a first class citizen or not.
>> Another good reason is that, regardless of what you read on Reddit and Hacker News, a lot of people actually really like JavaScript.
I believe WASM could serve the other lot of people who are not that much into JavaScript. Using the same language on server and browser also reduces friction(i.e. see NodeJS). Personally I believe JS has a such rank based on reach not on merit.
> reach not on merit
Node’s popularity and success is counter to this notion, IMHO. Seriously, lots of people love JavaScript.
Regarding node it has two things going for it, the frontend devs that only know JavaScript and try to do server side as well.
The fact that thanks to its world class JITs (V8 and ChakraCore) it easily beats Python and Ruby interpreters in performance, which are the most common deployed variant.
Also the revival of Java, .NET, Flash, ActiveX is already brewing, this is not only about Python and Ruby.
Just doing games in Unity, compile to WASM and deploy, just like plain old Flash.
And while at it, use the 2D GUI to build a complete web site, just like plain old Flash.
The difference is now we can all be happy, because it is a Web standard.
And yet somehow thanks to NodeJS, javascript development seems to have gotten exponentially more complex.
Yes, and garbage collection that crosses language boundaries.
Is this even a possibility?
[1] https://github.com/WebAssembly/host-bindings/blob/master/pro...
All of this tooling has been written to be forward-compatible with it, so whenever that lands, you can upgrade the tool and get a speed boost for free.
truly the complete dead end of it.
Unless maybe I'm missing something. Is a disassembler for WASM a thing yet?
Yes, it's part of the standard toolkit. See https://github.com/WebAssembly/wabt and specifically the "wasm2wat" tool.
If that kills it, it was already dead. Obfuscation and minification is already as bad as bytecode. Honestly, wasm might be a little better because there are less insane hacks and more simple, if low level, code.
Also, if people are willing to implement DRM in it just because it's bytecode, I'd rather they did that than implemented rootkits in all of the browsers. Thanks for that one W3C.
No more than it was when Flash was a thing, or Java applets, or Silverlight. The world has been presented with numerous opportunities to turn the web into nothing but binaries, it hasn't happened.
>Unless maybe I'm missing something.
You're missing the part where someone would have to put a gun to everyone's head and force them to rewrite the entire web as WASM blobs, then force all of the browsers to be redesigned, and the servers, so that HTML and plaintext are deprecated, for your doomsday scenario to be even remotely plausible.
Adding it to WASM will not be the amazing experience many think it will be.
The overhead problem you mention reminds me a little of the false intuition that people have about databases.
I've worked on a couple projects where people were surprised that as the data set grew (either more customers, or accumulated customer activity), operations like INSERT and UPDATE got slower and slower, even without new functionality getting in the way. Everyone expects SELECT to get slower, but INSERTs seem to catch them off guard.
Every INSERT or UPDATE has to update the indexes. And when you quadruple the data, the update time for each index doubles. At first the cost of the insert is in the noise floor. It's swamped by the communication and transaction overhead. But after a handful of doublings it becomes detectable. A few more and it becomes noticeable. After a few more it becomes a problem, and if you haven't already changed your product roadmap, you do now.
To make a web page fast, you have to correlate the DOM with the CSS and the viewport. Adding more data isn't free.
I don’t know if I agree it’ll be less interesting- but it will have narrower applications. They’ll be more self contained - data and processing related - rather than driving the UI... but I don’t know if I’d call that not interesting.
I mean... imagine a WASM game engine where the modules/plugins can be any language as long as the compile target is WASM and they follow the right API... with JS/DOM just doing the DOM part (canvas or webgl I guess).
Sounds pretty powerful and fun.
One interesting thing about wasm is the difference between libraries and apps; Rust’s small binary size here can make it useful for this infrastructure work, but for languages that need to bring along the runtime, it’s much more complex. This is one reason why we’re pursuing stuff like wasm-pack.
I’m glad to see more and more languages compiling to wasm though! Exciting times.
Now that they're using the Mono runtime it's significantly larger and it seems their main task now is finding ways to remove unused code from that runtime to get it back to reasonable.
What? What kind of bubble are you working in?
In which planet? Not only will most frameworks and standard JS libs dwarf this, but the average web page size has upped to ~ 3MB these days...
The original runtime that was used by Blazor was already a compact .NET runtime, and no matter how much you minify it (or any other runtime, such as the JVM), it will always have a considerable size.
>the average web page size has upped to ~ 3MB these days...
This is not an excuse to make web pages' sizes even larger :).
Btw, I'm not against the idea of using a managed language that targets WebAssembly for front-end development. On the contrary, I'm very excited about Blazor and I'm following its development, and I would love to see similar frameworks for other languages such as Kotlin or Swift.
But while I think the size of a runtime won't be an issue for web applications that use such frameworks, I don't like the idea of shipping large runtimes with wasm packages that might be used with other languages.
Look at something like jQuery. Let's assume for the sake of discussion there are 50 versions of jQuery (that's a low estimate), and 6 majorly used CDNs. That's 300 distinct cachable items. Now add in that most people now use multiple devices, and that caches are generally completely full and evicting things constantly. The chances of having a specific version from a specific CDN on the specific device is actually pretty low.
Now multiply that whole thing by another 100 libraries that all want to be the next jQuery. It's just not going to happen.
And cross-domain or content based caching isn't a solution either as it's opens an extremely large security hole (basically being able to probe your cache checking if a specific hash or content exists in it).
I'd much rather spend our collective time improving dead code removal tools and optimizing tightly linked bundles of libraries to give each web application it's own customized, small, optimized, and easily cachable "bundle". It avoids the reliance on 3rd party CDNs, it gives control over caching behavior back to the original website, it improves security, and can be faster (both in download speed and runtime speed).
I asked this same question[0]. Appears mono.js is 166kb in release mode, but it downloads/uses the DLLs directly as a system would, so those sizes are the same as they are for desktop apps (not sure off the top of my head what that is for ASP.Net stuff or the stdlib).
(You can see those here: https://www.npmjs.com/search?q=hello-wasm)
1: https://github.com/mozilla/source-map#sourcemapconsumerproto...
[1] https://github.com/tc39/proposal-weakrefs [2] https://github.com/WebAssembly/meetings/blob/master/2018/pre... [3] https://github.com/tschneidereit/typed-objects-explainer
It seems like cargo-web has lots of this ground covered already. I'm wondering why build these other tools in that case? I don't have a dog in this fight, I'm just working on a wasm-based app that I'm hoping will serve me for quite some time, and seeing what appears to be duplicated effort at such an early stage worries me a bit.
Either way, thanks for building this!
If so, then that’s correct, as rustc can’t compile C code. You need a C -> wasm compiler, and that’s emscripten.
Hopefully we’ll have built the ecosystem enough that you won’t need to rely on those libraries :)
Also, doesn't clang also have a wasm backend now? Emscripten isn't the only option.
Clang does have a wasm backend, same as the unknown target. It suffers the same problems; that is, one of the things that emscripten does is provide a runtime/support code that does things like "automatically translate opengl to webgl". That is, one of emscripten's major goals is "get code that was never assumed to be able to run on the web to run on the web with as little hassle as possible." Outside of the web, those C libraries were very much intended to work on the native platform. So there's extra complexity there.
We continue to support emscripten for when you need this use-case, but it effectively only works if you're building an application, not a library, and we want to support people writing libraries.
At that point why not just use the JVM stripped of the useless stuff as a base and add the remaining small pieces that might be needed. Or Graal.
I guess I don't understand what Wasm is doing that is so much different that couldn't be handled with other more advanced code bases.
Yup
> why not just use the JVM stripped of the useless stuff as a base
This often comes up in WASM discussions. First of all, you cannot divorce a JVM from its useless stuff. Many parts of the stdlib might as well be part of the bytecode (e.g. strings which then carries a done of charset code, classloaders, boxed primitives, method handles, lambda factories, etc). I would love to see an effort to leverage JVMs bytecode without all of it's baggage, but for now the marriage is so tight they are inseparable.
> Or Graal
That's a runtime VM/compiler, not a bytecode spec to target.
> I guess I don't understand what Wasm is doing that is so much different that couldn't be handled with other more advanced code bases.
Keep it simple, (mostly) no undefined behavior, no required GC, works the same on all platforms, large test suite, multiple big-company backers, etc. I can't think of an "assembly set" (or bytecode) that does all of that.
Webassembly was designed not to do this, and I really hope it stays that way forever. Optimizing JITs are useful for highly dynamic languages like Javascript; Webassembly's fast startup times and predictable performance are a much better solution for languages like Rust.
> I guess I don't understand what Wasm is doing that is so much different that couldn't be handled with other more advanced code bases.
On top of "the vast majority of the optimization is done ahead of time so there's no need for a JIT," there's also the memory model. Webassembly exposes memory as a big array of bytes for you to manage yourself, just like hardware. The JVM enforces a particular object model with classes, inheritance, and garbage collection.
So I guess what I'm saying is that "the JVM stripped of all the useless stuff" is what Webassembly is already. And some of the stuff that got stripped is the JIT and object model.
WebAssembly is a VM bytecode for a stack-based VM. Unless you want things to run very, very slowly you still need a JIT to emit native code, rather than loop dispatching each WebAssembly instruction in a bytecode interpreter.
WebKit, for example, has a two-tier JIT for WebAssembly just like JS, but WebAssembly has already had all the high level language related optimizations performed and looks a bit like an intermediate representation anyway so the first pass is very fast.
I think the VM is going to need to be just like every other VM (once inlining is introduced, why even bother with trying to optimize wasm before the JIT).
If wasm is going to be so good, then you could retart java to it? I know a lot of high performance java shops that would love to get rid of the GC in Java. But Hotspot can be an optimizing beast.
What WebKit is doing is moving in that direction (unfortunately) but it still looks much more like an "-O0 -> -O3" sort of thing than what Javascript gets.
> The next large piece of development work on wasm-pack will focus on using custom segments in compiled WebAssembly to declare dependencies on local Javascript files or other npm packages.
> The preliminary work for this feature has already landed in wasm-bindgen, so the next step will be integrating it into wasm-pack.
NO, Replace Javascript, replace HTML, replace CSS.