WebAssembly

From Wikipedia, the free encyclopedia

WebAssembly
WebAssembly Logo.svg
Paradigmstructured stack machine[1]
Designed byW3C
Developer
First appearedMarch 2017; 4 years ago (2017-03)
OSPlatform independent
LicenseApache License 2.0
Filename extensions
  • .wat (text format)
  • .wasm (binary format)
Websitewebassembly.org
Influenced by

WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs, and a corresponding textual assembly language, as well as interfaces for facilitating interactions between such programs and their host environment.[2][3][4][5] The main goal of WebAssembly is to enable high-performance applications on web pages, but the format is designed to be executed and integrated in other environments as well, including standalone ones.[6][7][8]

WebAssembly (i.e. WebAssembly Core Specification (then version 1.0, 1.1 is in draft[9]) and WebAssembly JavaScript Interface[10]) became a World Wide Web Consortium recommendation on 5 December 2019,[11] alongside HTML, CSS, and JavaScript.[12]

WebAssembly can support (at least in theory) any language (e.g. compiled or interpreted) on any operating system (with help of appropriate tools),[13] and in practice all of the most popular languages already have at least some level of support.

The Emscripten SDK can compile any LLVM-supported languages (such as C, C++ or Rust, among others) source code into a binary file which runs in the same sandbox as JavaScript code.[note 1] Emscripten provides bindings for several commonly used environment interfaces like WebGL. There is no direct Document Object Model (DOM) access; however, it is possible to create proxy functions for this, for example through stdweb,[18] web_sys,[19] and js_sys[20] when using the Rust language.

WebAssembly implementations usually use either ahead-of-time (AOT) or just-in-time (JIT) compilation, but may also use an interpreter. While the first implementations have landed in web browsers, there are also non-browser implementations for general-purpose use, including Wasmer,[13] Wasmtime[21] or WAMR,[22] wasm3, WAVM, and many others. The WebAssembly website has a page comparing popular engines and their implemented features.

The World Wide Web Consortium (W3C) maintains the standard with contributions from Mozilla, Microsoft, Google, Apple, Fastly, Intel, and Red Hat.[23][22]

History[]

WebAssembly was first announced in 2015,[24] and the first demonstration was executing Unity's Angry Bots in Firefox,[25] Google Chrome,[26] and Microsoft Edge.[27] The precursor technologies were asm.js from Mozilla and Google Native Client,[28][29] and the initial implementation was based on the feature set of asm.js.[30] The asm.js technology already provides near-native code execution speeds[31] and can be considered a viable alternative for browsers that don't support WebAssembly or have it disabled for security reasons.

In March 2017, the design of the minimum viable product (MVP) was declared to be finished and the preview phase ended.[32] In late September 2017, Safari 11 was released with support. In February 2018, the WebAssembly Working Group published three public working drafts for the Core Specification, JavaScript Interface, and Web API.[33][34][35][36]

Implementations[]

While WebAssembly was initially designed to enable near-native code execution speed in the web browser, it has been considered valuable outside of such, in more generalized contexts.[37][38] Since WebAssembly's runtime environments (RE) are low level virtual stack machines (akin to JVM or Flash VM) that can be embedded into host applications, some of them have found a way to standalone runtime environments like Wasmtime and Wasmer.[8][13]

Web browsers[]

In November 2017, Mozilla declared support "in all major browsers",[39] after WebAssembly was enabled by default in Edge 16.[40] The support includes mobile web browsers for iOS and Android. As of July 2021, 94% of installed browsers support WebAssembly.[41] But for older browsers, Wasm can be compiled into asm.js by a JavaScript polyfill.[42]

Compilers[]

Because WebAssembly executables are precompiled, it is possible to use a variety of programming languages to make them.[43] This is achieved either through direct compilation to Wasm, or through implementation of the corresponding virtual machines in Wasm. There have been around 40 programming languages reported to support Wasm as a compilation target.[44]

Emscripten compiles C and C++ to Wasm[32] using the Binaryen and LLVM as backend.[45]

As of version 8, a standalone Clang can compile C and C++ to Wasm.[46]

Its initial aim is to support compilation from C and C++,[47] though support for other source languages such as Rust, .NET languages[48][49][44] and AssemblyScript[50] (TypeScript-like) is also emerging. After the MVP release, there are plans to support multithreading and garbage collection[51][52] which would make WebAssembly a compilation target for garbage-collected programming languages like C# (supported via Blazor), F# (supported via Bolero[53] with help of Blazor), Python, and even JavaScript where the browser's just-in-time compilation speed is considered too slow. A number of other languages have some support including Python,[54] Java,[55] Julia,[56][57][58] Zig,[59] and Ruby,[60] as well as Go.[61]

Limitations[]

  1. In general, WebAssembly does not allow direct interaction with the DOM. All interaction must flow through JavaScript interop.
  2. Multithreading (although there are plans to address this.)
  3. Garbage collection (although there are plans to address this.)
  4. Security considerations (discussed below)

WebAssembly is supported on desktops, and mobile, but on the latter, in practice (for non-small memory allocations, such as with Unity game engine) there are "grave limitations that make many applications infeasible to be reliably deployed on mobile browsers [..] Currently allocating more than ~300MB of memory is not reliable on Chrome on Android without resorting to Chrome-specific workarounds, nor in Safari on iOS."[62]

All major web browsers allow WebAssembly if Content-Security-Policy is not specified, or if "unsafe-eval" is used, but otherwise the major web browsers behave differently.[63] In practice WebAssembly can't be used on Chrome without "unsafe-eval",[64][65] while a worker thread workaround is available.[66]

Security considerations[]

In June 2018, a security researcher presented the possibility of using WebAssembly to circumvent browser mitigations for Spectre and Meltdown security vulnerabilities once support for threads with shared memory is added. Due to this concern, WebAssembly developers put the feature on hold.[67][68][69] However, in order to explore these future language extensions, Google Chrome added experimental support for the WebAssembly thread proposal in October 2018.[70]

WebAssembly has been criticized for allowing greater ease of hiding the evidence for malware writers, scammers and phishing attackers; WebAssembly is present on the user's machine only in its compiled form, which "[makes malware] detection difficult".[71] The speed and concealability of WebAssembly have led to its use in hidden crypto mining on the website visitor's device.[71][72][67] Coinhive, a now defunct service facilitating cryptocurrency mining in website visitors' browsers, claims their "miner uses WebAssembly and runs with about 65% of the performance of a native Miner."[67] A June 2019 study from the Technische Universität Braunschweig analyzed the usage of WebAssembly in the Alexa top 1 million websites and found the prevalent use was for malicious crypto mining, and that malware accounted for more than half of the WebAssembly-using websites studied.[73][74] An April 2021 study from Universität Stuttgart found that since then crypto mining has been marginalized, falling to below 1% of all WebAssembly modules gathered from a wide range of sources, also including the Alexa top 1 million websites.[75]

The ability to effectively obfuscate large amounts of code can also be used to disable ad blocking and privacy tools that prevent web tracking like Privacy Badger.

As WebAssembly supports only structured control flow, it is amenable toward security verification techniques including symbolic execution. Current efforts in this direction include the Manticore symbolic execution engine.[76]

WASI[]

WebAssembly System Interface (WASI) is a simple interface (ABI and API) designed by Mozilla intended to be portable to any platform.[77] It provides POSIX-like features like file I/O constrained by capability-based security.[78][79] There are also a few other proposed ABI/APIs.[80][81]

WASI is influenced by CloudABI and Capsicum.

Solomon Hykes, a co-founder of Docker, wrote in 2019, "If WASM+WASI existed in 2008, we wouldn't have needed to create Docker. That's how important it is. WebAssembly on the server is the future of computing."[82] Wasmer, out in version 1.0, provides "software containerization, we create universal binaries that work anywhere without modification, including operating systems like Linux, macOS, Windows, and web browsers. Wasm automatically sandboxes applications by default for secure execution".[82]

Specification[]

Host environment[]

The general standard provides core specifications for JavaScript API and details on embedding.[4]

Virtual machine[]

Wasm code (binary code, i.e. bytecode) is intended to be run on a portable virtual stack machine (VM).[83] The VM is designed to be faster to parse and execute than JavaScript and to have a compact code representation.[47] An external functionality (like syscalls) that may be expected by Wasm binary code is not stipulated by the standard. It rather provides a way to deliver interfacing via modules by the host environment that the VM implementation runs in.[84][8]

Wasm program[]

A Wasm program is designed to be a separate module containing collections of various Wasm-defined values and program type definitions. These are expressed in either binary or textual format (see below) that both have a common structure.[85]

Instruction set[]

The core standard for the binary format of a Wasm program defines an instruction set architecture (ISA) consisting of specific binary encodings of types of operations which are executed by the VM (without specifying how exactly they must be executed).[86] The list of instructions includes standard memory load/store instructions, numeric, parametric, control of flow instruction types and Wasm-specific variable instructions.[87]

The number of opcodes used in the original standard (MVP) was a bit fewer than 200 of the 256 possible opcodes. Subsequent versions of WebAssembly pushed the number of opcodes a bit over 200. The WebAssembly SIMD proposal (for parallel processing) introduces an alternate opcode prefix (0xfd) for 128-bit SIMD. The concatenation of the SIMD prefix, plus an opcode that is valid after the SIMD prefix, forms a SIMD opcode. The SIMD opcodes bring an additional 236 instructions for the "minimum viable product" (MVP) SIMD capability (for a total of around 436 instructions).[88][89] Those instructions, the "finalized opcodes"[90] are implemented in Google's V8 (in Google Chrome) and in the corresponding engine in Mozilla Firefox (but not enabled in stable versions of the web browsers),[91] and there are also some additional proposal for instructions for later "post SIMD MVP", and there's also a separate "relaxed-simd" proposal on the table.[92]

These SIMD opcodes are also portable and translate to native instruction sets like x64 and ARM. In contrast, neither Java's JVM (nor CIL) support SIMD, at their opcode level, i.e. in the standard; both do have some parallel APIs which provide SIMD speedup. There is an extension for Java adding intrinsics for x64 SIMD,[93] that isn't portable, i.e. not usable on ARM or smartphones. Smartphones can support SIMD by calling assembly code with SIMD, and C# has similar support.

Code representation[]

In March 2017, the WebAssembly Community Group reached consensus on the initial (MVP) binary format, JavaScript API, and reference interpreter.[94] It defines a WebAssembly binary format (.wasm), which is not designed to be used by humans, as well as a human-readable WebAssembly text format (.wat) that resembles a cross between S-expressions and traditional assembly languages.

The table below shows an example of a factorial function written in C and its corresponding WebAssembly code after compilation, shown both in .wat text format (a human-readable textual representation of WebAssembly) and in .wasm binary format (the raw bytecode, expressed below in hexadecimal), that is executed by a Web browser or run-time environment that supports WebAssembly.

C source code and corresponding WebAssembly
C source code WebAssembly .wat text format WebAssembly .wasm binary format
int factorial(int n) {
  if (n == 0)
    return 1;
  else
    return n * factorial(n-1);
}
(func (param i64) (result i64)
  local.get 0
  i64.eqz
  if (result i64)
      i64.const 1
  else
      local.get 0
      local.get 0
      i64.const 1
      i64.sub
      call 0
      i64.mul
  end)
00 61 73 6D 01 00 00 00
01 00 01 60 01 73 01 73 06
03 00 01 00 02
0A 00 01
00 00
20 00
50
04 7E
42 01
05
20 00
20 00
42 01
7D
10 00
7E
0B
0B 15 17

All integer constants are encoded using a space-efficient, variable-length LEB128 encoding.[95]

The WebAssembly text format is more canonically written in a folded format using S-expressions. For instructions and expressions, this format is purely syntactic sugar and has no behavioral differences with the linear format.[96] Through wasm2wat, the code above decompiles to:

(module
  (type $t0 (func (param i64) (result i64)))
  (func $f0 (type $t0) (param $p0 i64) (result i64)
    (if $I0 (result i64) ; $I0 is an unused label name
      (i64.eqz
        (local.get $p0)) ; the name $p0 is the same as 0 here
      (then
        (i64.const 1))
      (else
        (i64.mul
          (local.get $p0)
          (call $f0      ; the name $f0 is the same as 0 here
            (i64.sub
              (local.get $p0)
              (i64.const 1))))))))

Note that a module is implicitly generated by the compiler. The function is actually referenced by an entry of the type table in the binary, hence a type section and the type emitted by the decompiler.[97] The compiler and decompiler can be accessed online.[98]

Literature[]

  • Haas, Andreas; Rossberg, Andreas; Schuff, Derek L.; Titzer, Ben L.; Gohman, Dan; Wagner, Luke; Zakai, Alon; Bastien, JF; Holman, Michael (June 2017). "Bringing the web up to speed with WebAssembly". Proceedings of the 38th ACM SIGPLAN Conference on Programming Language Design and Implementation. Association for Computing Machinery: 185–200. doi:10.1145/3062341.3062363. ISBN 9781450349888.
  • Watt, Conrad (2018). "Mechanising and Verifying the WebAssembly Specification" (PDF). ACM SIGPLAN International Conference on Certified Programs and Proofs. ACM. 7: 53–65. doi:10.1145/3167082. ISBN 9781450355865. S2CID 9401691.
  • Jangda, Abhinav; Powers, Bobby; Berger, Emery D.; Guha, Arjun (July 2019). "Not So Fast: Analyzing the Performance of WebAssembly vs. Native Code" (PDF). USENIX Annual Technical Conference: 15. ISBN 9781939133038. Cite journal requires |journal= (help)

Notes[]

  1. ^ According to official documentation, the Emscripten SDK may be used to create .wasm files which then may be executed in a web browser.[14][15][16] Even though Emscripten can consume various languages when using Clang, some problems may arise.[17]

See also[]

References[]

  1. ^ "WebAssembly/design/Semantics.md". GitHub. Retrieved 23 February 2021. WebAssembly code can be considered a structured stack machine; a machine where most computations use a stack of values, but control flow is expressed in structured constructs such as blocks, ifs, and loops. In practice, implementations need not maintain an actual value stack, nor actual data structures for control; they need only behave as if they did so.
  2. ^ "Introduction — WebAssembly 1.0". webassembly.github.io. Retrieved 18 June 2019. WebAssembly is an open standard...
  3. ^ "Introduction — WebAssembly 1.0". webassembly.github.io. Retrieved 18 June 2019. WebAssembly is a ... code format
  4. ^ Jump up to: a b "Conventions — WebAssembly 1.0". webassembly.github.io. Retrieved 17 May 2019. WebAssembly is a programming language that has multiple concrete representations (its binary format and the text format). Both map to a common structure.
  5. ^ "Introduction — WebAssembly 1.0". webassembly.github.io. Retrieved 18 June 2019. ... this specification is complemented by additional documents defining interfaces to specific embedding environments such as the Web. These will each define a WebAssembly application programming interface (API) suitable for a given environment.
  6. ^ "Introduction — WebAssembly 1.1". webassembly.github.io. Retrieved 19 February 2021. Its main goal is to enable high performance applications on the Web, but it does not make any Web-specific assumptions or provide Web-specific features, so it can be employed in other environments as well.
  7. ^ Haas, Andreas; Rossberg, Andreas; Schuff, Derek L.; Titzer, Ben L.; Holman, Michael; Gohman, Dan; Wagner, Luke; Zakai, Alon; Bastien, JF (14 June 2017). "Bringing the Web Up to Speed with WebAssembly". SIGPLAN Notices. 52 (6): 185–200. doi:10.1145/3140587.3062363. ISSN 0362-1340. While the Web is the primary motivation for WebAssembly, nothing in its design depends on the Web or a JavaScript environment. It is an open standard specifically designed for embedding in multiple contexts, and we expect that stand-alone implementations will become available in the future.
  8. ^ Jump up to: a b c "Outside the web: standalone WebAssembly binaries using Emscripten · V8". v8.dev. Retrieved 28 July 2020.
  9. ^ "WebAssembly Specification — WebAssembly 1.1". webassembly.github.io. Retrieved 22 March 2021.
  10. ^ "WebAssembly JavaScript Interface". www.w3.org. Retrieved 24 June 2020.
  11. ^ World Wide Web Consortium. "WebAssembly Core Specification". World Wide Web Consortium (W3). Retrieved 9 December 2019.
  12. ^ Couriol, Bruno. "WebAssembly 1.0 Becomes a W3C Recommendation and the Fourth Language to Run Natively in Browsers". infoq.com. Retrieved 9 December 2019.
  13. ^ Jump up to: a b c "Wasmer - The Universal WebAssembly Runtime". wasmer.io. Retrieved 19 February 2021. Compile everything to WebAssembly. Run it on any OS or embed it into other languages.
  14. ^ "Developer's Guide - WebAssembly". webassembly.org. Retrieved 10 June 2019.
  15. ^ "Compiling a New C/C++ Module to WebAssembly". MDN Web Docs. Retrieved 10 June 2019.
  16. ^ "Building to WebAssembly — Emscripten 1.38.33 documentation". emscripten.org. Retrieved 10 June 2019.
  17. ^ "Emscripting a C library to Wasm | Web". Google Developers. Retrieved 10 June 2019.
  18. ^ "stdweb - Rust". docs.rs. Retrieved 5 June 2019. The goal of this crate is to provide Rust bindings to the Web APIs and to allow a high degree of interoperability between Rust and JavaScript.
  19. ^ "web_sys - Rust". docs.rs. Retrieved 5 June 2019. Raw API bindings for Web APIs. This is a procedurally generated crate from browser WebIDL which provides a binding to all APIs that browser provide on the web.
  20. ^ "js_sys - Rust". docs.rs. Retrieved 5 June 2019. Bindings to JavaScript's standard, built-in objects, including their methods and properties.
  21. ^ "Wasmtime — a small and efficient runtime for WebAssembly & WASI". wasmtime.dev. Retrieved 18 December 2020.
  22. ^ Jump up to: a b "New Bytecode Alliance Brings the Security, Ubiquity, and Interoperability of the Web to the World of Pervasive Computing". Mozilla. 12 November 2019. Retrieved 27 May 2019.
  23. ^ Bright, Peter (18 June 2015). "The Web is getting its bytecode: WebAssembly". Ars Technica. Condé Nast.
  24. ^ "Launch bug". GitHub / WebAssembly / design. 11 June 2015.
  25. ^ Wagner, Luke (14 March 2016). "A WebAssembly Milestone: Experimental Support in Multiple Browsers". Mozilla Hacks.
  26. ^ Thompson, Seth (15 March 2016). "Experimental support for WebAssembly in V8". V8 Blog.
  27. ^ Zhu, Limin (15 March 2016). "Previewing WebAssembly experiments in Microsoft Edge". Microsoft Edge dev blog.
  28. ^ Lardinois, Frederic (17 June 2015). "Google, Microsoft, Mozilla And Others Team Up To Launch WebAssembly, A New Binary Format For The Web". TechCrunch. Retrieved 24 December 2017.
  29. ^ Avram, Abel (31 May 2017). "Google Is to Remove Support for PNaCl". InfoQ. Retrieved 22 December 2017.
  30. ^ "WebAssembly: a binary format for the web". ②ality – JavaScript and more. 18 June 2015.
  31. ^ "Staring at the Sun: Dalvik vs. ASM.js vs. Native". blog.mozilla.org. Retrieved 7 December 2019. Even discarding the one score where asm.js did better, it executes at around 70% of the speed of native C++ code.
  32. ^ Jump up to: a b Krill, Paul (6 March 2017). "WebAssembly is now ready for browsers to use". InfoWorld. Retrieved 23 December 2017.
  33. ^ "WebAssembly First Public Working Drafts". W3C. 15 February 2018. Retrieved 20 April 2018.
  34. ^ "WebAssembly Core Specification". W3C. 15 February 2018. Retrieved 20 April 2018.
  35. ^ "WebAssembly JavaScript Interface". W3C. 15 February 2018. Retrieved 20 April 2018.
  36. ^ "WebAssembly Web API". W3C. 15 February 2018. Retrieved 20 April 2018.
  37. ^ "Non-Web Embeddings". WebAssembly. Retrieved 15 May 2019.
  38. ^ "Non-Web Embeddings". GitHub / WebAssembly. Retrieved 15 May 2019.
  39. ^ "WebAssembly support now shipping in all major browsers". The Mozilla Blog. Retrieved 21 November 2017.
  40. ^ "Introducing new JavaScript optimizations, WebAssembly, SharedArrayBuffer, and Atomics in EdgeHTML 16". Microsoft Edge Dev Blog. 31 October 2017. Retrieved 21 November 2017.
  41. ^ "WebAssembly". Can I use. Retrieved 22 March 2020.
  42. ^ Bright, Peter (18 June 2015). "The Web is getting its bytecode: WebAssembly". Ars Technica. Retrieved 23 December 2017.
  43. ^ Ball, Kevin (26 June 2018). "How WebAssembly is Accelerating the Future of Web Development". Archived from the original on 12 February 2019. Retrieved 22 October 2018.
  44. ^ Jump up to: a b "Awesome WebAssembly Languages". 26 June 2018. Archived from the original on 12 February 2019. Retrieved 12 February 2019.
  45. ^ Zakai, Alon [@kripken] (21 October 2019). "Emscripten has switched to the upstream LLVM wasm backend by default! / Details:https://groups.google.com/forum/#!topic/emscripten-discuss/NpxVAOirSl4 …" (Tweet). Retrieved 22 October 2019 – via Twitter.
  46. ^ "LLVM 8.0.0 Release Notes — LLVM 8 documentation". releases.llvm.org. Retrieved 22 October 2019.
  47. ^ Jump up to: a b "WebAssembly High-Level Goals". GitHub / WebAssembly / design. 11 December 2015.
  48. ^ Krill, Paul (29 November 2017). "Direct WebAssembly compilation comes to Rust language". InfoWorld. Retrieved 24 December 2017.
  49. ^ "Frequently asked questions (FAQ) about Blazor". blazor.net. Retrieved 18 June 2018.
  50. ^ AssemblyScript/assemblyscript, The AssemblyScript Project, 9 September 2020, retrieved 9 September 2020
  51. ^ Krill, Paul (26 October 2017). "What's next for WebAssembly: GC, threads, debugging". TechWorld. Retrieved 24 December 2017.
  52. ^ "