Open5

WebGL-Native: Duktapeに移植したい

okuokuokuoku

prev: https://zenn.dev/okuoku/scraps/efa3e214ee8348
next: https://zenn.dev/okuoku/scraps/b4b12919554ab0

Duktape

https://duktape.org/

DuktapeはシングルソースのJavaScriptインタプリタで、完全なJavaScriptを実装しつつマイコンのような環境でも実行できるので人気がある。

他にもQuickJSやHermes等組込みJavaScriptエンジン自体には相当量の選択肢があるが、組込みが容易で、かつ、そこそこのパフォーマンスを提供するのでDuktapeを選んだ。というかQuickJSやHermesが割とこの手のインタプリタとしては高速といっても、Duktapeの2〜10倍くらいしか高速でないので、Duktapeで実用的なパフォーマンスが出ないなら他の処理系でも厳しいと考えざるを得ない。

(ちなみにV8のJITは現状の用途だとDuktapeの10〜100倍高速になると考えている -- 良いインライン化があるのが大きい)

okuokuokuoku

DLL読み取り機能の移動

DLLの読み込みのために ffi-napi を使いっぱなしだったので、 ffi-napi のソースコードに含まれるパブリックドメインなWin32向け dlopen 実装を使って自前で持つことにした。

https://github.com/okuoku/cwgl-proto/commit/9cdc729e6e60ce688f63c0088c23fce9b7eaa6a1

これにより、プロジェクトは一切JavaScript的な外部ライブラリに依存しなくなった(正確には async / await のランタイムはfacebookのを使ってるけど)。

基本ライブラリの組込み

... 基本ライブラリをDLLで供給していると、DLLの読み取り機能のために基本ライブラリが使えなくなっちゃうので、基本ライブラリは処理系の NCCC 実装が直に供給することにした。

https://github.com/okuoku/cwgl-proto/commit/98e9fc14fa967b069f54f37d0ffd6492cb744560

okuokuokuoku

特に2Dアプリが遅い

手元のサンプルではDOSbox-xが特に動作速度を守れないレベルで遅くなっていた。VisualStudioのプロファイラで確認してみると、

SDL_UpdateWindowSurfaceRects で時間を喰っているのがわかる。これは(少くとも当時の)Emscriptenでは JavaScript上でビットマップをコピー していて処理量がO(n^2)オーダとなっているため、インタプリタでは劇的に遅くなってしまう。

まぁこれに関してはWebGLを使ってねということで。。

okuokuokuoku

めも

  1. https://duktape.org/api.html#duk_push_current_function duk_push_current_function の存在に気付くのに小一時間掛かった。コンテキストオブジェクトへのポインタをJavaScript的なクロージャに覚えさせるために function(){}[0] = context 的に使っている。
  2. リファレンスページのページ内検索を . で始めると必ずリファレンスがヒットするようになっているのがかしこい。CSS的に隠すことで実現している。
<a href="#duk_push_c_function"><span class="hidechar">.</span>duk_push_c_function()</a>