LambdaでWebAssemblyを動かす

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

少し前の話になりますが、AWS Lambdaのアップデートで Node.js v8.10 が利用できるようになりました。

Node.jsは v8.0.0 からデフォルトでWebAssemblyが動くようになっているので、AWS Lambdaでもいけるんじゃない?と思い試してみました。

今回はWebAssemblyを使ったHello World的なLambdaを作成してみます。

検証環境

  • macOS Sierra 10.12.6
  • Emscripten: 1.38.5

WebAssemblyを作成する

最近は様々な言語がWebAssembly化に対応していますが、今回はC++とEmscriptenの組み合わせで試します。

まず、ソースを用意します。

#include <string>
#include <emscripten/bind.h>

using namespace emscripten;

val hello_message()
{
    return val(std::string("Hello from WebAssembly!"));
}

// エクスポート設定
EMSCRIPTEN_BINDINGS(hello) {
    function("hello_message", &hello_message); // hello_message 関数を呼び出せるようにする
}

次に、Emscriptenでビルドします。

$ em++ -std=c++14 -s WASM=1 -s MODULARIZE=1 --bind -o hello-wasm.js hello-wasm.cc

ビルドが成功すると、下記のファイルが生成されます。

  • hello-wasm.js
    • WebAssemblyを読み込んで使えるようにするためのグルーコード
  • hello-wasm.wasm
    • WebAssembly本体

ビルドしたものが動作するかREPLで試してみましょう。

$ node
> const wasm = require('./hello-wasm.js')();
undefined
> wasm.hello_message();
'Hello from WebAssembly!'

ソースに書いたとおりのメッセージを取得できました。WebAssemblyが用意できたのでAWS Lambdaに組み込んでみましょう。

Lambda functionを作成する

Lambda function自体の作成手順は下記エントリを参照してください。

index.js を用意します。

const wasm = require('./hello-wasm.js')();

exports.handler = async (event) => {
    const msg = wasm.hello_message();
    console.log(msg);
    context.done(null, msg);
};

ファイル一式をzipファイル化してアップロードしましょう。

$ zip -r hello-wasm.zip index.js hello-wasm.js hello-wasm.wasm
  adding: index.js (deflated 26%)
  adding: hello-wasm.js (deflated 77%)
  adding: hello-wasm.wasm (deflated 50%)

ファイル一覧に WebAssemblyが含まれていることを確認できました。次は実際に動かしてみましょう。

動かしてみる

テスト実行で動作させてみます。今回はイベントの内容を参照しないです。任意のイベントがあれば選択してください。無い場合は Hello World テンプレートでイベントを新規作成してください。

Testボタンを押して実行します。

実行結果に、WebAssemblyから取得したメッセージが表示されていますね!

おわりに

AWS Lambda上でWebAssemblyを動せることを確認できました。WebAssemblyを活用すると、 既存の資産やNPMで用意されていないライブラリも扱うことができそうです。出来ることの幅がより一層広がりそうなので、色々試してみたいと思います!