40,81 €
In the first definitive guide on WebAssembly, you'll learn how you can wield this new technology to break through the current barriers of web development and build an entirely new class of performant applications .
Key Features
Book Description
WebAssembly is a brand-new technology that represents a paradigm shift in web development. This book teaches programmers to leverage this technology to write high-performance applications that run in the browser. This book introduces you to powerful WebAssembly concepts to help you write lean and powerful web applications with native performance. You start with the evolution of web programming, the state of things today, and what can be done with the advent and release of WebAssembly. We take a look at the journey from JavaScript to asm.js to WebAssembly. We then move on to analyze the anatomy of a WebAssembly module and the relationship between binary and text formats, along with the corresponding JavaScript API. Further on, you'll implement all the techniques you've learned to build a high-performance application using C and WebAssembly, and then port an existing game written in C++ to WebAssembly using Emscripten. By the end of this book, you will be well-equipped to create high-performance applications and games for the web using WebAssembly.
What you will learn
Who this book is for
If you are a web developer or C/C++ programmer keen to leverage the powerful technology of WebAssembly to build high-performance web applications, then this book is for you.
Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:
Seitenzahl: 318
Veröffentlichungsjahr: 2018
Copyright © 2018 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Commissioning Editor: Kunal ChaudhariAcquisition Editor: Trusha ShriyanContent Development Editor: Aishwarya GawankarTechnical Editor: Surabhi KulkarniCopy Editor: Safis EditingProject Coordinator: Sheejal ShahProofreader: Safis EditingIndexer: Priyanka DhadkeGraphics: Alishon MendonsaProduction Coordinator: Nilesh Mohite
First published: September 2018
Production reference: 1240918
Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK.
ISBN 978-1-78899-737-9
www.packtpub.com
Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website.
Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals
Improve your learning with Skill Plans built especially for you
Get a free eBook or video every month
Mapt is fully searchable
Copy and paste, print, and bookmark content
Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details.
At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks.
Mike Rourke has been writing code for over a decade. He got his start creating Microsoft Access applications using VBA and decided he wanted to work with JavaScript full-time after building a Mozilla Firefox extension. He has a B.S. in mechanical engineering technology and worked primarily in product design/manufacturing engineering roles before starting a career as a software engineer in 2017. Currently, he works for a Chicago-based consulting company and is focused primarily on frontend JavaScript development. When's he not writing code, he's out in the woods camping with his wolf brothers.
Dan Ruta is a fresh graduate, about to start an MSc in computer vision. He got started with WebAssembly by implementing a small web-based deep learning library, and messing around with WebAssembly and GPGPU.
Other publications he has worked on include occasional technical blogs on Medium, and a team research paper combining AI, AR, and WebGL shaders to assist the visually impaired, which he presented at a conference.
His projects can be followed on GitHub and Medium (DanRuta), or on his website and tweets (Dan_Ruta).
Maxim Shaydo aka Moreas MaxGraey is an independent developer, consultant, system architect from Ukraine, he has worked with at LaSoft as a CTO and is a big fan of open source community.
He continues to be an enduring contributor for open source projects dedicated to WebAssembly, such as AssemblyScript language that has been gaining a lot of attention lately. He happens to be very interested in development of WebGL, WebVR technologies, and Flow Based Programming as well.
This project could not have been completed without being reviewed by Alon Zakai (kripken) known for his work on emscripten and binaryen. Special thanks to Daniel Wirtz (dcodeIO) who is the main contributor of AssemplyScript and an incredibly productive mate. Last but not the least, I would like to thank my parents — Mr. and Mrs Shaydo, without them none of this would indeed be possible.
If you're interested in becoming an author for Packt, please visit authors.packtpub.com and apply today. We have worked with thousands of developers and tech professionals, just like you, to help them share their insight with the global tech community. You can make a general application, apply for a specific hot topic that we are recruiting an author for, or submit your own idea.
Title Page
Copyright and Credits
Learn WebAssembly
Dedication
PacktPub.com
Why subscribe?
PacktPub.com
Contributors
About the author
About the reviewers
Packt is searching for authors like you
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Download the color images
Conventions used
Get in touch
Reviews
What is WebAssembly?
The road to WebAssembly
The evolution of JavaScript
Google and Native Client
Mozilla and asm.js
WebAssembly is born
What exactly is WebAssembly and where can I use it?
Official definition
Binary instruction format
Portable target for compilation
The core specification
Language concepts
Semantic phases
The JavaScript and Web APIs
So will it replace JavaScript?
Where can I use it?
What languages are supported?
C and C++
Rust
Other languages
What are the limitations?
No garbage collection
No direct DOM access
No support in older browsers
How does it relate to Emscripten?
Emscripten's role
The EMSDK and Binaryen
Summary
Questions
Further reading
Elements of WebAssembly - Wat, Wasm, and the JavaScript API
Common structure and abstract syntax
Wat
Definitions and S-expressions
Values, types, and instructions
Role in the development process
Binary format and the module file (Wasm)
Definition and module overview
Module sections
The JavaScript and Web APIs
WebAssembly store and object caches
Loading a module and the WebAssembly namespace methods
WebAssembly objects
WebAssembly.Module
WebAssembly.Instance
WebAssembly.Memory
WebAssembly.Table
WebAssembly errors (CompileError, LinkError, RuntimeError)
Connecting the dots with WasmFiddle
What is WasmFiddle?
C code to Wat
Wasm to JavaScript
Summary
Questions
Further reading
Setting Up a Development Environment
Installing the development tooling
Operating systems and hardware
macOS 
Ubuntu
Windows
Package managers
Homebrew for macOS
Apt for Ubuntu
Chocolatey for Windows
Git
Installing Git on macOS
Installing Git on Ubuntu
Installing Git on Windows
Node.js
nvm
Installing nvm on macOS
Install nvm on Ubuntu
Installing nvm on Windows
Installing Node.js using nvm
GNU make and rimraf
GNU Make on macOS and Ubuntu
Installing GNU Make on macOS
Installing GNU Make on Ubuntu
Installing GNU make on Windows
Installing rimraf
VS Code
Installing Visual Studio Code on macOS
Installing Visual Studio Code on Ubuntu
Installing VS Code on Windows
Configuring VS Code
Managing settings and customization
Extensions overview
Configuration for C/C++ and WebAssembly
Installing C/C++ for VS Code
Configuring C/C++ for VS Code
WebAssembly Toolkit for VSCode
Other useful extensions
Auto rename tag
Bracket pair colorizer
Material Icon theme and Atom One Light theme
Setting up for the web
Cloning the book examples repository
Installing a local server
Validating your browser
Validating Google Chrome
Validating Mozilla Firefox
Validating other browsers
Other tools
iTerm2 for macOS
Terminator for Ubuntu
cmder for Windows
Zsh and Oh-My-Zsh
Summary
Questions
Further reading
Installing the Required Dependencies
The development workflow
Steps in the workflow
Integrating Tooling into the workflow
Emscripten and the EMSDK
Emscripten overview
Where does the EMSDK fit in?
Installing the prerequisites
Common prerequisites
Installing the prerequisites on macOS
Installing the prerequisites on Ubuntu
Installing the prerequisites on Windows
Installing and configuring the EMSDK
Installation process across all platforms
Installation on macOS and Ubuntu
Installation and configuration on Windows
Configuration in VS Code
Testing the compiler
The C code
Compiling the C code
Summary
Questions
Further reading
Creating and Loading a WebAssembly Module
Compiling C with Emscripten glue code
Writing the example C code
Compiling the example C code
Outputting HTML with glue code
Outputting glue code with no HTML
Loading the Emscripten module
Pre-generated loading code
Writing custom loading code
Compiling C without the glue code
C code for WebAssembly
Compiling with a Build Task in VS Code
Fetching and instantiating a Wasm file
Common JavaScript loading code
The HTML page
Serving it all up
Summary
Questions
Further reading
Interacting with JavaScript and Debugging
The Emscripten module versus the WebAssembly object
What is the Emscripten module?
Default methods in the glue code
Differences with the WebAssembly object
Calling compiled C/C++ functions from JavaScript
Calling functions from a Module 
Module.ccall()
Module.cwrap()
C++ and name mangling
Calling functions from a WebAssembly instance
Calling JavaScript functions from C/C++
Interacting with JavaScript using glue code
Executing strings with emscripten_run_script()
Executing inline JavaScript with EM_ASM()
Reusing inline JavaScript with EM_JS()
Examples of using glue code
The C code
The HTML code
Compiling and serving the result
Interacting with JavaScript without glue code
Passing JavaScript to C/C++ using the import object
Calling imported functions in C/C++
An example without glue code
The C++ code
The HTML code
Compiling and serving the result
Advanced Emscripten features
Embind
File System API
Fetch API
Debugging in the browser
High-level overview
Using source maps
Summary
Questions
Further reading
Creating an Application from Scratch
Cook the Books – making WebAssembly accountable
Overview and functionality
JavaScript libraries used
Vue
UIkit
Lodash
Data-driven documents
Other libraries
C and the build process
Setting up the project
Configuring for Node.js
Adding files and folders
Configuring the build step
Setting up a mock API
Downloading the C stdlib Wasm
The final result
Building the C portion
Overview
A note regarding workflow
C file contents
Declarations
Linked list operations
transactions operations
transactions calculations
Category calculations
Compiling to Wasm
Building the JavaScript portion
Overview
A note about browser compatibility
Creating a Wasm instance in initializeWasm.js
Interacting with Wasm in WasmTransactions.js
Utilizing the API in api.js
Managing global state in store.js
The import and store declarations
Transactions operations
TransactionModal management
Balances calculation
Store initialization
Loading the application in main.js
Adding the web assets
Creating the Vue components
The structure of a Vue component
The App component
The BalancesBar
The TransactionsTab
The ChartsTab
Running the application
Validating the /src folder
Start it up!
Testing it out
Changing initial balances
Creating a new transaction
Deleting an existing transaction
Editing an existing transaction
Testing the Charts tab
Wrap up
Summary
Questions
Further reading
Porting a Game with Emscripten
Overview of the game
What is Tetris?
The source of the source
A note about porting
Getting the code
Building the native project
The game in action
The code base in depth
Breaking the code into objects
The constants file
The piece class
The constructor and draw() function
The move(), rotate(), and isBlock() functions
The getColumn() and getRow() functions
The Board class
The constructor and draw() function
The isCollision() function
The unite() function
The displayScore() function
The Game class
The constructor and destructor
The loop() function
The main file
Porting to Emscripten
Preparing for porting
What's changing?
Adding the web assets
Porting the existing code
Updating the constants file
Building and running the game
Building with VS Code tasks
Building with a Makefile
Running the game
Summary
Questions
Further reading
Integrating with Node.js
Why Node.js?
Seamless integration
Complementary technologies
Development with npm
Server-side WebAssembly with Express
Overview of the project
Express configuration
Instantiating a Wasm module with Node.js
Creating a mock database
Interacting with the WebAssembly module
Wrapping interaction in Transaction.js
Transaction operations in assign-routes.js
Building and running the application
Building the application
Starting and testing out the application
Client-side WebAssembly with Webpack
Overview of the project
What is Webpack?
Installing and configuring Webpack
Dependencies overview
Configuring loaders and plugins in webpack.config.js
The C code
Definitions and declarations
The start() function
The updateRectLocation() function
The JavaScript code
The import statements
Component state
Wasm initialization
Component mounting
Component rendering
Building and running the application
Testing the build
Running the start script
Testing WebAssembly modules with Jest
The code being tested
Testing configuration
Tests file review
Running the tests
Summary
Questions
Further reading
Advanced Tools and Upcoming Features
WABT and Binaryen
WABT – the WebAssembly binary toolkit
Binaryen
Compiling with LLVM
The installation process
The example code
The C++ file
The HTML file
Compiling and running the example
Online tooling
WasmFiddle
WebAssembly Explorer
WebAssembly Studio
Parallel Wasm with Web Workers
Web Workers and WebAssembly
Creating a worker
The WebAssembly workflow
Limitations in Google Chrome
Overview of the code
The C code
The JavaScript code
Defining thread execution in worker.js
Interacting with Wasm in WasmWorker.js
Loading the application in index.js
The web assets
Building and running the application
Compiling the C files
Interacting with the application
Debugging Web Workers
Upcoming features
The standardization process
Threads
Host bindings
Garbage collection
Reference types
Summary
Questions
Further reading
Other Books You May Enjoy
Leave a review - let other readers know what you think
This book introduces readers to WebAssembly, a new and exciting technology capable of executing languages other than JavaScript in the browser. The book describes how to build a C/JavaScript application from scratch that uses WebAssembly and the process for porting an existing C++ code base to run in the browser with the help of Emscripten.
WebAssembly represents an important shift for the web platform. As a compilation target for languages such as C, C++, and Rust, it provides the ability to build a new class of application. WebAssembly is supported by all of the major browser vendors and represents a collaborative effort.
In this book, we'll describe the elements that make up WebAssembly, as well as its origins. We'll walk through the process of installing the required tools, setting up a development environment, and interacting with WebAssembly. We'll work through simple examples and progress through increasingly advanced use cases. By the end of this book, you'll be well-equipped to use WebAssembly in your C, C++, or JavaScript project.
If you are a C/C++ programmer who wishes to build applications for the web, or a web developer who wishes to improve the performance of their JavaScript applications, then this book is for you. The book is intended for developers familiar with JavaScript who wouldn't mind learning some C and C++ (and vice versa). This book accommodates for C/C++ programmers and JavaScript programmers alike by providing two example applications.
Chapter 1, What is WebAssembly?, describes the origins of WebAssembly and provides a high-level overview of the technology. It covers how WebAssembly can be used, which programming languages are supported, and its current limitations.
Chapter 2, Elements of WebAssembly – Wat, Wasm, and the JavaScript API, outlines the elements that comprise WebAssembly. It provides a detailed explanation of the text and binary formats, as well as the corresponding JavaScript and Web APIs.
Chapter 3, Setting Up a Development Environment, walks through the tooling used to develop with WebAssembly. It provides the installation instructions for each platform and provides recommendations for improving the development experience.
Chapter 4, Installing the Required Dependencies, provides instructions for installing the toolchain requirements for each platform. By the end of this chapter, you'll be able to compile C and C++ to WebAssembly modules.
Chapter 5, Creating and Loading a WebAssembly Module, explains how to generate a WebAssembly module using Emscripten and how flags are passed to the compiler affect the resulting output. It describes the techniques for loading a WebAssembly module in the browser.
Chapter 6, Interacting with JavaScript and Debugging, elaborates on the differences between Emscripten's Module object and the browser's global WebAssembly object. This chapter describes the features Emscripten provides as well as instructions for generating source maps.
Chapter 7, Creating an Application from Scratch, walks through the creation of a JavaScript accounting application that interacts with a WebAssembly module. We will write C code to calculate values from accounting transactions and pass the data between JavaScript and the compiled WebAssembly module.
Chapter 8, Porting a Game with Emscripten, takes a step-by-step approach to porting an existing C++ game to WebAssembly using Emscripten. After reviewing the existing C++ code base, changes are made to the appropriate files to enable the game to run in the browser.
Chapter 9, Integrating with Node.js, demonstrates how Node.js and npm can be used with WebAssembly on the server and client side. The chapter covers the use of WebAssembly in an Express application, integrating WebAssembly with webpack, and testing a WebAssembly module using Jest.
Chapter 10, Advanced Tools and Upcoming Features, covers advanced tools, use cases, and new WebAssembly features currently in the process of standardization. This chapter describes WABT, Binaryen, and the tooling available online. In this chapter, you'll learn how to compile WebAssembly modules using LLVM and how WebAssembly modules can be used with Web Workers. The chapter wraps up with a description of the standardization process and a review of some of the exciting features in the process of being added to the specification.
You should have some programming experience and understand concepts such as variables, and functions. If you've never seen a line of JavaScript or C/C++ code, you may want to do some preliminary research before working through the examples in this book. I've chosen to use JavaScript ES6/7 features such as destructuring and arrow functions, so if you haven't worked with JavaScript in the last 3 - 4 years, the syntax may look slightly different.
You can download the example code files for this book from your account at www.packtpub.com. If you purchased this book elsewhere, you can visit www.packtpub.com/support and register to have the files emailed directly to you.
You can download the code files by following these steps:
Log in or register at
www.packtpub.com
.
Select the
SUPPORT
tab.
Click on
Code Downloads & Errata
.
Enter the name of the book in the
Search
box and follow the onscreen instructions.
Once the file is downloaded, please make sure that you unzip or extract the folder using the latest version of:
WinRAR/7-Zip for Windows
Zipeg/iZip/UnRarX for Mac
7-Zip/PeaZip for Linux
The code bundle for the book is also hosted on GitHub at https://github.com/PacktPublishing/Learn-WebAssembly. In case there's an update to the code, it will be updated on the existing GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://www.packtpub.com/sites/default/files/downloads/9781788997379_ColorImages.pdf.
There are a number of text conventions used throughout this book.
CodeInText: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: "instantiate() is the primary API for compiling and instantiating WebAssembly code."
A block of code is set as follows:
int addTwo(int num) { return num + 2;}
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
int calculate(int firstVal, int secondVal) {
return firstVal - secondVal;
}
Any command-line input or output is written as follows:
npm install -g webassembly
Bold: Indicates a new term, an important word, or words that you see onscreen. For example, words in menus or dialog boxes appear in the text like this. Here is an example: "You can do this by pressing the Start menu button, and right-clicking on the Command Prompt application and selecting Run as administrator."
Feedback from our readers is always welcome.
General feedback: Email [email protected] and mention the book title in the subject of your message. If you have questions about any aspect of this book, please email us at [email protected].
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/submit-errata, selecting your book, clicking on the Errata Submission Form link, and entering the details.
Piracy: If you come across any illegal copies of our works in any form on the Internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.
Please leave a review. Once you have read and used this book, why not leave a review on the site that you purchased it from? Potential readers can then see and use your unbiased opinion to make purchase decisions, we at Packt can understand what you think about our products, and our authors can see your feedback on their book. Thank you!
For more information about Packt, please visit packtpub.com.
WebAssembly (Wasm) represents an important stepping stone for the web platform. Enabling a developer to run compiled code on the web without a plugin or browser lock-in presents many new opportunities. Some confusion exists about what WebAssembly is, as does some skepticism about its staying power.
In this chapter, we will discuss how WebAssembly came to be, what WebAssembly is with regard to the official definition, and the technologies it encompasses. The potential use cases, supported languages, and limitations will be covered, as well as where to find additional information.
Our goal for this chapter is to understand the following:
The technologies that led the way for WebAssembly
What WebAssembly is and some of its potential use cases
Which programming languages can be used with WebAssembly
The current limitations of WebAssembly
How WebAssembly relates to Emscripten and asm.js
Web development has had an interesting history, to say the least. Several (failed) attempts have been made to expand the platform to support different languages. Clunky solutions such as plugins failed to stand the test of time, and limiting a user to a single browser is a recipe for disaster.
WebAssembly was developed as an elegant solution to a problem that has existed since browsers were first able to execute code: If you want to develop for the web, you have to use JavaScript. Fortunately, using JavaScript doesn't have the same negative connotations it had back in the early 2000s, but it continues to have certain limitations as a programming language. In this section, we're going to discuss the technologies that led to WebAssembly to get a better grasp of why this new technology is needed.
JavaScript was created by Brendan Eich in just 10 days back in 1995. Originally seen as a toy language by programmers, it was used primarily to make buttons flash or banners appear on a web page. The last decade has seen JavaScript evolve from a toy to a platform with profound capabilities and a massive following.
In 2008 heavy competition in the browser market resulted in the addition of just-in-time (JIT) compilers, which increased the execution speed of JavaScript by a factor of 10. Node.js debuted in 2009 and represented a paradigm shift in web development. Ryan Dahl combined Google's V8 JavaScript engine, an event loop, and a low-level I/O API to build a platform that allowed for the use of JavaScript across the server and client side. Node.js led to npm, a package manager that allowed for the development of libraries to be used within the Node.js ecosystem. As of the time of writing, there are over 600,000 packages available with hundreds being added every day:
It's not just the Node.js ecosystem that is growing; JavaScript itself is being actively developed. The ECMA Technical Committee 39 (TC39), which dictates the standards for JavaScript and oversees the addition of new language features, releases yearly updates to JavaScript with a community-driven proposal process. Between its wealth of libraries and tooling, constant improvements to the language, and possessing one of the largest communities of programmers, JavaScript has become a force to be reckoned with.
But the language does have some shortcomings:
Up until recently, JavaScript only included 64-bit floating point numbers. This can cause issues with very large or very small numbers.
BigInt
, a new numeric primitive that can alleviate some of these issues, is in the the process of being added to the ECMAScript specification, but it may take some time until it's fully supported in browsers.
JavaScript is weakly typed, which adds to its flexibility, but can cause confusion and bugs.
It essentially gives you enough rope to hang yourself.
JavaScript isn't as performant as compiled languages despite the best efforts of the browser vendors.
If a developer wants to create a web application, they need to learn JavaScript—whether they like it or not.
To avoid having to write more than a few lines of JavaScript, some developers built transpilers to convert other languages to JavaScript. Transpilers (or source-to-source compilers) are types of compilers that convert source code in one programming language to equivalent source code in another programming language. TypeScript, which is a popular tool for frontend JavaScript development, transpiles TypeScript to valid JavaScript targeted for browsers or Node.js. Pick any programming language and there's a good chance that someone created a JavaScript transpiler for it. For example, if you prefer to write Python, you have about 15 different tools that you can use to generate JavaScript. In the end, though, it's still JavaScript, so you're still subject to the idiosyncrasies of the language.
As the web evolved into a valid platform for building and distributing applications, more and more complex and resource-intensive applications were created. In order to meet the demands of these applications, browser vendors began working on new technologies to integrate into their software without disrupting the normal course of web development. Google and Mozilla, creators of Chrome and Firefox, respectively, took two different paths to achieve this goal, culminating in the creation of WebAssembly.
Google developed Native Client (NaCl) with the intent to safely run native code within a web browser. The executable code would run in a sandbox and offered the performance advantages of native code execution.
NaCl was tied to a specific architecture, while Portable Native Client (PNaCl) was an architecture-independent version of NaCl developed to run on any platform. The technology consisted of two elements:
Toolchains which could transform C/C++ code to NaCl modules
Runtime components which were components embedded in the browser that allowed execution of NaCl modules:
NaCl's architecture-specific executable (nexe) was limited to applications and extensions that were installed from Google's Chrome Web Store, but PNaCl executables (pexe) can be freely distributed on the web and embedded in web applications. Portability was made possible with Pepper, an open source API for creating NaCl modules, and its corresponding plugin API (PPAPI). Pepper enabled communication between NaCl modules and the hosting browser, and allowed for access to system-level functions in a safe and portable way. Applications could be easily distributed by including a manifest file and a compiled module (pexe) with the corresponding HTML, CSS, and JavaScript:
NaCl offered promising opportunities to overcome the performance limitations of the web, but it had some drawbacks. Although Chrome had built-in support for PNaCl executables and Pepper, other major browser did not. Detractors of the technology took issue with the black-box nature of the applications as well as the potential security risks and complexity.
Mozilla focused its efforts on improving the performance of JavaScript with asm.js. They wouldn't add support for Pepper to Firefox due to the incompleteness of its API specification and limited documentation. In the end, NaCl was deprecated in May, 2017, in favor of WebAssembly.
Mozilla debuted asm.js in 2013 and provided a way for developers to translate their C and C++ source code to JavaScript. The official specification for asm.js defines it as a strict subset of JavaScript that can be used as a low-level, efficient target language for compilers. It's still valid JavaScript, but the language features are limited to those that are amenable to ahead-of-time (AOT) optimization. AOT is a technique that the browser's JavaScript engine uses to execute code more efficiently by compiling it down to native machine code. asm.js achieves these performance gains by having 100% type consistency and manual memory management.
Using a tool such as Emscripten, C/C++ code can be transpiled down to asm.js and easily distributed using the same means as normal JavaScript. Accessing the functions in an asm.js module requires linking, which involves calling its function to obtain an object with the module's exports.
asm.js is incredibly flexible, however, certain interactions with the module can cause a loss of performance. For example, if an asm.js module is given access to a custom JavaScript function that fails dynamic or static validation, the code can't take advantage of AOT and falls back to the interpreter:
asm.js isn't just a stepping stone. It forms the basis for WebAssembly's Minimum Viable Product (MVP). The official WebAssembly site explicitly mentions asm.js in the section entitled WebAssembly High-Level Goals.
So why create WebAssembly when you could use asm.js? Aside from the potential performance loss, an asm.js module is a text file that must be transferred over the network before any compilation can take place. A WebAssembly module is in a binary format, which makes it much more efficient to transfer due to its smaller size.
WebAssembly modules use a promise-based approach to instantiation, which takes advantage of modern JavaScript and eliminates the need for any is this loadedyet? code.
The World Wide Web Consortium (W3C), an international community built to develop web standards, formed the WebAssembly Working Group in April, 2015, to standardize WebAssembly and oversee the specification and proposal process. Since then, the Core Specification and corresponding JavaScript API and Web API have been released. The initial implementation of WebAssembly support in browsers was based on the feature set of asm.js. WebAssembly's binary format and corresponding .wasm file combined facets of asm.js output with PNaCl's concept of a distributed executable.
So how will WebAssembly succeed where NaCl failed? According to Dr. Axel Rauschmayer, there are three reasons detailed at http://2ality.com/2015/06/web-assembly.html#what-is-different-this-time:
WebAssembly has a succinct and descriptive definition on the official site, but it's only a piece of the puzzle. There are several other components that fall under the umbrella of WebAssembly. Understanding the role each component plays will give you a better understanding of the technology as a whole. In this section, we will provide a detailed breakdown of WebAssembly's definition and describe potential use cases.
The official WebAssembly website (https://webassembly.org) offers this definition:
Let's break that definition down into parts to add some clarification.
WebAssembly actually encompasses several elements—a binary format and text format, which are documented in the Core Specification, the corresponding APIs (JavaScript and web), and a compilation target. The binary and text format both map to a common structure in the form of an abstract syntax. To better understand abstract syntax, it can be explained in the context of an abstract syntax tree (AST). An AST is a tree representation of the structure of source code for a programming language. Tools such as ESLint use JavaScript's AST to find linting errors. The following example contains a function and the corresponding AST for JavaScript (taken from https://astexplorer.net).
A simple JavaScript function follows:
function doStuff(thingToDo) { console.log(thingToDo);}
The corresponding AST is as follows:
{ "type": "Program", "start": 0, "end": 57, "body": [ { "type": "FunctionDeclaration", "start": 9, "end": 16, "id": { "type": "Identifier", "start": 17, "end": 26, "name": "doStuff" }, "generator": false, "expression": false, "params": [ { "type": "Identifier", "start": 28, "end": 57, "name": "thingToDo" } ], "body": { "type": "BlockStatement", "start": 32, "end": 55, "body": [ { "type": "ExpressionStatement", "start": 32, "end": 55, "expression": { "type": "CallExpression", "start": 32, "end": 54, "callee": { "type": "MemberExpression", "start": 32, "end": 43, "object": { "type": "Identifier", "start": 32, "end": 39, "name": "console" }, "property": { "type": "Identifier", "start": 40, "end": 43, "name": "log" }, "computed": false }, "arguments": [ { "type": "Identifier", "start": 44, "end": 53, "name": "thingToDo" } ] } } ] } } ], "sourceType": "module"}
An AST may be verbose, but it does an excellent job at describing the components of a program. Representing source code in an AST makes verification and compilation simple and efficient. WebAssembly code in text format is serialized into an AST and compiled to the binary format (as a .wasm file), which is fetched, loaded, and utilized by a web page. When the module is loaded, the browser's JavaScript engine utilizes a decoding stack to decode the .wasm file into an AST, perform type checking, and interpret it to execute functions. WebAssembly started as a binary instruction format for an AST. Due to the performance implications of verifying Wasm expressions that return void, the binary instruction format was updated to target a stack machine.
