Chapter 5 · 14 July – 17 September

Raku in a browser tab

The interpreter is portable C++ with no dependencies, and that is exactly what compiles to WebAssembly. Twelve days after the first commit, Raku++ ran in a browser tab with no server behind it. It was the same interpreter, not a port. Two months later a second route to the browser followed: Raku compiled to JavaScript.

14 JulRaku.js: the interpreter built with Emscripten, running in a Web Worker
≈ 2 MBthe engine gzipped (7.5 MB raw)
1.3–6.8×the WebAssembly tax against native, on a clean host
65 msfib(29) compiled to JavaScript, against 297 ms interpreted
The turnNothing in the engine's source was changed for the browser: the WebAssembly build only adds an entry point, a build script and an editor. Because it is the same engine, its semantics are the ones Roast checks. That is what lets every example on this site run live.

Raku.js

Three choices in the build were measured, not assumed:

Recursion depth is the browser's real limit. A plain recursive sub reaches 58 levels in a Chrome worker and 115 on Chrome's main thread; in Safari, 32 and 419. When a worker's stack overflows, the run is retried on the main thread.

The tax for running in WebAssembly is 1.3× to 6.8× against the native binary, depending on the program. Even so, the WebAssembly engine's big-integer kernel (41.7 ms under Node) outran native Rakudo on the same kernel (258.9 ms) when it was measured.

Raku as JavaScript

On 3 September a proposal to retire Rakudo's own JavaScript backend cited Raku++ in the browser. The same week, Raku++ gained --target=js: a second code generator whose output is JavaScript source rather than C++. It trades completeness for speed, size and access to the host. What it cannot compile falls back to the WebAssembly engine. Anything that parses at run time, such as EVAL, stays WebAssembly-only for good.

Things that broke on the way