YAPC::Asia 2013に参加しました

YAPC::Asia 2013に参加してきました。今年も大盛況で、処理系の話、大規模サービスの話、ホビープログラミングの話など盛りだくさんで楽しいイベントでした。また今年でlestrrat & 941体制は終了ということです。長い間お疲れ様でした&ありがとうございました!

さて、1日目にLTをしたのでその資料も公開します。当初はPower AssertのPerl実装を考えていたのですが、途中で方向転換したのでpower assertとperl.jsの二部構成になってます。

なおemscriptenについて補足しますと、これマシン語の代わりにJavaScriptを吐き出すC/C++コンパイラで、あらゆるシステムコールemscriptenの提供するJavaScript実装となっています。すなわち、Cの関数をアセンブリで実装できるのと同じ意味で、emscriptenの世界ではCの関数をJSで実装することもできるということです。このようなemscripten libraryはCのヘッダファイルとJavaScriptの実装ファイルからなることになります。

たとえば、以下のようなputs(3)に似た関数を定義するとしましょう。

// mylib.h
extern void my_puts(const char* cstr);

実装は以下の様なJSファイルになります。

// mylib.js
var MyLib = {
	my_puts: function (ptr) {
		var s = '';
		while (HEAPU8[ptr] != 0) {
			s += String.fromCharCode(HEAPU8[ptr]);
			ptr++;
		}
		console.log(s);
	},
};

mergeInto(LibraryManager.library, MyLib);

引数は const char* なので、JSレベルに渡ってくるのはポインタ、つまりメモリ(ヒープ)のある一点を指し示す整数値です。そのポインタをつかってヒープから一文字づつ読みだし、JSの文字列に変換して出力します。JSの構文でC言語を書いていると思うと自然に理解できるかと思います。

試しにこれを使ってみましょう。Cコードは以下のようになります。

#include "mylib.h"

int main() {
    my_puts("hello");
}

これを--js-library付きでコンパイルします。

$ emcc --js-library mylib.js hello.c # makes a.out.js
$ node a.out.js
hello

うまくいきました。実際には、char* から JSの文字列を生成するユーティリティとしてModule.Pointer_stringify(ptr [, len])が提供されているのでそちらを使うほうがいいでしょう。

それにしても、emscriptenはなんとも奇妙で面白い世界ですね。