WebAssembly

11.18

介绍

WebAssembly 是一种底层编译型的语言,也是一种二进制指令格式。它被设计成可以作为 C/C++/Rust 的编译目标。从而使这些语言也可以用来做 web 开发。

  • 高效和快速

    二进制,充分利用硬件

  • 安全

    运行在沙箱环境

  • 开放和可调试

    源码提供了文本化的格式

  • Web 平台的一部分

    和 JavaScript 紧密结合

概念

WebAssembly 和 web 平台的融合

web 平台可以看作一下两部分

  • 运行代码(app)的虚拟机(virtual machine)
  • 代码(app)可以调用的 Web APIs

面临的问题:当处理 3D 游戏、虚拟和增强显示、计算机视觉、图片和视频编辑等,会遇到性能问题。另外,大型 JavaScrip 应用下载和运行开销比较大。

解决方案:WebAssembly 设计为 JavaScript 的补充。JavaScript 是高阶语言,更灵活。WebAssembly 是低阶语言,性能更好。两者以接口或模块的形式互相调用,存在于一个虚拟机中。

核心概念

  • Module:被浏览器编译后的可执行的机器码。像 ES2015 module 一样有导出和导入。

  • Memory:大小可变的 ArrayBuffer,包含了 WebAssembly 可以获取的字节数据。

  • Table:大小可变的 typed array,包含了函数等的引用。

  • Instance:包含运行时的状态的 Module。类似于一个已经被导入实例化的 ES2015 module。

JavaScript 可以完全控制下载、编译和运行 WebAssembly。可以把 WebAssembly 看成是 JavaScript 提供高性能函数的一个特性。

将来,WebAssembly 的模块能直接方便地以<script type="module">的形式使用。

如何使用 WebAssembly

WebAssembly 主要提供了一种二进制码以及加载和使用这些二进制码的接口。那么如何在实际中使用呢?

编译 C/C++

在线编译器

Emscripten

Emscripen 是基于 LLVM 来编译 C/C++ 的工具。文档:https://emscripten.org/index.html

安装

以 Linux/MacOS 源码安装为例

# Get the emsdk repo
git clone https://github.com/emscripten-core/emsdk.git

# Enter that directory
cd emsdk

# Download and install the latest SDK tools
./emsdk install latest

# Make the "latest" SDK "active" for the current user. (writes ~/emscripten file)
./emsdk activate latest

使用

Tutorial

# Navigate to the emscripten directory under the SDK
cd emsdk/upstream/emscripten

hello_world.c

#include <stdio.h>

int main() {
    printf("Hello, world!\n");
    return 0;
}
# Compiles c 
# Output: a.out.js, a.out.wasm
./emcc /path/to/hello_world.c

# Run output
node a.out.js

# Html with embedded JavaScript and wasm
# Output hello.html, hello.js, hello.wasm
./emcc /path/to/hello_world.c -o hello.html

# Start a HTTP server, then open browser in `http://localhost:5000/hello.html`
serve
📖