世界を動かす技術を、日本語で。

Asm.jsとのお別れ

概要

  • Firefox 148以降、 SpiderMonkeyのasm.js最適化 がデフォルトで無効化
  • asm.jsコード自体は 通常のJavaScriptエンジン で引き続き動作
  • WebAssembly への再コンパイル推奨、パフォーマンス向上
  • asm.jsの歴史と WebAssembly誕生 への影響
  • asm.jsコンパイラOdinMonkeyの役割終了と新体制

Firefoxにおけるasm.js最適化の終了

  • Firefox 148 以降、SpiderMonkeyの asm.js最適化機能 がデフォルトで無効化
  • asm.jsコードは 通常のJITコンパイラ で実行、動作に支障なし
  • asm.jsは JavaScriptの厳格なサブセット、特別な環境不要
  • WebAssembly への再コンパイルで 高速化・バイナリ縮小 が可能
  • asm.js最適化コードは将来的に 完全削除予定

asm.jsの歴史と功績

  • asm.jsは Mozilla による NaCl/PNaClへの回答 として誕生
  • 厳格で静的型付けされたJavaScriptサブセットの採用
  • ネイティブコード並みの速度 でWeb上での実行を実現
  • 2013年Firefox 22 で実装、UnityやUnrealなどの C/C++コード資産のWeb移植 を促進
    • 例: Epic Citadelデモ がわずか4日でWeb移植
  • asm.jsの成功が WebAssemblyの開発・実現 に繋がる
  • asm.jsなしでは WebAssemblyの誕生はなかった という評価

なぜ今、無効化なのか

  • WebAssemblyの普及 により、asm.js利用はほぼ移行済み
  • 並行サポートは 保守コスト増加セキュリティリスク の要因
  • asm.jsを利用中の開発者には WebAssemblyへの移行 を強く推奨
  • WebAssemblyパイプラインは asm.jsより高性能・高効率

OdinMonkeyからBaldrMonkeyへ

  • asm.jsコンパイラ OdinMonkey の役割終了(Ragnarök)
  • Twilight of OdinMonkey」としてバグトラッキング
  • OdinMonkeyの後継として BaldrMonkey (WebAssembly最適化コンパイラ)が誕生
    • RabaldrMonkey (WebAssemblyベースラインコンパイラ)とともに新体制
  • OdinMonkeyの 13年間の貢献 に感謝と惜別
  • 北欧神話になぞらえた 新時代の幕開け

今後の推奨対応

  • asm.jsコンテンツ提供者は WebAssemblyへの再コンパイル を検討
  • 高速化・バイナリ縮小・保守性向上 のメリット
  • Mozillaコミュニティによる 継続的な進化 への期待

Hackerたちの意見

俺の計画、ランタイムでjsコード生成してアルゴリズムを速くするってやつがダメになった。wasmでやるのはもっと大変だな。

まだAssemblyScriptがあるの?要件を満たすかもしれないけど、俺が勘違いしてるか、機能を理解してないかも。 https://www.assemblyscript.org/

ブラウザで動かすための小さくて速いWATコンパイラがいくつかあるよ。

まだ動くよ。asm.jsは結局普通のJavaScriptコードだからね。ただ、asm.js用のカスタムパイプラインほど速くはパース/実行できないだけ。俺の予想だと、本当に大きなアプリじゃない限り、あんまり違いは感じないと思う。

asm.jsのサブセットを試してみて、どんな感じか見てみて。特別なasm.jsサポートがブラウザに無くても、Emscriptenの出力パフォーマンスは意外と良かったのを覚えてるよ。

実行時にwasmコードを生成するのは結構簡単だよ(有効なasm.jsコードを生成するよりも簡単だと思う)。テスト用にちょっとしたライブラリがあって、これが多くを処理してくれるんだ: https://searchfox.org/firefox-main/source/js/src/jit-test/li...

asm.jsは終わった!WebAssembly万歳!

正直言うと、数年前にWASMの登場でasm.jsは廃止されたと思ってた。

Gary BernhardtのJavaScriptに関するトークを見たのは忘れられない。[0] それがasm.jsとの出会いで、ブラウザでコードをコンパイルするためのラビリンスに入るきっかけだった。12年経った今、彼のフィクションがどれだけ現実になったか、驚きだよ。[0] https://www.destroyallsoftware.com/talks/the-birth-and-death...

AIの台頭がなければ、WASMが全ての言語のためのマシンレベルのコンパイルターゲットとして実現していた可能性もあるね。ゲイリーが予測した以上に、AIの登場は見えてなかったんだ。

ついにasm.jsの死が来たのか?予言のタイムラインから離れていってるな。 https://www.destroyallsoftware.com/talks/the-birth-and-death... (これにまだ出会ったことがない人には、ぜひ見てほしい。間違いなく、史上最高のテックトークだと思う。)

この技術の終焉で、予言の糸が断たれた。セーブデータを復元して運命の織りを取り戻すか、作り出した運命の世界に留まるか。

心配しないで、YavaScriptは永遠に生き続けるから。

asm.jsをWASMに置き換えれば、まだ正しい道を進んでるよ。

あのプレゼンテーションは年に2、3回見返すんだ。プレゼンの仕方や、スライドデッキの構成の仕方、オペレーティングシステムの権限リングアーキテクチャについての驚くほど教育的なツアーの素晴らしい例だからね。いつか戦争の時代が来て、古いプログラミングパラダイムへの心理的な執着が解放されて、もっと進んだやり方に移行できるようになると思う(でも、あなたの銀行がYavaScriptを動かすのはあと85年は止まらないだろうけど)。

戦争をCOVIDに置き換えたら、2020年に起こったことだから、そんなに遠くないよね。真実がわかるのは2035年まで待たなきゃいけないけど。

個人的にはこれは間違いだと思う。でも、どれだけ重要かはわからない。俺の知る限り、まだasm.jsを使ってる人は少ないし。でもwasmはJavaScriptからはあまりにも孤立してる。俺の限られた使い方では、むしろasm.jsにコンパイルしようか考えてたけど、emscriptenがまだ完全にサポートしてるかはわからなかった。wasmからはほとんどのWeb APIを呼び出せないし。でも、俺がやろうとしてたことにとってもっと重要なのは、jsからwasmにゼロコピーのバッファを渡せないこと。すべてはトレードオフだよ。孤立はいい面もあるけど、悪い面もある。

でも、wasmはjavascriptからあまりにも孤立してるね。自分の限られた使い方では、asm.jsにコンパイルしようか考えてたけど、asm.jsはwasmよりもJSとのインタラクションが厳しく制限されると思う。基本的に、単純な数値や配列バッファに制限されちゃう。今のwasmはGCタイプもあって、externrefを使ってJSの値を保持できるから。 > でも、私がやろうとしてたことにとってもっと重要なのは、JSからwasmにゼロコピーのバッファを移動できないこと。asm.jsでもそれはできないと思う。wasmでのゼロコピーのバッファに関する提案があるよ: https://github.com/WebAssembly/memory-control/blob/main/prop...

もしかしたら誤解してるかもしれないけど、asm.jsにも同じ制限があるんじゃない?つまり、asm.jsのコードから直接ウェブAPIを呼び出すことはできないし、「外部」関数のためには特別な処理が必要だよね。

確か、Emscriptenは2020年頃にasm.jsのサポートを削除したと思う。それがasm.jsをサポートしていた最も重要なツールチェーンだったんじゃないかな(Rustも続いてたかもしれないけど、今もサポートしてるかはわからない) > WASMからはほとんどのウェブAPIを呼び出せないよ。厳密なasm.jsからも呼び出せないし、asm.jsは数値だけをサポートしてるから(JSの文字列やオブジェクトはなし)、CヒープをArrayBufferオブジェクトで管理してるのはWASMと同じだよ。 > でも、俺がやろうとしてたことにはもっと重要なことで、jsからwasmにバッファをゼロコピーで移動できないんだ。上の問題と同じで、asm.jsから「本物」のJavaScriptを呼び出さなきゃいけないし、他のArrayBuffersを「asm.jsヒープ」に直接マッピングすることもできないから、コピーが必要なんだ。asm.jsとWASMの「JavaScript FFI」はあまり変わらないよ。

うーん、asm.jsからWASMへのトランスパイラーが必要かも。古いバージョンのEmscriptenでレガシーコードをコンパイルするのはかなりイライラするし、EmscriptenのABIの変化に合わせてJSコードを更新するのも同じくらい面倒だよね。

Binaryenには昔asm2wasmツールがあったけど、今はもう使われてないと思う。他に同じようなものは見つからなかった。少なくともasm.jsのコードは、asm.jsのオプションを無効にしても動き続けるけど、翻訳ツールがあればいいのに。

asm.jsはMozillaがNaClとPNaClの問いに対する回答だった: ウェブでネイティブスピードでコードを実行するにはどうすればいいのか?もし今だったら、ChromeはNaClとPNaClを何が何でも推進して、みんなが「Web」スタンダードに追いついてないSafariやFirefoxに文句を言うだろうね。

俺はまだ、間違ったタイムラインにいるって思ってる。PNaClが死んで、代わりにちゃんとした後継が出てくる代わりに、Electronアプリのスープに生きたまま煮られてる感じ。しばらくの間、ブラウザ内で全てをやる時代が来ると思ってたんだ。でも、ある意味それはどんどん現実になってるけど、なんか前よりも悪化してる気がする。WASMは好きだし、もっと好きになりたいけど、エコシステムの成熟度が信じられないくらいひどい。もっと悪いのは、みんなが信頼できないAIツールとその出力を、まさにそんなサンドボックスで動かすべきなのに、企業は逆のことを売ってるってこと。ホスティングされたサンドボックスや、ホスティングされたJSベースのVMをね。結局、クライアントサイドのサンドボックスにはお金がなかったのが問題だったんだろうね。

まあ、当時彼らがやろうとしていたことは基本的にそれだよね。ウェブ標準委員会を通して進めようとしてたし。確か、うまくいかなかった大きな理由は、NaClが「大きな」技術で、asm.jsが「小さな」技術だったから、asm.jsが数年遅れて始まったにもかかわらず、先に製品化に至ったんだよね。

つまり、Chromeがそれを推進して、Appleはコメントを拒否してフィリバスターするってこと?(WebKitチームへの投資がないからね)それで、ネットの中のお人好しな人たちが彼らに従うって感じかな。最近のAppleは規制問題が本格化してからWebKitへの投資を増やしてるみたいだから、今なら結果が違ったかもしれないね。

それは悲しいけど、納得できるね。面白い事実として、Figmaはもともと完全にC++のコードベースから始まったんだ。Asm.jsはブラウザでデザインツールを動かすことが可能だって証明するのに重要だった。WebAssemblyへの移行は、支払いをする顧客ができてからで、ロード時間の改善もあった(Asm.jsはまだJSだから、バンドルサイズが大きくて、コードをASTにパースする必要があるけど、WASMとは違うんだ)。

それが悲しいことなの?一時期は意味のあるコンパイルターゲットだっただけだよ。i386-unknown-freebsd1が廃止されたことに悲しむようなもんだね。

それが悲しいのは、クリーンでネイティブなデスクトップ用Figmaアプリが手に入ったはずなのに、ってことだよね。

Asm.jsがいいのは、シムを使わずにウェブAPIを直接呼び出せるってことじゃない?データの入出力も簡単だし。WebAssemblyに完全に移行したいけど、まだ制限が多い気がするんだけど、俺が間違ってるのかな?

WasmもウェブAPIを直接呼び出せるよ。聞くところによると、複雑な型(ネストされた辞書とか)をフォーマット間で変換するのがオーバーヘッドになるらしい。でも、wasmはJSランタイム内で動くからね。

ウェブAPIについて何を指しているかによるよ。例えば、Fetch APIはasm.jsのJavaScriptのサブセットには含まれてないから、どちらの場合でもJavaScriptのシムが必要になるよ。でも、兄弟のコメントが言ってるように、大きな構造間の変換からオーバーヘッドが来るんだ。

ずっと前に、WebGLの本でasm.jsについて小さな章を書いたことがあるんだ。https://webglinsights.github.io/ asm.jsの台頭を見るのは楽しかったし、WebAssemblyの前身だったからね。初期のデモは本当にクールだった;ブラウザで動くUnreal Engineとか。:) ここで日の入りを見るのはちょっと切ないけど、でもそれがより良いものにつながったんだよね。