提起 WebAssembly/Wasm 可能会想起它是一种可以在浏览器里运行 C/C++/Rust 的技术,实际上它是一个虚拟机标准,它的实现可以在 MCU(单片机)、移动设备、桌面电脑到服务器里面跑,可以嵌入到浏览器、嵌入到应用程序或者独立运行,没有具体的边界。
特点:
- 编译一次到处可运行(有点类似JVM虚拟机),源语言可以是 C/C++,Rust,Go,Swift ,TypeScript,C#,Kotlin 等等。
- 具体的功能依赖于导入的接口(Import API),否则只是一个单纯的运算器(栈式虚拟机)。目前接口主要有 Web JS 和 WASI 两种,前者用在浏览器里,后者可以作为独立应用程序(比如调用文件系统、socket 等)。
- 在 WASM 虚拟机里,只能调用宿主导入的方法和共享的内存,无法直接调用宿主的资源(比如 Web DOM 对象、文件系统等),所以天然具有沙盘安全特性。
- 性能很好,提供了接近本地程序的性能,同一段简单的 C 计算程序,以 WASM 方式运行大概慢 1 倍左右,相对一般动态语言慢几倍到上百倍来说,性能已非常突出。
- 可以很好地把丰富的 C/C++ 资源库移植到 Web,如一些图片、视频、音频等处理程序。
页面内容不多,基本上每行都要仔细阅读,有个总体的印象。
页面左侧的 Guides/How to 要看,跟着动手做一做,右侧的是浏览器 WebAssembly 名称空间内的几个主要对象的介绍,看介绍文字即可,不用深入。
-
编译工具 Emscripten
-
本地静态文件 Http/Web 服务程序
http-server(nodejs) 或者 httpserver (python)
-
浏览器
Chrome/Edge, Firefox, Safari
Emscripten 工具常有变化,且有怪脾气:
-
emcc some.c // 默认输出 a.out.js, a.out.wasm
emcc some.c -o some.js // 输出 some.wasm 和 some.js
emcc some.c -o some.html // 输出 some.html, some.wasm 和 some.js能得到在浏览器运行的目标文件(*.wasm),但无法使用 WebAssembly.instantiate() 方法实例化, 编译时需要添加 (-O2 或 -O3 或 -Os) 参数。
-
emcc some.c -o some.wasm
输出 STANDALONE_WASM 类型的 wasm,在浏览器中无法直接加载和实例化,使用 wasmtime 或者 wasm3 等工具运行。
实测添加 (-O2 或 -O3 或 -Os) 和 (-s SIDE_MODULE=1) 参数编译的 STANDALONE_WASM 类型能在浏览器加载,如 emcc some.c -Os -s WASM=1 -s SIDE_MODULE=1 -o some.wasm
-
-s 参数意义 https://github.com/emscripten-core/emscripten/blob/master/src/settings.js
-
-O 参数意义 https://emscripten.org/docs/tools_reference/emcc.html#emcc-os
-
emcc 可以加参数 -std=c99/c11/c++11
- https://webassembly.org/getting-started/js-api/
- https://github.com/mdn/webassembly-examples/tree/master/js-api-examples
- https://ihsavru.medium.com/calling-javascript-code-from-c-c-using-webassembly-a9445c11bc6d
- https://ihsavru.medium.com/loading-webassembly-modules-in-javascript-dc09fbd5eac2
- https://wasi.dev/
- https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md
- https://v8.dev/blog/emscripten-standalone-wasm#using-standalone-mode-in-emscripten
如果虚拟机的 Host 提供了 filesystems, sockets 等导入,WebAssembly 也能像一般的本地程序般运行。
文本 wat 到 wasm 到 c 之间的转换
https://github.com/webassembly/wabt
-
《Learn WebAssembly: Build web applications with native performance using Wasm and C/C++》 Mike Rourke
-
《深入浅出 WebAssembly》于航
内容全面,想深入学习 原理 方面的可以阅读
-
《WebAssembly标准入门》柴树杉,丁尔男
想 钻研 WebAssembly 汇编语言的可以阅读