RTTI
実行する時とかに -dinstr オプションをつけるとバイトコードが出るそうです。
let _ = print_int 12345; ()
みたいなコードは、
i@u ~/test/ocaml> gcaml -dinstr pr_test.ml const 12345 push getglobal Pervasives! getfield 30 apply 1 const 0a return 1
とかになりました。 12345 を積んで、 Pervasives (Object とか Kernel とか Prelude とか Lobby とか言語ごとに違う最初のモジュールみたいなヤツぽい。 JS だったら実装ごとに違ったりとか) から関数探してきて apply 1 (1は引数の数だと思う) してる。そのまんまですな。 Gprint.eprint に書き換えると…
i@u ~/test/ocaml> gcaml -dinstr pr_test.ml const 12345 push const 0 push getglobal Builtintypes! getfield 1 push const [0: [0: "int" 1]] makeblock 2, 0 makeblock 2, 2 makeblock 1, 0 makeblock 1, 0 push getglobal Gprint! getfield 3 apply 2 const 0a return 1
なんかややこいことになってますなぁ。型情報を第一引数として渡してるんでしょうけど、謎の makeblock とかでなんかよくわからないことしてますのう。ちなみに Printf.printf "%d\n" 12345 はこんな感じ。
i@u ~/test/ocaml> gcaml -dinstr pr_test.ml const 12345 push const "%d\n" push getglobal Printf! getfield 1 apply 2 const 0a return 1
まぁ実行時型情報にはコストがかかるという話ですね。 printf は文字列のパースが入るからこのコードだけ見て速度推測してもしょうがないけど。