WebAssembly技术
——从C/C++到Javascript之路
- 案例描述
随着对无插件预览性能要求的越来越高,原来的Emscripten asm.js技术已显不足,但目前一种新技术——WebAssembly正日趋成熟,WebAssembly可以将低级别编程语言(包括C和C++)编译成二进制字节码,可以较大的提升浏览器的性能。
- 案例分析和解决
WebAssembly作为一种新兴的Web技术,正在快速演变中,Google、苹果、微软和Mozilla的正在联合开发WebAssembly。WebAssembly(wasm)是一种可用于浏览器中的字节码(bytecode),可使浏览器性能提升20倍。字节码是一种机器可读的指令集,与脚本语言相比,字节码的加载速度更快。WebAssembly项目旨在开发全新的字节码,从而让桌面和移动端浏览器变得更高效。使用WebAssembly,我们可以在浏览器中运行一些高性能、低级别的编程语言,可用它将大型的C和C++代码库比如游戏、物理引擎甚至是桌面应用程序导入Web平台。截至目前为止,我们已经可以在Chrome、Firefox中使用WebAssembly,Edge和Safari对它的支持也基本完成。
- WebAssembly编译环境配置
我们使用 Emscripten 将 C 代码编译为 wasm 格式,官方推荐的方式是首先下载 Portable Emscripten SDK for Linux and OS X (emsdk-portable.tar.gz) 然后利用 emsdk 进行安装:
$ git clone https://github.com/juj/emsdk.git $ cd emsdk $ ./emsdk install latest $ ./emsdk activate latest $ source ./emsdk_env.sh --build=Release |
新版Emscripten已经包含了-s WASM=1编译选项,通过该选项可以将C/C++代码直接编译成wasm文件。
除此之外,我们还可以通过官方提供的另外两个工具将.js文件转换成.wasm,工具分别为Binaryen和WABT (WebAssembly Binary Toolkit),安装方法可参考官方 Developer’s Guide 和 Advanced Tools。
虽然Emscripten能生成asm.js和wasm,但是却不能把asm.js转成wasm。因为它是基于LLVM的,然而asm.js没法编译成LLVM IR (Intermediate Representation)。想要把asm.js编译成WebAssembly,就要用到官方提供的Binaryen和WABT (WebAssembly Binary Toolkit)工具了。原理和编译方法参考官方文档,整个过程如下:
Binaryen WABT math.js ---> math.wast ---> math.wasm |
用脚本描述如下:
$ asm2wasm math.js -o math.wast $ wast2wasm math.wast -o math.wasm |
- 如何将C/C++代码编译成.wasm
使用C语言来编写WebAssembly模块,并将其编译成.wasm文件。这些.wasm文件并不能直接被浏览器识别,所以它们需要一种称为JavaScript胶接代码。
首先编写一段C代码,保存为test.c,代码如下