Chrome’s NaCl/PNaCl platform runs C and C++ code within a sandboxed environment. It is integrated within the Chrome Extensions/App ecosystem and is well accepted by the developer community.
Unfortunately, other browsers have not been very welcoming of PNaCl/NaCl. As a result, after years of active development, PNaCl/NaCl is now deprecating to embrace WebAssembly.
Welcome to WebAssembly
WebAssembly (Wasm) is an open standard developed by the W3C community group. The group defines the specification for Wasm executable format, which is portable, compact, safe, and executes at native or near-native speeds. In addition, unlike earlier efforts by browser vendors to support a specific language, any language that can be compiled to Wasm format can be executed in that browser.
Modern browsers such as Chrome, Firefox, Edge, and Safari natively support WebAssembly. As a result, WebAssembly will enable computing-intensive applications such as graphics-heavy games and scientific simulations on a web platform.
Several compilers can compile specific languages into Wasm. These include the Go and Rust (with the help of wasm-pack) compilers to create the Wasm binary. Most prominent among them is Emscripten, which compiles C and C++ code into the Wasm format.
Migrate from NaCl to WebAssembly
Choosing a compiler
Though the latest version of Clang can generate the wasm binary, the preferred way is to use Emscripten. Emscripten is a compiler toolchain for C and C++ code targeting WebAssembly and comes with valuable features aplenty. For example, Emscripten can emulate Filesystem if the code uses File IO. You can also change the target to produce asm.js instead of a wasm binary.
Though Emscripten can compile any C and C++ code to WebAssembly, some areas will need fixing,
- If your code uses APIs from PNaCl, you will have to find the closest match in Emscripten or from the libraries.
- Code that uses any platform/architecture-specific code cannot be compiled.
- Code that relies on big-endian architecture cannot be compiled.
- As opposed to Emscripten, PNaCl is based on an older version of Clang. Hence the code that compiles on PNaCl may not compile using Emscripten.
- Developers may also need to fix issues in third-party libraries. There are plenty of libraries that are already ported to Emscripten for direct use.
NaCl is loaded using the embed tag, and postMessage aids the communication between JS and NaCl. In the case of Wasm, if Emscripten is in use, compilation generates glue code that loads the Wasm file. The JS and Wasm layers talk to each other by exposing functions and using flags when compiling to generate the appropriate binary. Then, either layer can directly invoke the exposed functions.
Though Wasm runs at near-native speeds, it may not match the speed of NaCl in all cases for a multitude of reasons. For example, NaCl natively supports Exceptions; however, they are emulated in Wasm. Hence if the code uses Exceptions, it will run slower on Wasm. Emscripten has suggested techniques that should help improve performance. However, peak performance levels may not be possible in many cases. In such cases, profiling the code using Chrome DevTools should help identify areas causing issues.