ブラウザから機械語を実行できるWebAssembly用のオンライン開発環境「WebAssembly Studio」を使ってみた
「WebAssembly」は、C言語などで書かれたソースコードをコンパイルして生成されていて高速に処理できる機械語をブラウザで実行できるようにする技術です。Firefoxを開発するMozillaは2018年4月11日、そのWebAssemblyを簡単に開発できるようにするオンライン開発環境「WebAssembly Studio」を公開しました。
WebAssembly Studio
https://webassembly.studio/
ブラウザで何か処理を行いたい場合によく使用されるのが「JavaScript」ですが、JavaScriptはコードを一行ずつ処理するインタプリタ言語であり、また変数の型をインタプリタが解釈する動的型付けを行う言語でもあるため、処理速度が遅いという問題点を抱えています。「WebAssembly」はそのような事情を背景に生み出された技術で、ブラウザ上で高速に動作するという特徴があります。
そして「WebAssembly Studio」は、CやRustのコーディングやWebAssemblyへのコンパイル、そして生成された機械語の実行などをブラウザ上で簡単に行えるツールです。面倒な開発環境構築などが一切不要なのですぐに使用できるということで、実際に使ってどういう機能があるのか確かめてみました。
公式のチュートリアルがYouTubeから視聴でき、使用方法を学ぶことができます。
Introducing the WebAssembly Studio Beta - YouTube
WebAssembly Studioのサイトへアクセスすると、プロジェクト作成画面になります。「Empty C Project」を選択して「Create」をクリックします。
プロジェクトを作成すると以下の画面になります。左のカラムからファイルを選択すると右側に表示されるというわけです。
早速「main.c」をクリックして中身を見てみると、「return 42;」とだけ書かれた簡単なコードになっているのがわかります。
また、その下の「main.html」は実行する時に表示するhtmlファイル。「main.js」を呼び出すとだけ書かれています。
そして「main.js」を見てみると「main.wasm」を実行して結果を画面に表示するという内容になっています。
実行する前に機械語へとコンパイルする必要があるので、右上にある「Build」をクリックして「main.wasm」を生成します。「main.wasm」をクリックして表示してみると、機械語ではなくテキスト表現である「wat」形式で表示され、編集できるようになっています。このファイルを編集して保存すると自動で「wasm」形式に変換されて保存されます。
実行ファイルが用意できたので今度は「Run」をクリックして実行してみると、右下に「42」と表示されます。
「main.c」を書き換えて戻り値を「2000」にしてビルドし、実行すると今度は「2000」と表示されます。
また、「main.wasm」を直接編集して「2000」を「10」に変更して実行してみると、きちんと「10」と表示されました。
この「main.wasm」ファイルを右クリックするとさまざまなメニューが表示されます。「To Firefox x86」「To Firefox x86 Baseline」「Binary Explorer」の3つのメニューを試してみます。
まず「To Firefox x86」をクリックすると、「main.wasm.x86」というファイルが生成され、中を見てみると「main.wasm」がx86系プロセッサ用のアセンブリ言語に変換されたものが表示されます。
「To Firefox x86 Baseline」も同様のものが生成されますが、こちらは最適化されておらず、やや長めのコードが表示されます。その分、先ほどのオプションに比べるとこちらの方が変換時間が短いです。
「Binary Explorer」はマシンが実際のバイナリファイルを閲覧できる機能です。「WebAssembly Code Explorer」はブラウザの新しいウィンドウで開かれ、左にバイナリ、右に「wat」形式のコードという表示になっており、それぞれの一部をクリックするともう一方の対応する場所が光って表示されるため関係がわかりやすくなっています。
また、「main.wasm」を右クリックして表示されるメニューから「Optimize」をクリックすると、コードが最適化されて短くなります。
もう一度「To Firefox x86」を実行してみると、生成された「main.wasm.x86」も短くなっていました。
さて、ページの更新ボタンを押すとデータが消えて「Create New Project」の画面に戻ります。今度は「Hello World in C」を選択し、「Create」をクリック。
「main.c」を見てみると、通常の「printf("Hello World\n")」の下に、謎のコードがいろいろくっついているのがわかります。
コンパイルして生成された「main.wasm」を見てみると2000行近くにまで膨れあがっています。
理由を調べるために「main.wasm」を右クリックして「Generate Call Graph」をクリックし、コールグラフを生成します。
生成された「main.wasm.dot」をクリックして表示すると、右側にコールグラフが表示されました。このように、コールグラフにはサブルーチンの呼び出し関係が図示されています。
右の方を見てみると、システムコールがインポートされているのがわかります。
実際の機械で実行するのとは違い、ブラウザからの実行ではカーネルをフルに利用することができないため、このように一部を手動で再実装する必要があるというわけです。
実行すると標準出力に「Hello World」が出力されました。「Hello World」を出力するコードはさまざまな言語で初めて書くプログラムとして選択されやすいですが、WebAssemblyで最初に書くプログラムを「Hello Worldの出力」にするのはやめておいた方が良さそうです。
なお、上の「Fork」ボタンをクリックするとデータがオンラインに保存されます。保存したファイルには「Share」ボタンをクリックすると表示されるURLでアクセス可能です。また、Webページへの埋め込みを行うコードも生成されます。
実際に埋め込んでみるとこんな感じです。「Build」「Run」は埋め込んだページ上で動作しますが、中身を編集する場合は「WebAssembly Studio」に移動する必要があるようです。
また、「Download」ボタンを押すとデータをzipファイルでまとめてダウンロードできます。また、左のメニューの何もない部分を右クリックすることで逆にファイルをアップロードすることも可能となっています。
「WebAssembly」は2016年から2017年にかけて主要なウェブブラウザでサポートされてから普及が進んでいなかった機能ですが、簡単に開発できる環境が提供されたことで本格的な開発が進んでいきそうです。
・関連記事
JavaScriptを補完してウェブを高速化する「WebAssembly」をChromeがついに実装したので実行速度を試してみた - GIGAZINE
「Firefox 52」正式版がリリース、WebAssemblyへの対応がスタートしセキュリティ機能も向上 - GIGAZINE
Google Chrome搭載のJavaScript実行エンジン「V8」でインタプリタ「Ignition」とコンパイラ「TurboFan」がデフォルトで有効に - GIGAZINE
仕事を全自動化して6年間も働かず年収1000万円を得ていたプログラマーが最終的にクビに - GIGAZINE
ドラクエXはこうして作られた、大規模ゲーム開発におけるマネージメント方法 - GIGAZINE
・関連コンテンツ
-
編集部員向けに、画像を自動でGIGAZINEに掲載する時の形式に整えるツールを作成しました。せっかくなので、作り方を記事にしてみました。 画像を変換する方法は多数存在していますが、今回はJavaScriptのライブラリである「sharp」を使用します。 sharp - npm https://www.npmjs.com/package/sharp 最初に開発環境を整えるため、Node.jsをインストールします。Node.jsのダウンロードページで「Prebuilt Installer」をクリックし、「Download Node.js v○○.○○.○」をクリック。 ダウンロードしたmsiファイルをダブルクリックして実行します。 Node.jsのセットアップウィザードが起動するので「Next」をクリック。 ライセンスに同意して「Next」をクリックします。 インストール先のフォルダを確認して「Next」をクリック。 何をインストールするのかを設定できますが、今回は特に何も変更せず「Next」をクリックすればOK。 「Next」をクリック。 「Install」をクリックします。 インストールが完了したら「Finish」をクリックしてインストーラーを閉じます。 続いて必要なライブラリをセットアップしていきます。コマンドプロンプトを起動して「cd」コマンドで作業用のフォルダに移動し、下記のコマンドを入力。 [code]npm init -y npm install sharp@^0.29.3 fs-extra[/code]
エクスプローラーから作業用フォルダ内に「index.js」という名前のファイルを作成し、メモ帳などのテキストエディタで開いて下記のコードを入力します。 [code]const fs = require("fs-extra"); const sharp = require("sharp"); const dirname = process.cwd(); const input = fs.readFileSync(dirname + "/00.png" class="lazyload">