… especially since pthreads (Mozilla pthreads,Chromium pthreads) andSIMD (simd.js,Chromium SIMD,simd.js in asm.js) are coming toJavaScript.
There are two main benefits WebAssembly provides:
The kind of binary format being considered for WebAssembly can be nativelydecoded much faster than JavaScript can be parsed (experiments show morethan 20× faster). On mobile, large compiled codes can easily take 20–40secondsjust to parse, so native decoding (especially when combined withother techniques likestreaming for better-than-gzip compression) iscritical to providing a good cold-load user experience.
By avoiding the simultaneous asm.js constraints ofAOT-compilabilityand good performance even on engines withoutspecific asm.js optimizations, a new standard makes itmuch easier toadd thefeatures
required to reach nativelevels of performance.
Of course, every new standard introduces new costs (maintenance, attack surface,code size) that must be offset by the benefits. WebAssembly minimizes costs byhaving a design that allows (though not requires) a browser to implementWebAssembly inside itsexisting JavaScript engine (thereby reusing theJavaScript engine’s existing compiler backend, ES6 module loading frontend,security sandboxing mechanisms and other supporting VM components). Thus, incost, WebAssembly should be comparable to a big new JavaScript feature, not afundamental extension to the browser model.
Comparing the two, even for engines which already optimize asm.js, the benefitsoutweigh the costs.
WebAssembly was designed witha variety of use cases in mind.
We think so. There was an earlyprototype with demos [1,2], which showedthat decoding a binary WebAssembly-like format into asm.js can be efficient.And as the WebAssembly design has changed there have beenmoreexperimentswith polyfilling.
Overall, optimism has been increasing for quick adoption of WebAssembly inbrowsers, which is great, but it has decreased the motivation to work on apolyfill.
It is also the case that polyfilling WebAssembly to asm.js is less urgentbecause of the existence of alternatives, for example, a reverse polyfill -compilingasm.js to WebAssembly -exists, and it allows shipping a single build that can run as eitherasm.js or WebAssembly. It is also possible to build a project intotwo parallel asm.js and WebAssembly builds by justflipping a switchin emscripten, which avoids polyfill time on the client entirely. A thirdoption, for non-performant code, is to use a compiled WebAssembly interpretersuch asbinaryen.js.
However, a WebAssembly polyfill is still an interesting idea and should inprinciple be possible.
As explained in thehigh-level goals, to achieve a MinimumViable Product, the initial focus is onC/C++.
However, byintegrating with JavaScript at the ES6 Module interface,web developers don’t need to write C++ to take advantage of libraries that others have written; reusing a modular C++ library can be as simple asusing a module from JavaScript.
Beyond the MVP, anotherhigh-level goalis to improve support for languages other than C/C++. This includesallowing WebAssembly code toallocate and access garbage-collected (JavaScript, DOM, Web API) objects
.Even before GC support is added to WebAssembly, it is possible to compile a language’s VM to WebAssembly (assuming it’s written in portable C/C++) and this has already been demonstrated (1,2,3). However, “compile the VM” strategies increase the size of distributed code, lose browser devtools integration, can have cross-languagecycle-collection problems and miss optimizations that require integration with the browser.
WebAssembly initially focuses onC/C++, and a new, cleanWebAssembly backend is being developed in upstream clang/LLVM, which can then beused by LLVM-based projects likeEmscripten andPNaCl.
As WebAssembly evolves it will support more languages than C/C++, and we hopethat other compilers will support it as well, even for the C/C++ language, forexampleGCC. The WebAssembly working group found it easier to start withLLVM support because they had more experience with that toolchain from theirEmscripten andPNaCl work.
We hope that proprietary compilers also gain WebAssembly support, but we’ll letvendors speak about their own platforms.
TheWebAssembly Community Group would be delighted to collaborate with morecompiler vendors, take their input into consideration in WebAssembly itself, andwork with them on ABI matters.
Yes! WebAssembly defines atext format to be rendered whendevelopers view the source of a WebAssembly module in any developer tool. Also,a specific goal of the text format is to allow developers to write WebAssemblymodules by hand for testing, experimenting, optimizing, learning and teachingpurposes. In fact, by dropping all thecoercions required by asm.js validation,the WebAssembly text format should be much more natural to read and write thanasm.js. Outside the browser, command-line and online tools that convert betweentext and binary will also be made readily available. Lastly, a scalable form ofsource maps is also being considered as part of the WebAssemblytooling story.
Existing Emscripten users will get the option to build their projects toWebAssembly, by flipping a flag. Initially, Emscripten’s asm.js output would beconverted to WebAssembly, but eventually Emscripten would use WebAssemblythroughout the pipeline. This painless transition is enabled by thehigh-level goal that WebAssembly integrate well with theWeb platform (including allowing synchronous calls into and out of JavaScript)which makes WebAssembly compatible with Emscripten’s current asm.js compilationmodel.
No! WebAssembly is designed to be a complement to, not replacement of,JavaScript. While WebAssembly will, over time, allow many languages to becompiled to the Web, JavaScript has an incredible amount of momentum and willremain the single, privileged (as describedabove) dynamic language of theWeb. Furthermore, it is expected that JavaScript and WebAssembly will be usedtogether in a number of configurations:
TheLLVM compiler infrastructure has a lot of attractive qualities: it has an existing intermediate representation (LLVM IR) and binaryencoding format (bitcode). It has code generation backends targeting many architectures and is actively developed and maintained by a large community. Infact PNaCl already uses LLVM as a basis for its binaryformat. However, the goals and requirements that LLVM was designed to meet aresubtly mismatched with those of WebAssembly.
WebAssembly has several requirements and goals for its Instruction SetArchitecture (ISA) and binary encoding:
LLVM IR is meant to make compiler optimizations easy to implement, and torepresent the constructs and semantics required by C, C++, and other languageson a large variety of operating systems and architectures. This means that bydefault the IR is not portable (the same program has different representationsfor different architectures) or stable (it changes over time as optimization andlanguage requirements change). It has representations for a huge variety ofinformation that is useful for implementing mid-level compiler optimizations butis not useful for code generation (but which represents a large surface area forcodegen implementers to deal with). It also has undefined behavior (largelysimilar to that of C and C++) which makes some classes of optimization feasibleor more powerful, but can lead to unpredictable behavior at runtime. LLVM’sbinary format (bitcode) was designed for temporary on-disk serializationof the IR for link-time optimization, and not for stability or compressibility(although it does have some features for both of those).
None of these problems are insurmountable. For example PNaCl defines a smallportablesubsetof the IR with reduced undefined behavior, and a stable version of the bitcodeencoding. It also employs several techniques to improve startupperformance. However, each customization, workaround, and special solution meansless benefit from the common infrastructure. We believe that by taking ourexperience with LLVM and designing an IR and binary encoding for our goals andrequirements, we can do much better than adapting a system designed for otherpurposes.
Note that this discussion applies to use of LLVM IR as a standardizedformat. LLVM’s clang frontend and midlevel optimizers can still be used togenerate WebAssembly code from C and C++, and will use LLVM IR in theirimplementation similarly to how PNaCl and Emscripten do today.
Optimizing compilers commonly have fast-math flags which permit the compiler torelax the rules around floating point in order to optimize moreaggressively. This can include assuming that NaNs or infinities don’t occur,ignoring the difference between negative zero and positive zero, makingalgebraic manipulations which change how rounding is performed or when overflowmight occur, or replacing operators with approximations that are cheaper tocompute.
These optimizations effectively introduce nondeterminism; it isn’t possible todetermine how the code will behave without knowing the specific choices made bythe optimizer. This often isn’t a serious problem in native code scenarios,because all the nondeterminism is resolved by the time native code isproduced. Since most hardware doesn’t have floating point nondeterminism,developers have an opportunity to test the generated code, and then count on itbehaving consistently for all users thereafter.
WebAssembly implementations run on the user side, so there is no opportunity fordevelopers to test the final behavior of the code. Nondeterminism at this levelcould cause distributed WebAssembly programs to behave differently in differentimplementations, or change over time. WebAssembly does havesome nondeterminism in cases where the tradeoffs warrantit, but fast-math flags are not believed to be important enough:
sin,cos,exp,pow, and so on. WebAssembly’s strategy for such functions is to allow themto be implemented as library routines in WebAssembly itself (note that x86’ssin andcos instructions are slow and imprecise and are generally avoidedthese days anyway). Users wishing to use faster and less precise mathfunctions on WebAssembly can simply select a math library implementationwhich does so.add,sub, ormul they don’t have to worry about NaN for example doesn’t makethem any faster, because NaN is handled quickly and transparently in hardwareon all modern platforms.mmap?Themmapsyscall has many useful features. While these are all packed into one overloadedsyscall in POSIX, WebAssembly unpacks this functionality into multipleoperators:
memory.grow operator;0 tomemory.size.A significant feature ofmmap that is missing from the above list is theability to allocate disjoint virtual address ranges. The reasoning for thisomission is:
mmap with what appears to be noncontiguous memoryallocation (but, under the hood is just coordinated use ofmemory_resize andmprotect/map_file/map_shmem/madvise).The benefit of allowing noncontiguous virtual address allocation would be ifit allowed the engine to interleave a WebAssembly module’s linear memory withother memory allocations in the same process (in order to mitigate virtualaddress space fragmentation). There are two problems with this:
size_t?The amount of linear memory needed to hold an abstractsize_t would then alsoneed to be determined by an abstraction, and then partitioning the linear memoryaddress space into segments for different purposes would be more complex. Thesize of each segment would depend on how manysize_t-sized objects are storedin it. This is theoretically doable, but it would add complexity and there wouldbe more work to do at application startup time.
Also, allowing applications to statically know the pointer size can allow themto be optimized more aggressively. Optimizers can better fold and simplifyinteger expressions when they have full knowledge of the bitwidth. And, knowingmemory sizes and layouts for various types allows one to know how many trailingzeros there are in various pointer types.
Also, C and C++ deeply conflict with the concept of an abstractsize_t.Constructs likesizeof are required to be fully evaluated in the front-endof the compiler because they can participate in type checking. And even beforethat, it’s common to have predefined macros which indicate pointer sizes,allowing code to be specialized for pointer sizes at the very earliest stages ofcompilation. Once specializations are made, information is lost, scuttlingattempts to introduce abstractions.
And finally, it’s still possible to add an abstractsize_t in the future ifthe need arises and practicalities permit it.
A great number of applications don’t ever need as much as 4 GiB of memory.Forcing all these applications to use 8 bytes for every pointer they store wouldsignificantly increase the amount of memory they require, and decrease theireffective utilization of important hardware resources such as cache and memorybandwidth.
The motivations and performance effects here should be essentially the same asthose that motivated the development of thex32 ABI for Linux.
Even Knuth found it worthwhile to give us his opinion on this issue at some point,a flame about 64-bit pointers.
Yes but it will depend on theWebAssembly embedder. Inside a browser you’ll get access to the same HTML5 and other browser-specific APIs which are also accessible through regular JavaScript. However, if a wasm VM is provided as an“app execution platform” by a specific vendor, it might provide access toproprietary platform-specific APIs of e.g. Android / iOS.