👋

QuickJSをWASI p1で動かしてみる

2025/02/08に公開

はじめに

QuickJS(HP, GitHub)はCで実装されている軽量な(1MBくらいの)JavaScript Runtime。
QuickJSのWASM関連プロジェクトでいうと、WASM空間でJSをサンドボックス実行できるquickjs-emscriptenが有名だが、せっかくならローカルや他言語からでも動かせる[1]WASIで動かしたい。
ということでqjsのWASIビルドを調べてみた。

ちなみにQuickJSがWASM/WASIで動くと何が嬉しいかというと

  • サンドボックス環境で動かせる(通信やファイルアクセスを制約できる)
  • ファイルIOが抽象化されているのでモジュール含め実体のファイルが無い場合も簡単に実行できる
  • 他言語からの呼び出しが簡単に出来る
  • 任意のCPU・OSで動かせる

みたいなところがあると思っている。
(これらのメリットは別にquickjsに限らず、WASM/WASI全般の強みだが...)

検証手順

特別なところがあるわけではないので、検証でやった手順を一通りメモしておく。

環境構築

WASMモジュールの中身確認

WASM AnalyzerでWASMモジュールを解析してみる。

WASIはWASIでもWASI p1対応っぽい(つまりComponentではない)
imports
exports

REPL

wasmtime qjs-wasi.wasmからREPLを立ち上げる。

> wasmtime qjs-wasi.wasm
QuickJS-ng - Type ".help" for help
qjs > a = 1
a = 1

1
qjs > 1
qjs > b = 2
b = 2

2
qjs > 2
qjs > a + b
a + b

3
qjs > 3
qjs > console.log("hello")
console.log("hello")
hello

hello
undefined
qjs > undefined

スクリプト実行

jsファイルを実行する。

ファイルツリー
└ examples
  ├ test.js
  └ test2.js
test.js
export function hello_world() {
    console.log("Hello, world!");
};
test2.js
import { hello_world } from "./test.js";

let test = "Hello from test2";
console.log(test);
hello_world();
結果
>wasmtime --dir ./examples::/ qjs-wasi.wasm -m /test2.js
Hello from test2
Hello, world!

感想

WASMをやってみたいと思って苦しむのは大体ビルドのところなので、バイナリが配布されていると楽で良いな~という感想だった。
Componentにも対応してくれるとありがたいな~と思ったり…
後はPythonとかから呼び出してみたい。

脚注
  1. emscriptenは実行にnodeやブラウザといった何らかのJS環境が必要...な認識なのだがあってるよね? ↩︎

Discussion