Update: Here's a quote from the Microsoft announcement:
"Despite being an early implementation, the demo starts-up significantly faster than just using asm.js as the WebAssembly binaries have a smaller file size and parse more quickly than plain JavaScript that needs to be parsed in the asm.js case."
https://blogs.windows.com/msedgedev/2016/03/15/previewing-we...
A javascript application compiled to wasm doesn't really make sense. Javascript isn't a compiled language. The best you could do would be to store some kind of compressed representation of the source code, along with a JIT compiler to run that source code. It isn't a sensible thing to do.
These are totally sensible. Look at: http://www.call-cc.org/
...which will also make it feasible to use other gc:ed languages without shipping an enormous runtime.
I'm not sure how much space just cutting out the GC will save?
I mean, it is if you compile it to wasm. It is definitely JIT compiled.
No one wants to do web development in C++ honestly, but they would like the performance.
With IE9 support slipping, it seems to be a no-brainer in terms of support at this point too [1].
I'm also thinking this could be a huge win once it hits node.js (v6?), as this could be a great answer to better binary module support. As binary modules are a bit of a pain to support, and prebuilt binary modules are in a hodge-podge state.
As I understand it, it's little more than a binary serialization of JavaScript ASTs. In which case, no, you don't need to ship your own GC with it.
I mean, you could always write a JavaScript interpreter in JavaScript, and then compile that into WASM, in which case, yes, you'd ship your own GC. I don't see why you would feel the need to do that for real world applications, though.
I don't, WebAssembly is about C++, primarily. Every design decision has been to support C++. Everything else is an afterthought that will come later. WebAssembly isn't about minifying your JS.
Read this: https://github.com/WebAssembly/design/blob/master/GC.md GC, DOM access, etc. don't exist in WebAssembly code, yet.
https://github.com/WebAssembly/design/blob/master/FAQ.md#whi...
What I'd love to be able to do with tools like Unity3D that compile C# and other CLR languages into asm.js, would be to pass JavaScript objects directly in and out of the C# code so you can manipulate the underlying JavaScript objects directly from C# with little or no overhead.
Right now of course you can implement JSON libraries in C#, but it's indirectly and inefficiently layered on top of the flat memory model of asm.js. I want to be able to use the native JavaScript objects and libraries directly from other languages like C# that compile into JavaScript. That would be ideal!
To do that, asm.js would need a way to store references to garbage collected JS objects somewhere, somehow, using proxies or handles represented in linear memory, opaque reference types [2], or some other magic like that, like Apple's JavaScript/Objective C bridging stuff [3].
[1] http://bytecrafter.blogspot.nl/2015/06/a-quick-overview-of-w...
[2] https://github.com/WebAssembly/design/blob/master/GC.md
[3] https://developer.apple.com/library/mac/documentation/Cocoa/...
This compiled/interpreted distinction has gotten quite fuzzy, and it has been for decades now. Smalltalk was always a compiled language with really late binding. It did compile to a bytecode which was interpreted at first, but that became JIT compiled in all but one commercial VM. This all happened over a decade ago.
Also, there is clearly a subset of Javascript programs that could be usefully compiled down to a small, fast, compact machine language program.
I suppose the extra restrictions of Typescript would help. At least if you add extra restrictions to make it easier to compile.
Compiling JavaScript text source code into a binary representation of its AST will save time and space downloading, and time starting up.
You won't need another JIT compiler, the web browser usually already has one. WebAssembly is bytecode and JIT agnostic. Compiling text JavaScript into a binary WebAssembly representation of the parse tree is different than compiling the parse tree to bytecode, or JITting the parse tree or bytecode to machine code. They are complementary layers, and both synergistically useful together.
[1] http://bytecrafter.blogspot.nl/2015/06/a-quick-overview-of-w...
Similar to asking why would you want to run JavaScript on the server?
There's something to be said for having your code in a single language. People can move to different parts of the project more easily and if you need to run the code in multiple places then you can do so with (mostly) a single codebase.
The real question is why WOULDN'T you compile all your JavaScript to wasm assuming the build process is easy enough. For complex site that already have a build pipeline I don't see any reason to publish minified JavaScript instead of just building it all into wasm for performance reasons (assuming mature debugging tools of course). The only question I'd have is whether you get that much gain by going from JavaScript to wasm or if the browser's JIT compiler can do a good enough job.
All of the "just-in-time" optimizations can be done ahead of time. Which saves [that much run time x that many users] in computer time.
Type tracing in particular is the big win, and with a dynamic languages you simply can't prove enough to do it ahead of time. There's also startup time that you're paying with AOT and avoiding with JIT.
The post I originally replied to brought this up in the context of TypeScript with the aside that TypeScript is basically JavaScript. Do you think that using TypeScript's static typing and compiling to wasm could/would be faster than JIT-compiled JavaScript?
Just like Flash or the JS game platforms that are stupid hacks on top of the canvas element, if people have to implement text rendering without the DOM, it'll encourage putting poorly-rendered text in unusable layouts with squirrely scrollbars. We can do better.
I'm not sure why, if you like JS, people can keep on using JS indefinitely. My theory on programming is to use the language that I prefer, and worry about everything else secondary. For me that's Python. I've mostly avoided any deep dives on learning JS so it'll be nice to be a part of a budding Python web frontend community when the time comes.
And the memory management is uses should make compilation to WebAssembly rather straightforward. (... I believe – I have little knowledge of that sphere and welcome any corrections).
Speed. Oh and memory - if I could optimize it so that all our vectors, matrices and logic code did only stack allocations I would be a happy camper.
Why don't you compile into native platforms?
Looking at dependencies for certain key Javascript libraries makes me skeptical now that this is possible.
AOT compiling highly dynamic languages gives you very little room for optimizations.
Branch prediction on a CPU can be quite helpful, but if a program stops hitting the same branches it can impact performance. The point of a just in time compiler is that it compiles on the fly, which does take a certain amount of time. That could be loading time for your application.
In any case, the purpose of this development would be to design something that is faster than V8. And I'm specifically speaking of compiling with inferred types or from asm.js or TypeScript, not embedding a VM or a garbage collector or an emulator.
This compiler might only accept programs that would be faster.
I don't really see how a js -> wasm compiler fundamentally changes things. You're still working in JS which has poor memory placement semantics.
Compilers don't know how to layout your data. They don't know how you'll access it or the traversal patterns. Your whiz-bang compiler isn't going to strip out class members and AoS from SoA because that's a fundamental data structure problem.
Compilers are great, they fold things down, inline and unroll loops. When it comes to memory placement they can't know your intent and it's up to you to lay out your data appropriately. They might do padding but anything else is going to have memory & complexity implications and they shouldn't make those decisions for you.
This is really an issue of backend optimization to "make things like asm.js."
For example, there are obvious examples of cases where a JavaScript object's properties and property types would be transparent to a compiler at compile time, with a complete graph of where those values would be stored and used. This would be stored in the WebAssembly stack, analogous to an asm.js fixed array.
The WebAssembly sandbox is designed to run code directly. The JIT is designed to build code to run directly in an iterative fashion. If system designers knows how software is expected to operate, they can make choices to instrument that process and also make software which is designed intelligently.
Java runs in a VM. Someone could write a just in time compiler for .java code that performs well. That's not a sufficient argument not to develop or continue to develop a javac compiler for byte code. Additionally, whether or not a language is designed to use GC doesn't mean there couldn't be research or design into avoiding or augmenting that situation for performance (in the way that a just-in-time compiler would relieve the situation). Nor reason not to build a platform and engineering methodology to deploy to two independent and cooperating runtime environments.
Neither Asm.js and emscripten or C are the end of all things. Neither is dynamicism.
The problem is that you can't fully trust your type inference. JIT compilers can get away with this because they can escape to the interpreter if a type check fails. With an AOT compiler you can optimize for your inferred type but you still always have to include complete code for the slow path too. At that point 80%+ of your instruction cache is gonna be probably-unused code. You can never eliminate as many type checks as a tracing or block versioning JIT.
TypeScript doesn't help either:
function foo(a: int, b: int) { return a + b; }
window['fo' + String.fromCharCode(111)]('nice ', 'try);
Whoops. TypeScript is (intentionally) unsound, which doesn't help your compilation much.If AOT compilation were a way to get JavaScript faster than V8, V8 would compile ahead-of-time (well, it would probably compile in the background and use an interpreter on first load, but you get the idea).
asm.js is a different since it is strongly typed and explicitly controls memory layout. It's not JavaScript from the perspective of implementation.
Then I will have faster (and smaller) code on platforms that support WebAssembly and regular JavaScript on platforms that don't.
What a wonderful way to deploy JavaScript to WebAssembly for enlightened developers, which doesn't involve a "compiler."
Obviously, we are thinking of different scenarios. My subset of JavaScript may be different than yours, which might be different than asm.js. Asm.js would be great except it isn't idiomatic and having a fixed heap isn't always great. That doesn't mean there aren't middle grounds which are as of yet unexplored. This is sort of a limited area, which is probably why no one's started a project on this yet.
By the window['foo'] argument, minifiers are unnecessary because then you can't use eval().
Well, the problem there is that your subset would be... C. JavaScript without automatic memory management, closures, prototype inheritance[1], and dynamic types isn't really JS anymore.
> By the window['foo'] argument, minifiers are unnecessary because then you can't use eval().
Most minifiers don't touch object properties or global variables for this reason. Closure compiler is the only one that does and it's quite strict (and doesn't work on a lot of JS code because of it).
1. Assuming objects are hash tables in your implementation, you might be able to do inheritance by reference counting a list of parent hash tables but that could get messy.
Also, Uglify 2 modifies global properties if you tell it to, and neither uglify nor closure compiler do well with object properties, which can be renamed.
All of these arguments assume that a developer is unaware or not understanding of the mechanisms that their code uses. It seems no one is interested in using anything other than emscripten/LLVM.
1. https://developers.google.com/v8/experiments#strong-mode
2. https://groups.google.com/forum/#!msg/strengthen-js/ojj3TDxb...
No that's not how it works. The problem with most JIT'd languages is that every variable or field is a pointer, every function call is a virtual call and there are no type signatures to help a compiler. These are the main reasons. If you added structs, nonvirtual functions and type hints you will quickly enter C performance territory (this is basically what asm.js does).
JIT compilers heavily use profiler guided optimizations to avoid the overheads associated with dynamic languages. They can often inline polymorphic function calls because usually 98% the variable points to an instance of type X and the remaining 2% to type Y. Falling back to a normal polymorphic call if the type is not Y. This is something an AOT compiler cannot do.
Yes, it can. You know the part where the JIT decides whether to execute X or Y? That can easily be implemented in a conditional in compiled code with the two code paths, X and Y.
But I'm more interested in the C performance territory. I'm not even interested in cross-compiling code where globals are used or variables change types.
It's possible to strip the functions and properties off of a JavaScript prototype and if it's well behaved, which user code is more likely to be than JavaScript libraries, it can be compiled fairly well.
And that's the difference with a JIT compiler: if the value is almost certainly X, then it just emits the code for X and a stub for Y. The stub just bails back into the interpreter. The check is a couple machine instructions and the fast path can be pipelined (since branch prediction is unlikely to fail).
An AOT compiler has to include the full code for both X and Y, no matter how unlikely Y is. AOT compiling dynamically typed languages gets you easily 80%-90% unused code.
The only difference in this hypothetical is that the slower path would run faster.
Also JITs can remove many more type checks, because it knows when a check would be redundant. See e.g. Lazy Basic Block Versioning[1], but existing tracing JITs do quite well also.