Labels as Values による Compiled goto でインタプリタを高速化
Android のインタプリタは C で実装されたバージョンとアセンブラで実装されたバージョンがあって、どちらもインストラクションを goto で処理するように実装されている。
ずっと気になっていた C の goto の仕組みを調べてみた。
#include <stdio.h> int main(int argc, char *argv[]) { void *table[] = { &&l0, &&l1, &&l2 }; // ←これがキモい goto *table[1]; l0: printf("l0\n"); goto *table[2]; l1: printf("l1\n"); goto *table[0]; l2: printf("l2\n"); return 0; }
このコードを実行すると、l1、l0、l2 と表示されるのだが、はたして table に格納している &&l0 などは何者なのか。以下のページで氷解した。
DSAS開発者の部屋:インタプリタ型言語を高速化する computed goto
なるほど、gcc の拡張なのか(どうりでキモいわけだ)。これはインタプリタが楽に書けてかつ高速になるという魅力的な機能なんだけど、移植性を損なうのも事実。