📄 Page
1
(This page has no text content)
📄 Page
2
WebAssembly: The Definitive Guide Safe, Fast, and Portable Code Brian Sletten
📄 Page
3
WebAssembly: The Definitive Guide by Brian Sletten Copyright © 2022 Bosatsu Consulting, Inc. All rights reserved. Printed in the United States of America. Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles (http://oreilly.com). For more information, contact our corporate/institutional sales department: 800-998-9938 or corporate@oreilly.com. Acquisitions Editor: Suzanne McQuade Development Editor: Angela Rufino Production Editor: Kate Galloway Copyeditor: Piper Editorial Consulting, LLC Proofreader: JM Olejarz Indexer: nSight, Inc. Interior Designer: David Futato Cover Designer: Karen Montgomery Illustrator: Kate Dullea December 2021: First Edition Revision History for the First Edition
📄 Page
4
2021-12-01: First Release See http://oreilly.com/catalog/errata.csp?isbn=9781492089841 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. WebAssembly: The Definitive Guide, the cover image, and related trade dress are trademarks of O’Reilly Media, Inc. The views expressed in this work are those of the author, and do not represent the publisher’s views. While the publisher and the author have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights. 978-1-492-08984-1 [LSI]
📄 Page
5
Dedication This book was born on a mountain of privilege during a period when many people didn’t have the luxury of working from home. It is therefore dedicated to the frontline and essential workers who kept the lights on during a dark time.
📄 Page
6
Preface I believe WebAssembly is an ascendant technology that has the potential to transform the entire software development industry in one form or another. I do not believe WebAssembly is going to be transformative because I am writing a book on the topic. I’m writing a book on it because I believe it will be transformative. Presumably you are interested in the technology as well. The problem is, I think I have less of an idea of who you are as a reader than many authors do. If this were a book about a particular programming language or a specific topic, there would be a self-selecting aspect to the audience and I could proceed apace. But WebAssembly is a much larger topic than most people realize, and I am trying to paint a very large picture with this book. Most of the other books that have been published have focused on a single aspect of it, and I can understand why. Some of you might think WebAssembly is a technology for killing JavaScript. It isn’t. Some of you may think it is about bringing applications to the browser. It is that, but it is also so much more. It is useful on the server side, in the video game world, as a plug-in mechanism, in support of serverless functions and edge computing, in embedded systems, for the blockchain, and in many other topics we will investigate together. This is the first attempt I know of to be this comprehensive with the topic, and I felt it was important to tell this more complete version. In the lead-up to the publication of this book, I have mostly gotten positive support and excitement from people I have spoken to about the project. One limited form of pushback I have gotten is with respect to the title. Some folks felt it was premature to have “The Definitive Guide” for this new of a technology. That is a fair position to take, but because I am trying to describe an extremely big and encompassing technical landscape, I thought it was reasonable. I hope by the end of the book you agree.
📄 Page
7
All I ask is that you have an open mind and a bit of patience. WebAssembly touches a lot of languages, runtimes, and operational environments. In addition to teaching you about the low-level details, we will look at integrations with the dominant programming languages in this space and several different use cases. I have tried not to make too many assumptions about your background, so I have heavily annotated the text with breadcrumbs for further exploration and discovery via footnotes. If you are a more advanced developer just seeking details about WebAssembly, feel free to ignore these and don’t take offense. I expect a rather wide audience will be at least perusing this book, and I want them to feel welcome, too. If you are on the junior side development-wise, this will be a challenging book. But I have tried to make it possible for you to at least see what is going on. Consider the various links and references as a personal guide into a more sophisticated development reality. Don’t get overwhelmed, just tackle things one at a time in whatever order interests you or makes sense. There is no single way into this industry, and however you get there is legitimate. At the end of the day, WebAssembly is going to allow us to basically choose our programming languages and run them securely in just about any computational surface area. We have been promised this before, but I think this time it is more likely to come to fruition. Thank you for giving me the opportunity to explain why. Conventions Used in This Book The following typographical conventions are used in this book: Italic Indicates new terms, URLs, email addresses, filenames, and file extensions. Constant width
📄 Page
8
Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types, environment variables, statements, and keywords. Constant width bold Shows commands or other text that should be typed literally by the user. Constant width italic Shows text that should be replaced with user-supplied values or by values determined by context. This element signifies a tip or suggestion. This element signifies a general note. Using Code Examples Supplemental material (code examples, exercises, etc.) is available for download at https://github.com/bsletten/wasm_tdg. If you have a technical question or a problem using the code examples, please send email to bookquestions@oreilly.com. This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation. You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant
📄 Page
9
amount of example code from this book into your product’s documentation does require permission. We appreciate, but generally do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “WebAssembly: The Definitive Guide by Brian Sletten (O’Reilly). Copyright 2022 Bosatsu Consulting, Inc., 978-1-492-08984-1.” If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at permissions@oreilly.com. O’Reilly Online Learning For more than 40 years, O’Reilly Media has provided technology and business training, knowledge, and insight to help companies succeed. Our unique network of experts and innovators share their knowledge and expertise through books, articles, and our online learning platform. O’Reilly’s online learning platform gives you on-demand access to live training courses, in-depth learning paths, interactive coding environments, and a vast collection of text and video from O’Reilly and 200+ other publishers. For more information, visit http://oreilly.com. How to Contact Us Please address comments and questions concerning this book to the publisher: O’Reilly Media, Inc. 1005 Gravenstein Highway North Sebastopol, CA 95472
📄 Page
10
800-998-9938 (in the United States or Canada) 707-829-0515 (international or local) 707-829-0104 (fax) We have a web page for this book, where we list errata, examples, and any additional information. You can access this page at https://oreil.ly/webassemblyTDG. Email bookquestions@oreilly.com to comment or ask technical questions about this book. For news and information about our books and courses, visit http://oreilly.com. Find us on Facebook: http://facebook.com/oreilly Follow us on Twitter: http://twitter.com/oreillymedia Watch us on YouTube: http://youtube.com/oreillymedia Acknowledgments At times, our own light goes out and is rekindled by a spark from another person. Each of us has cause to think with deep gratitude of those who have lighted the flame within us. —Albert Schweitzer The myth of the sole author is persistent. I have huge communities of people to thank for the production of this book and their assistance to me along the way. On the other hand, I alone am responsible for any errors, inaccuracies, and problems. I would like to start with the larger WebAssembly community. They have done a remarkable job in designing this platform without overdesigning it. It is a moving target, and they are busy juggling and balancing a surplus of competing issues. Along the way, they have left breadcrumbs to explain
📄 Page
11
decisions and lay the foundations for the future. I would like to call special attention to the contributions of Lin Clark, who has emerged as one of my favorite technical communicators. Not only is she generous with her time, but her cartoon introductions to complex topics are also among the most effective forms of technical communication I have encountered. The O’Reilly community is a top-notch organization. Everyone I have encountered there, current and past, has been a solid representative of the brand. I would like to thank Mike Loukides for his time in discussing my much larger views and suggesting we start with WebAssembly. My editors, Zan McQuade and Angela Rufino, have been stalwart champions of the project with the absolute patience of Job. Kate Galloway and her team helped me get it across the finish line. I would like to issue a special thank you to Karen Montgomery for the beautiful cover. My dogs’ groomer is especially fond of it, as you caught the essence of this ridiculously lovable breed of Norwich terriers. For those who have questioned the relevance, they are the smallest working dog and—as I pitched it—small, fast, and portable, just like WebAssembly. For insight into the various WebAssembly use cases, I interviewed several members of the projects and companies I mention throughout. In no particular order, I would like to express my gratitude to Tim McCallum, Aaron Turner, Connor Hicks, Liam Randall, Kevin Hoffman, Sasha Krsmanovic, Jérôme Laban, and Francois Tanguay. The technical reviewers have honored me with the gift of their time and feedback. I would like to thank Dr. Sam Bail, Taylor Poindexter, Hannah Thoreson, Brooks Townsend, Jay Phelps, David Sletten, and the incomparable Dr. Venkat Subramaniam. I was given a venue to begin speaking professionally about WebAssembly by Jay Zimmerman of the No Fluff Just Stuff conference series back in 2017. He and I knew it was too soon, but we wanted to start the conversation and I appreciate the opportunity. The rest of the speakers and attendees of this remarkable technical carnival have given me no end of inspiration and feedback, for which I am so much the richer.
📄 Page
12
My friends and family have encouraged and supported me in all things, a debt I will never be able to repay. No one has done more than my wife and friend, Kristin. She and our dogs, Loki and Freyja, have made this time at home during the pandemic not just bearable, but richer than my life on the road. Thank you, all.
📄 Page
13
Chapter 1. Introduction Extraordinary claims require extraordinary evidence. —Dr. Carl Sagan This chapter will introduce WebAssembly and provide context for its expansive reach. In some sense it is a culmination of the evolution of the web over the last several decades. There is quite a bit of history to cover to make sense of it all. If you are not a fan of history and exposition, you can skip this chapter and go to directly to Chapter 2, but I hope you don’t. I think it is important to understand why this technology is so important and where it came from. What WebAssembly Offers One of the greatest skills an engineer can develop is the ability to assess what a new technology brings to the table. As Dr. Fred Brooks of the University of North Carolina reminds us, there are no “silver bullets”; everything has trade-offs. Complexity is often not eliminated with a new technology, but is simply moved somewhere else. So when something does actually change what is possible or how we do our work in a positive direction, it deserves our attention and we should figure out why. When trying to understand the implications of something new, I usually start by trying to determine the motivation of those behind it. Another good source of insight is where an alternative has fallen short. What has come before, and how does it influence this new technology we are trying to decipher? As in art and music, we are constantly borrowing good ideas from multiple sources, so to truly understand why WebAssembly deserves our attention and what it provides, we must first look at what has preceded it and how it makes a difference.
📄 Page
14
In the paper that formally introduced the world to WebAssembly, the authors indicate that the motivation was about rising to meet the needs of modern, web-delivered software in ways that JavaScript alone could not. Ultimately, it was a quest to provide software that is: Safe Fast Portable Compact In this vision, WebAssembly is centered at the intersection of software development, the web, its history, and how it delivers functionality in a geographically distributed space. Over time, the idea has expanded dramatically beyond this starting point to imagine a ubiquitous, safe, performant computational platform that touches just about every aspect of our professional lives as technologists. WebAssembly will impact the worlds of client-side web development, desktop and enterprise applications, server-side functionality, legacy modernization, games, education, cloud computing, mobile platforms, Internet of Things (IoT) ecosystems, serverless and microservices initiatives, and more. I hope to convince you of this over the course of this book. Our deployment platforms are more varied than ever, so we need portability at both the code and application levels. A common instruction set or byte code target can make algorithms work across various environments because we just need to map logical steps to how they can be expressed on a particular machine architecture. Programmers use application programming interfaces (APIs) such as OpenGL, POSIX, or Win32 because they provide the functionality to open files, spawn subprocesses, or draw things to the screen. They are convenient and reduce the amount of code a developer needs to write, but they create a dependency on the presence of libraries to provide the functionality. If the API is not available in a target environment, the application will not run. This was one of the ways Microsoft was able to use its strength in the operating system marketplace 1 2 3 4
📄 Page
15
to dominate in the application suite space as well. On the other hand, open standards can make it easier to port software into different environments. Another issue with the runtime side of the software we are building is that different hosts have different hardware capabilities (number of cores, presence of GPUs) or security restrictions (whether files can be opened or network traffic can be sent or received). Software often adapts to what is available by using features-testing approaches to determine what resources an application can take advantage of, but this often complicates the business functionality. We simply cannot afford the time and money needed to rewrite software for multiple platforms constantly. Instead, we need better strategies for reuse. We also need this flexibility without the complexity of modifying the code to support the platform on which it will run. Making the code different for different host environments increases its complexity and complicates testing and deployment strategies. After several decades, the value proposition of open source software is clear. We gravitate toward valuable, reusable components written by other developers as a means of satisficing our own needs. However, not all available code is trustworthy, and we open ourselves up to software supply chain attacks when we execute untrusted bits we have downloaded from the internet. We become vulnerable to the risks, business impacts, and personal costs of insecure software systems through phishing attacks, data breaches, malware, and ransomware. Until now, JavaScript has been the only way to solve some of these problems. When it is run in a sandboxed environment, it gives us some manner of security. It is ubiquitous and portable. The engines have gotten faster. The ecosystem has exploded into an avalanche of productivity. Once you leave the confines of browser-based protections, however, we still have security concerns. There is a difference between JavaScript code running as a client and JavaScript running on the server. The single-threaded design complicates long-running or highly concurrent tasks. Due to its origins as a dynamic language, there are several classes of optimizations that are available to other programming languages that are, and will remain, 5
📄 Page
16
unavailable as options to even the fastest and most modern JavaScript runtimes. Additionally, it is too easy to add JavaScript dependencies and not realize how much baggage and risk are being pulled in transitively. Developers who do not take the time to consider these decisions carefully end up encumbering every aspect of upstream software testing, deployment, and use. Each of these scripts has to be loaded and validated once it is transferred over the network. This slows down the time to use and makes everything feel sluggish. When a dependent package is modified or removed, it has the potential to disrupt enormous amounts of deployed software. There is a perception among casual observers that WebAssembly is an assault on JavaScript, but that simply is not the case. Sure, you will be able to avoid JavaScript if you want to, but it is mostly about giving you options to solve problems in the language of your choice without requiring a separate runtime or having to care what language another piece of software is written in. It is already possible to use a WebAssembly module without knowing how it was built. This is going to increase the lifetime of business value we get out of our software and yet simultaneously allow us to innovate in adopting new languages without impacting everything else. We have experienced several tools, languages, platforms, and frameworks over the course of the past several decades that have attempted to solve these problems, but WebAssembly represents one of the first times we are getting it right. Its designers are not attempting to overspecify anything. They are learning from the past, embracing the web, and applying problem- space thinking to what is ultimately a hard and multidimensional problem. Let’s look at the formative influences on this exciting new technology before we dive into it further. History of the Web There is a running joke in the WebAssembly community that WebAssembly is “neither web nor assembly.” While this is true on some levels, the name 6 7
📄 Page
17
is suggestive enough of what it provides. It is a target platform with a series of instructions that are vaguely assemblyesque. The fact that WebAssembly modules are frequently going to be delivered over the web as another type of URL-addressable resource justifies the inclusion of the word Web in the name. One of the main distinctions between “conventional software development” and “web development” is that there is effectively no installation required with the latter once you have a browser available. This is a game-changer in terms of costs to deliver and the ability to quickly turn new releases around in the face of bugs and feature requests. When couched in other cross- platform technology ecosystems such as the internet and the web, it makes supporting multiple hardware and software environments much easier too. Sir Tim Berners-Lee, the inventor of the World Wide Web, worked at the European Organization for Nuclear Research (CERN), where he submitted a proposal for interlinking documents, images, and data in the pursuance of CERN’s larger research goals. Even though the impact is clear in hindsight, he had to advertise his ideas internally several times before he was asked to act on them. As an organization, CERN was represented by dozens of research facilities around the world, which sent scientists with their own computers, applications, and data. There was no real capacity to force everyone to use the same operating systems or platforms, so he recognized the need for a technical solution to solve the problem. Prior to the web, there were services such as Archie, Gopher, and WAIS, but he imagined a more user-friendly platform that was ultimately engendered as an application-level innovation at the top of the internet’s layered architecture. He also took ideas from the Standard Generalized Markup Language (SGML) and made them the basis of the HyperText Markup Language (HTML). The result of these designs quickly became the major mechanism for delivering information, documentation, and eventually application functionality to the world. It did so without requiring the various stakeholders to agree on specific technologies or platforms by defining the 8 9 10 11 12 13 14
📄 Page
18
exchange of standards, and included both how requests were made and what was returned in response. Any piece of software that understood the standards could communicate with any other piece of software that did as well. This gives us freedom of choice and the ability to evolve either side independent of the other. Origins of JavaScript The web’s interaction model is called Hypertext Transfer Protocol (HTTP). It is based upon a constrained set of verbs for exchanging text-based messages. While it was a simple and effective model that was easy to implement, it was quickly seen to be inadequate for the task of interactive, modern applications because of inherent latencies in returning to the server constantly. The idea of being able to send code down to the browser has always been compelling. If it ran on the user’s side of the interaction, not every activity would require a return to the server. This would make web applications dramatically more interactive, responsive, and enjoyable to use. How to achieve this was not entirely clear, though. Which programming language would make the most sense? How would we balance expressive power with shallow learning curves so more individuals could participate in the development process? Which languages performed better than others, and how would we protect sensitive resources on the client side from malicious software? Most of the innovation in the browser space was originally driven by Netscape Communications Corp. Believe it or not, Netscape Navigator was originally a paid piece of software, but the company’s larger interest was in selling server-side software. By extending what was possible on the client, it could create and sell more powerful and lucrative server functionality. At the time, Java was emerging from its beginnings as an embedded language for consumer devices, but it did not yet have much of a track record of success. It was a compelling idea as a simplified version of C++ that ran on a virtual platform and was therefore inherently cross-platform. 15
📄 Page
19
As an environment designed to run software downloaded over the network, it had security built in via language design, sandboxed containers, and fine- grained permission models. Porting applications between various operating systems was tricky business, and the prospect of not needing to do so created a frenzy around what the future of software development would be. Sun Microsystems found itself in the enviable position of having a solution to a perfect storm of problems and opportunities. Given this potential, discussions were underway to bring Java to the browser, but it was not clear what that deal would look like or when it would land. As an object-oriented programming (OOP) language, Java contained sophisticated language features such as threads and inheritance. There was concern at Netscape that this might prove too difficult for nonprofessional software developers to master, so the company hired Brendan Eich to create a “Scheme for the browser,” imagining an easier, lightweight scripting language. Brendan had the freedom to make some decisions about what he wanted to include in the language, but he was also under pressure to get it done as quickly as possible. A language for interactive applications was seen as a crucial step forward for this emerging platform, and everyone wanted it yesterday. As Sebastián Peyrott notes in the blog post, “A Brief History of JavaScript,” what emerged was “a premature lovechild of Scheme and Self, with Java looks.” Initially JavaScript in the browser was limited to simple interactions such as dynamic menus, pop-up dialogs, and responding to button clicks. These were significant advances over roundtrips to the server for every action, but they were still toys compared to what was possible on desktop and workstation machines at the time. The company I worked for during the early days of the web created the first whole-earth visualization environment, involving terabytes of terrain information, hyperspectral imagery, and pulling video frames from drone videos. This required Silicon Graphics workstations initially, of course, but it was able to run on PCs with consumer-grade graphics processing 16 17 18 19
📄 Page
20
units (GPUs) within a couple of years. Nothing like that was remotely possible on the web back then, although, thanks to WebAssembly, that is no longer true. There was simply no confusing real software development with web development. As we have noted, though, one of the nice things about the separation of concerns between the client and the server was that the client could evolve independently of the server. While Java and the Java Enterprise model came to dominate the backend, JavaScript evolved in the browser and eventually became the dominant force that it is. Evolution of the Web Platform As Java applets and JavaScript became available in the Netscape browser, developers began to experiment with dynamic pages, animations, and more sophisticated user interface components. For years these were still just toy applications, but the vision had appeal and it was not difficult to imagine where it could eventually lead. Microsoft felt the need to keep up but was not overly interested in directly supporting its competitors’ technologies. It (rightly) felt that this web development might eventually upend its operating system dominance. When Microsoft released Internet Explorer with scripting support, the company called it JScript to avoid legal issues and reverse-engineered Netscape’s interpreter. Microsoft’s version supported interaction with Windows-based Component Object Model (COM) elements and had other twists that made it easy to write incompatible scripts between the browsers. Its initial support of the efforts to standardize JavaScript as ECMAScript waned for a while and eventually the Browser Wars began. This was a frustrating time for developers and ultimately involved anticompetitive lawsuits against Microsoft by the US government. As Netscape’s fortunes waned, Internet Explorer began to dominate the browser space and cross-platform innovation subsided for a while even as JavaScript went through the standardization process. Java applets became widely used in some circles, but they ran in a sandboxed environment, so it 20 21