色々な Javascript Engine で遊んでみた。意外とエンジンごとに特徴があった。
比較
Javascript Engine | ビルド時間(かなり良い Ubuntu 16.04) | 実行ファイルの大きさ | シェル起動後のメモリサイズ (VmHWM) | 感想 |
---|---|---|---|---|
V8 (Google) | 61 分 | 17M | 13040 kB | ビルドが面倒くさい |
SpiderMonkey (Mozilla) | 12 分 | 209M | 16804 kB | バイナリサイズが大きい |
JerryScript (Samsung) | 5 秒 | 218K | 4kB | Javascript が古いがメモリが少ない |
Duktape | 4 秒 | 308K | 1088kB | 楽 |
V8
Getting Started: https://github.com/v8/v8/wiki/Getting%20Started%20with%20Embedding
に書いてある事をなぞってみる。V8 は depot_tools とか言う特殊なツールでダウンロードやビルドを行うので、ちょっとややこしい。
ソースコードのダウンロード
depot_tools のダウンロードと PATH 設定
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
$ export PATH=`pwd`/depot_tools:"$PATH"
Google Source にログイン。Configure Git に行って適当なアカウントでログインし、コマンド文字列をシェルにコピペする。
以下のコマンドでインストールが上手く行ったか確認。
$ gclient
v8 のダウンロード (2 - 3 分)
$ fetch v8
$ cd v8
サンプルのバージョンに合せる
$ git checkout -b 5.8 -t branch-heads/5.8
ビルド設定
$ tools/dev/v8gen.py x64.release
ビルド設定を編集するために以下実行
$ gn args out.gn/x64.release
エディタが起動するので、以下修正追加
is_component_build = false
v8_static_library = true
ビルド (一時間)
$ ninja -C out.gn/x64.release
テスト
samples/hello-world.cc にサンプルがあるのでビルド。同様に samples/shell をビルドすると REPL が出来る。
$ g++ -I. -Iinclude samples/hello-world.cc -o hello-world -Wl,--start-group \
out.gn/x64.release/obj/{libv8_{base,libbase,external_snapshot,libplatform,libsampler},\
third_party/icu/libicu{uc,i18n},src/inspector/libinspector}.a \
-Wl,--end-group -lrt -ldl -pthread -std=c++0x
スナップショットファイル (natives_blob.bin, snapshot_blob.bin) と ICU ファイル (icudtl.dat) を実行ファイルの場所にコピー
$ cp out.gn/x64.release/*.bin .
$ cp out.gn/x64.release/icudtl.dat .
サンプルプログラムを実行
$ ./hello-world
Hello, World!
特徴
- 実行サイズの大きさ: 17M
- shell 起動直後のメモリサイズ: VmHWM: 13040 kB
宿題
- bin ファイル、ICU ファイルとは何か?
- hello-world.cc の中身を変える。
- v8 に機能を追加する。
SpiderMonkey
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Build_Documentation を元に作業
依存ツールインストールとソースコードのダウンロード
sudo apt install -y autoconf2.13
git clone --depth 1 https://github.com/mozilla/gecko-dev.git
cd gecko-dev/js/src
ビルド (12 分)
autoconf2.13
mkdir build_OPT.OBJ
cd build_OPT.OBJ
../configure
make
起動
$ ./js/src/shell/js
js> print("hello world!")
hello world!
特徴
- 実行ファイルの大きさ: 209M
- js 起動直後のメモリサイズ: VmHWM: 16804 kB
JerryScript
ダウンロード
git clone https://github.com/jerryscript-project/jerryscript.git
cd jerryscript
ビルド (5秒)
python tools/build.py
実行
./build/bin/jerry
特徴
- 実行ファイルの大きさ: 218K
- シェル起動直後のメモリサイズ: 4kB
Duktape
ダウンロード
$ wget http://duktape.org/duktape-2.1.0.tar.xz
$ tar xJvf duktape-2.1.0.tar.xz
$ cd duktape-2.1.0
ビルド (4秒)
$ make -f Makefile.cmdline
実行
$ ./duk
特徴
- 実行ファイルの大きさ: 308K
- シェル直後のメモリサイズ: 1088 kB
おまけ。Javascript の機能がどの仕様で定義されているか?
Javascript では。最初から幾つかの関数やオブジェクトが使える。それらの機能がどの仕様で定義されているのか調べてみた。
- ECMAScript で定義されている機能
- 18 The Global Object で Ecmascript のグローバルオブジェクトが定義されている。
- decodeURI などの歴史的関数
- Array, Set などの基本オブジェクト
- JSON, Math などのユーティリティ
- V8 では https://github.com/v8/v8/blob/master/src/bootstrapper.cc#L4191 あたりで登録している。
- WHATWG で定義されている機能
- 非常にわかりにくいが https://spec.whatwg.org/ から辿れるページに分割されて書かれている。
-
7.3 The Window object
- window, history, navigator 等のブラウザ操作関数
-
8 Web application APIs 特に 8.2 The WindowOrWorkerGlobalScope mixin
- btoa などの歴史的関数
- setTimeout などのタイマ
- createImageBitmap などの置き場所に困った雰囲気の関数。
- Notifications, Console, XMLHttpRequest などは独立した文書になっている。
- node.js が定義している機能
- https://nodejs.org/api/ にわかりやすく定義されている。
他の javascript エンジン
- ChakraCore (Microsoft) https://github.com/Microsoft/ChakraCore