You get a bonus - 1 coin for daily activity. Now you have 1 coin

WebAssembly ( Wasm ) — a portable binary code format

Lecture



WebAssembly ( Wasm ) defines a portable binary code format and a corresponding text format for executable programs , as well as programming interfaces to make communication between such programs and their host environment easier.

WebAssembly's main goal is to enable high-performance applications on web pages, but it is also designed for use in non-web environments. It is an open standard , intended to support any language on any operating system, and in practice many of the most popular languages already have at least some level of support.

Announced in 2015 and first released in March 2017, WebAssembly became a World Wide Web Consortium recommendation on 5 December 2019 and received the Programming Languages Software Award from ACM SIGPLAN in 2021. The World Wide Web Consortium (W3C) maintains the standard with contributions from Mozilla, Microsoft, Google, Apple, Fastly, Intel and Red Hat.

History

The name WebAssembly is meant to read as a synonym for assembly language. The name suggests bringing assembly-like programming to the web, where it would run on the client side — on the computer of the website's user, through that user's web browser. To achieve this, WebAssembly has to be far more hardware-independent than a real assembly language.

WebAssembly was first announced in 2015 , and the first demonstration was running Angry Bots by Unity in Firefox, , Google Chrome, and Microsoft Edge. The technology's predecessors were Mozilla's asm.js and Google Native Client, and the initial implementation was based on the asm.js feature set. asm.js already delivers execution speed close to that of native code and can be considered a viable alternative for browsers that do not support WebAssembly or have disabled it for security reasons.

In March 2017 it was announced that development of the minimum viable product (MVP) was complete and the preview phase had ended. In late September 2017, Safari 11 shipped with support. In February 2018, the WebAssembly Working Group published three public working drafts for the core specification, the JavaScript interface and the web API.

In June 2019, Chrome 75 shipped with WebAssembly threads enabled by default.

Since April 2022, WebAssembly 2.0 has been in draft status, adding a large number of SIMD-related instructions and a new v128 data type, along with the ability for functions to return multiple values and to initialise/copy bulk memory.

Implementations

Although WebAssembly was originally designed to deliver execution speed close to that of machine code in a web browser, it was also seen as valuable beyond that, in more general contexts. Because WebAssembly runtimes (REs) are low-level virtual stack machines (similar to the JVM or the Flash VM) that can be embedded in host applications, some implementations build standalone runtimes such as Wasmtime [ Wikidata ] and Wasmer [ Wikidata ] . WebAssembly runtimes are embedded in application servers to host "server-side" WebAssembly applications, and in other applications to support plugin-based software extension architectures — for example "WebAssembly for Proxies" (proxy-wasm), which defines a WebAssembly-based ABI for extending proxy servers.

Web browsers

In November 2017, Mozilla declared support "in all major browsers" after WebAssembly was enabled by default in Edge 16. This support also covers mobile web browsers for iOS and Android. As of March 2024, 99% of tracked web browsers support WebAssembly (version 1.0), more than for its predecessor asm.js. For the 2.0 standard, support may be lower, but still more than 90% of web browsers can already support, for example, the reference-types extension.

Compilers

WebAssembly implementations typically use either ahead-of-time (AOT) compilation or just-in-time (JIT) compilation, but they can also use an interpreter. Although the first implementations appeared in web browsers, there are also general-purpose non-browser implementations, including Wasmer, Wasmtime or WAMR, wasm3, WAVM and many others.

Because WebAssembly executables are precompiled, a variety of programming languages can be used to produce them. This is achieved either by compiling directly to Wasm, or by implementing the corresponding virtual machines in Wasm. Around 40 programming languages are reported to support Wasm as a compilation target.

Emscripten compiles C and C++ to Wasm , using Clang as the front end, replacing LLVM as the back end and using Binaryen as the optimiser. The Emscripten SDK can compile source code in any language supported by LLVM (for example C, C++ or Rust, and so on) into a binary that runs in the same sandboxed environment as JavaScript code. [ note 1 ] Emscripten provides bindings for several commonly used environment interfaces, such as WebGL.

Starting with version 8, standalone Clang can compile C and C++ to Wasm. The initial goal was to support compilation from C and C++, although support is also emerging for other source languages such as Rust, the .NET languages and AssemblyScript (which is TypeScript-like).

After the MVP release, WebAssembly added support for multithreading and garbage collection ( WasmGC , and web browsers including Safari added support for it), which made it possible to compile garbage-collected programming languages more efficiently, such as C# (supported via Blazor), F# (supported via Bolero, which uses Blazor) and Python.

Some other languages have some level of support, including Python, Julia, Ruby and Ring.

A number of systems can compile Java and other JVM languages to JavaScript and WebAssembly. These include CheerpJ, JWebAssembly and TeaVM. Kotlin supports WebAssembly directly.

Limitations

Web browsers do not allow WebAssembly code to manipulate the Document Object Model directly. To do so, Wasm code must go through JavaScript. [ note 2 ]

In a developer survey conducted in October 2023, fewer than half of the 303 participants were satisfied with the state of WebAssembly. The overwhelming majority pointed to the need for improvement in four areas: WASI, debugging support, integration with JavaScript and browser APIs, and build tooling.

For memory-intensive allocation in WebAssembly there are "serious limitations that make it impossible to reliably deploy many applications in mobile browsers [...] At present, allocating more than ~300 MB of memory is not reliable either in Chrome on Android without using Chrome-specific workarounds, or in Safari on iOS".

All major browsers allow WebAssembly if no Content-Security-Policy is specified or if "unsafe-eval" is used, but otherwise they behave differently. Chrome requires "unsafe-eval", although a worker thread may be a solution.

Security considerations

In June 2018, a security researcher demonstrated the possibility of using WebAssembly to bypass browser mitigations for the Spectre and Meltdown vulnerabilities after shared-memory thread support was added. Because of this problem, the WebAssembly developers put the feature on hold. However, in order to explore these future language extensions, Google Chrome added experimental support for the WebAssembly threads proposal in October 2018.

WebAssembly has been criticised for allowing malware developers, scammers and phishing attacks to conceal evidence more easily; WebAssembly is present on the user's computer only in compiled form, which "[makes] malware detection harder". The speed and easy concealment available in WebAssembly have led to its use for covert cryptocurrency mining on the devices of website visitors. Coinhive, a now-defunct service that made it easy to mine cryptocurrency in the browsers of a website's visitors, claimed that their "miner uses WebAssembly and runs at roughly 65% of the performance of a native miner". A June 2019 study at the Technical University of Braunschweig analysed WebAssembly usage across the Alexa top 1 million websites and found that the predominant use was malicious cryptocurrency mining, and that malware accounted for more than half of the surveyed websites using WebAssembly. An April 2021 study at the University of Stuttgart showed that cryptocurrency mining had since been pushed into the background, falling to less than 1% of all WebAssembly modules collected from a broad range of sources, including the Alexa top 1 million websites as well.

Because WebAssembly supports only structured control flow, it lends itself to security verification techniques, including symbolic execution.

WASI

The WebAssembly System Interface (WASI) is a simple interface (an ABI and API) designed by Mozilla that is intended to be portable to any platform. It provides POSIX-like functions, such as file I/O, constrained by capability-based security. There are further proposed ABIs/APIs.

WASI is influenced by CloudABI and Capsicum.

Solomon Hykes , 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."

Specification

Host environment

The overall standard contains the core specifications for the JavaScript API and details of embedding.

Virtual machine

Wasm code (binary code, i.e. bytecode) is designed to run on a portable virtual stack machine (VM). The VM is designed for faster parsing and execution than JavaScript, and for a compact code representation. Any external functionality (such as system calls) that Wasm binary code might expect is not provided by the standard. Instead, it provides a way for the host environment in which the VM runs to expose an interface through modules.

A Wasm program

A Wasm program is designed as a separate module containing sets of the various values defined by Wasm and definitions of program types. These are supplied in binary or text format (see below), which share a common structure. Such a module can expose a start function that is executed when the wasm binary is instantiated.

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 the types of operations that the virtual machine executes (without specifying exactly how they must be executed). The list of instructions includes standard memory load/store instructions, numeric, parametric, type control-flow instructions, and Wasm-specific variable instructions.

The number of opcodes used in the original standard (MVP) was slightly under 200 out of 256 possible opcodes. Later versions of WebAssembly increased the number of opcodes to slightly over 200. The WebAssembly SIMD proposal (for parallel processing) introduces an alternative opcode prefix (0xfd) for 128-bit SIMD. The concatenation of the SIMD prefix and 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 (about 436 instructions in total). These instructions, the "finished opcodes", are enabled by default in Google V8 (in Google Chrome), the SpiderMonkey engine in Mozilla Firefox and the JavaScriptCore engine in Apple's Safari, and there are also some further instruction proposals for a later "post SIMD MVP", as well as a separate "relaxed-simd" proposal on the table.

These SIMD opcodes are also portable and are translated to native instruction sets such as x64 and ARM. By contrast, neither Java's JVM nor CIL supports SIMD at the opcode level , i.e. in the standard; both have some parallel APIs that provide SIMD acceleration. There is an extension for Java that adds intrinsics for x64 SIMD, which is not portable, i.e. it cannot be used 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, the JavaScript API and the reference interpreter. [ 106 ] It defines the WebAssembly binary format ( .wasm), which is not intended to be used by humans, as well as the human-readable WebAssembly text format ( .wat), which resembles something between S-expressions and traditional assembly languages.

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

C source code and the corresponding WebAssembly
C source code WebAssembly text format .wat WebAssembly binary format .wasm

 
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 06 01 60 01 7E 01 7E 
03 02 01 00 
0A 17 01 
15 00 
20 00 50 
04 
7E 
42 01 
05 
20 00 
20 00 
42 01 
7Д 
10 00 
7Е 
0Б 
0Б

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

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 behavioural differences from the linear format. Using wasm2watthe 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 here is the same as 0 
      ( then 
        ( i64.const  1 )) 
      ( else 
        ( i64.mul 
          ( local.get  $p0 ) 
          ( call  $f0       ;; the name $f0 here is the same as 0 
            ( i64.sub 
              ( local.get  $p0 ) 
              ( i64.const  1 ))))))))

The module is generated implicitly by the compiler. The function references an entry in the type table in the binary, hence the type section and the type emitted by the decompiler. The compiler and decompiler are available online.

See also

  • ​Architecture Neutral Distribution Format (ANDF)
  • UNCOL
  • Java bytecode
  • Common Language Runtime
  • LLVM
  • Compilation
  • Software portability
  • DOM
  • JavaScript
  • WebGL

Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Scripting client side JavaScript, jqvery, BackBone"

Terms: Scripting client side JavaScript, jqvery, BackBone