SlideShare uma empresa Scribd logo
1 de 39
Baixar para ler offline
ocamloptの全体像ocamloptの全体像ocamloptの全体像ocamloptの全体像ocamloptの全体像
Kiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu Okabe
私は誰?私は誰?私は誰?私は誰?私は誰?
☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q
☆ Metasepiプロジェクト主催☆ Metasepiプロジェクト主催☆ Metasepiプロジェクト主催☆ Metasepiプロジェクト主催☆ Metasepiプロジェクト主催
☆ Ajhc Haskellコンパイラ開発者☆ Ajhc Haskellコンパイラ開発者☆ Ajhc Haskellコンパイラ開発者☆ Ajhc Haskellコンパイラ開発者☆ Ajhc Haskellコンパイラ開発者
☆ Debian Maintainer☆ Debian Maintainer☆ Debian Maintainer☆ Debian Maintainer☆ Debian Maintainer
☆ 前はデジタルサイネージの開発してました☆ 前はデジタルサイネージの開発してました☆ 前はデジタルサイネージの開発してました☆ 前はデジタルサイネージの開発してました☆ 前はデジタルサイネージの開発してました
☆ その昔はNetBSDでコピー機作ってた☆ その昔はNetBSDでコピー機作ってた☆ その昔はNetBSDでコピー機作ってた☆ その昔はNetBSDでコピー機作ってた☆ その昔はNetBSDでコピー機作ってた
ぼくとOCamlぼくとOCamlぼくとOCamlぼくとOCamlぼくとOCaml
☆ 最初の会社で社内勉強会☆ 最初の会社で社内勉強会☆ 最初の会社で社内勉強会☆ 最初の会社で社内勉強会☆ 最初の会社で社内勉強会
☆ letの嵐にとまどう☆ letの嵐にとまどう☆ letの嵐にとまどう☆ letの嵐にとまどう☆ letの嵐にとまどう
☆ 数年後にPFDSを読む☆ 数年後にPFDSを読む☆ 数年後にPFDSを読む☆ 数年後にPFDSを読む☆ 数年後にPFDSを読む
☆ lazyきもちいい!☆ lazyきもちいい!☆ lazyきもちいい!☆ lazyきもちいい!☆ lazyきもちいい!
☆ camlp4に脳味噌を焼きはらわれる...☆ camlp4に脳味噌を焼きはらわれる...☆ camlp4に脳味噌を焼きはらわれる...☆ camlp4に脳味噌を焼きはらわれる...☆ camlp4に脳味噌を焼きはらわれる...
☆ camloebaさんに脅されてocamlopt読む☆ camloebaさんに脅されてocamlopt読む☆ camloebaさんに脅されてocamlopt読む☆ camloebaさんに脅されてocamlopt読む☆ camloebaさんに脅されてocamlopt読む
☆ OCamlコードわかりやすい! <= イマココ☆ OCamlコードわかりやすい! <= イマココ☆ OCamlコードわかりやすい! <= イマココ☆ OCamlコードわかりやすい! <= イマココ☆ OCamlコードわかりやすい! <= イマココ
今日のもくじ今日のもくじ今日のもくじ今日のもくじ今日のもくじ
☆ [1] ocamloptについて簡単に☆ [1] ocamloptについて簡単に☆ [1] ocamloptについて簡単に☆ [1] ocamloptについて簡単に☆ [1] ocamloptについて簡単に
☆ [2] ソース探検のシナリオ☆ [2] ソース探検のシナリオ☆ [2] ソース探検のシナリオ☆ [2] ソース探検のシナリオ☆ [2] ソース探検のシナリオ
☆ [3] プログラムの起動☆ [3] プログラムの起動☆ [3] プログラムの起動☆ [3] プログラムの起動☆ [3] プログラムの起動
☆ [4] 文字列を画面に印字☆ [4] 文字列を画面に印字☆ [4] 文字列を画面に印字☆ [4] 文字列を画面に印字☆ [4] 文字列を画面に印字
☆ [5] シグナルの扱い☆ [5] シグナルの扱い☆ [5] シグナルの扱い☆ [5] シグナルの扱い☆ [5] シグナルの扱い
[1] ocamloptについて簡単に[1] ocamloptについて簡単に[1] ocamloptについて簡単に[1] ocamloptについて簡単に[1] ocamloptについて簡単に
まずはOCaml 4.00.1をインストールまずはOCaml 4.00.1をインストールまずはOCaml 4.00.1をインストールまずはOCaml 4.00.1をインストールまずはOCaml 4.00.1をインストール
$ git clone git@github.com:ocaml/ocaml.git
$ cd ocaml
$ git checkout 4.00.1
$ sudo apt-get build-dep ocaml
$ ./configure -with-debug-runtime
$ make world.opt
$ sudo make install
$ which ocamlopt
/usr/local/bin/ocamlopt
$ ocamlopt -version
4.00.1
$ git clone git@github.com:ocaml/ocaml.git
$ cd ocaml
$ git checkout 4.00.1
$ sudo apt-get build-dep ocaml
$ ./configure -with-debug-runtime
$ make world.opt
$ sudo make install
$ which ocamlopt
/usr/local/bin/ocamlopt
$ ocamlopt -version
4.00.1
$ git clone git@github.com:ocaml/ocaml.git
$ cd ocaml
$ git checkout 4.00.1
$ sudo apt-get build-dep ocaml
$ ./configure -with-debug-runtime
$ make world.opt
$ sudo make install
$ which ocamlopt
/usr/local/bin/ocamlopt
$ ocamlopt -version
4.00.1
$ git clone git@github.com:ocaml/ocaml.git
$ cd ocaml
$ git checkout 4.00.1
$ sudo apt-get build-dep ocaml
$ ./configure -with-debug-runtime
$ make world.opt
$ sudo make install
$ which ocamlopt
/usr/local/bin/ocamlopt
$ ocamlopt -version
4.00.1
$ git clone git@github.com:ocaml/ocaml.git
$ cd ocaml
$ git checkout 4.00.1
$ sudo apt-get build-dep ocaml
$ ./configure -with-debug-runtime
$ make world.opt
$ sudo make install
$ which ocamlopt
/usr/local/bin/ocamlopt
$ ocamlopt -version
4.00.1
想定環境想定環境想定環境想定環境想定環境
☆ Debian GNU/Linux sid amd64☆ Debian GNU/Linux sid amd64☆ Debian GNU/Linux sid amd64☆ Debian GNU/Linux sid amd64☆ Debian GNU/Linux sid amd64
ocamloptってなんどすか?ocamloptってなんどすか?ocamloptってなんどすか?ocamloptってなんどすか?ocamloptってなんどすか?
OCamlソースを実行バイナリにするコンパイラOCamlソースを実行バイナリにするコンパイラOCamlソースを実行バイナリにするコンパイラOCamlソースを実行バイナリにするコンパイラOCamlソースを実行バイナリにするコンパイラ
$ cat hello.ml
let hello _ = print_endline "Hello world!";;
let _ = hello ();
$ ocamlopt -g -runtime-variant d -o hello.bin hello.ml
$ file hello.bin
hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.32,
BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not
stripped
$ ./hello.bin
### OCaml runtime: debug mode ###
Initial minor heap size: 2048k bytes
Initial major heap size: 992k bytes
Initial space overhead: 80%
Initial max overhead: 500%
Initial heap increment: 992k bytes
Initial allocation policy: 0
Hello world!
$ cat hello.ml
let hello _ = print_endline "Hello world!";;
let _ = hello ();
$ ocamlopt -g -runtime-variant d -o hello.bin hello.ml
$ file hello.bin
hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.32,
BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not
stripped
$ ./hello.bin
### OCaml runtime: debug mode ###
Initial minor heap size: 2048k bytes
Initial major heap size: 992k bytes
Initial space overhead: 80%
Initial max overhead: 500%
Initial heap increment: 992k bytes
Initial allocation policy: 0
Hello world!
$ cat hello.ml
let hello _ = print_endline "Hello world!";;
let _ = hello ();
$ ocamlopt -g -runtime-variant d -o hello.bin hello.ml
$ file hello.bin
hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.32,
BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not
stripped
$ ./hello.bin
### OCaml runtime: debug mode ###
Initial minor heap size: 2048k bytes
Initial major heap size: 992k bytes
Initial space overhead: 80%
Initial max overhead: 500%
Initial heap increment: 992k bytes
Initial allocation policy: 0
Hello world!
$ cat hello.ml
let hello _ = print_endline "Hello world!";;
let _ = hello ();
$ ocamlopt -g -runtime-variant d -o hello.bin hello.ml
$ file hello.bin
hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.32,
BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not
stripped
$ ./hello.bin
### OCaml runtime: debug mode ###
Initial minor heap size: 2048k bytes
Initial major heap size: 992k bytes
Initial space overhead: 80%
Initial max overhead: 500%
Initial heap increment: 992k bytes
Initial allocation policy: 0
Hello world!
$ cat hello.ml
let hello _ = print_endline "Hello world!";;
let _ = hello ();
$ ocamlopt -g -runtime-variant d -o hello.bin hello.ml
$ file hello.bin
hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.32,
BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not
stripped
$ ./hello.bin
### OCaml runtime: debug mode ###
Initial minor heap size: 2048k bytes
Initial major heap size: 992k bytes
Initial space overhead: 80%
Initial max overhead: 500%
Initial heap increment: 992k bytes
Initial allocation policy: 0
Hello world!
-with-debug-runtime? -g?-with-debug-runtime? -g?-with-debug-runtime? -g?-with-debug-runtime? -g?-with-debug-runtime? -g?
☆ objdump -S hello.bin してみると...☆ objdump -S hello.bin してみると...☆ objdump -S hello.bin してみると...☆ objdump -S hello.bin してみると...☆ objdump -S hello.bin してみると...
どーいうことだってばよ!?どーいうことだってばよ!?どーいうことだってばよ!?どーいうことだってばよ!?どーいうことだってばよ!?
☆ objdumpやgdbで☆ objdumpやgdbで☆ objdumpやgdbで☆ objdumpやgdbで☆ objdumpやgdbで
☆ 実行バイナリの中の☆ 実行バイナリの中の☆ 実行バイナリの中の☆ 実行バイナリの中の☆ 実行バイナリの中の
☆ コンパイル結果マシン語と☆ コンパイル結果マシン語と☆ コンパイル結果マシン語と☆ コンパイル結果マシン語と☆ コンパイル結果マシン語と
☆ ランタイムのマシン語の両方を☆ ランタイムのマシン語の両方を☆ ランタイムのマシン語の両方を☆ ランタイムのマシン語の両方を☆ ランタイムのマシン語の両方を
☆ ソースコードレベルデバッグできる☆ ソースコードレベルデバッグできる☆ ソースコードレベルデバッグできる☆ ソースコードレベルデバッグできる☆ ソースコードレベルデバッグできる
すばらしい!すばらしい!すばらしい!すばらしい!すばらしい!
[2] ソース探検のシナリオ[2] ソース探検のシナリオ[2] ソース探検のシナリオ[2] ソース探検のシナリオ[2] ソース探検のシナリオ
[3] プログラムの起動[3] プログラムの起動[3] プログラムの起動[3] プログラムの起動[3] プログラムの起動
☆ main関数から実行が開始されて☆ main関数から実行が開始されて☆ main関数から実行が開始されて☆ main関数から実行が開始されて☆ main関数から実行が開始されて
☆ camlHello__entry関数がプログラム入口☆ camlHello__entry関数がプログラム入口☆ camlHello__entry関数がプログラム入口☆ camlHello__entry関数がプログラム入口☆ camlHello__entry関数がプログラム入口
$ ocamlopt -o hello.bin hello.ml
$ gdb hello.bin
(gdb) b camlHello__entry
Breakpoint 1 at 0x402260
(gdb) run
...
Breakpoint 1, 0x0000000000402260 in camlHello__entry ()
(gdb) bt
#0 0x0000000000402260 in camlHello__entry ()
#1 0x0000000000401e89 in caml_program ()
#2 0x0000000000410d82 in caml_start_program ()
#3 0x0000000000411245 in caml_main ()
#4 0x000000000040414e in main ()
$ ocamlopt -o hello.bin hello.ml
$ gdb hello.bin
(gdb) b camlHello__entry
Breakpoint 1 at 0x402260
(gdb) run
...
Breakpoint 1, 0x0000000000402260 in camlHello__entry ()
(gdb) bt
#0 0x0000000000402260 in camlHello__entry ()
#1 0x0000000000401e89 in caml_program ()
#2 0x0000000000410d82 in caml_start_program ()
#3 0x0000000000411245 in caml_main ()
#4 0x000000000040414e in main ()
$ ocamlopt -o hello.bin hello.ml
$ gdb hello.bin
(gdb) b camlHello__entry
Breakpoint 1 at 0x402260
(gdb) run
...
Breakpoint 1, 0x0000000000402260 in camlHello__entry ()
(gdb) bt
#0 0x0000000000402260 in camlHello__entry ()
#1 0x0000000000401e89 in caml_program ()
#2 0x0000000000410d82 in caml_start_program ()
#3 0x0000000000411245 in caml_main ()
#4 0x000000000040414e in main ()
$ ocamlopt -o hello.bin hello.ml
$ gdb hello.bin
(gdb) b camlHello__entry
Breakpoint 1 at 0x402260
(gdb) run
...
Breakpoint 1, 0x0000000000402260 in camlHello__entry ()
(gdb) bt
#0 0x0000000000402260 in camlHello__entry ()
#1 0x0000000000401e89 in caml_program ()
#2 0x0000000000410d82 in caml_start_program ()
#3 0x0000000000411245 in caml_main ()
#4 0x000000000040414e in main ()
$ ocamlopt -o hello.bin hello.ml
$ gdb hello.bin
(gdb) b camlHello__entry
Breakpoint 1 at 0x402260
(gdb) run
...
Breakpoint 1, 0x0000000000402260 in camlHello__entry ()
(gdb) bt
#0 0x0000000000402260 in camlHello__entry ()
#1 0x0000000000401e89 in caml_program ()
#2 0x0000000000410d82 in caml_start_program ()
#3 0x0000000000411245 in caml_main ()
#4 0x000000000040414e in main ()
main関数はどこに?main関数はどこに?main関数はどこに?main関数はどこに?main関数はどこに?
☆ "byterun/main.c"です☆ "byterun/main.c"です☆ "byterun/main.c"です☆ "byterun/main.c"です☆ "byterun/main.c"です
☆ え?バイトコード?☆ え?バイトコード?☆ え?バイトコード?☆ え?バイトコード?☆ え?バイトコード?
☆ "{byte,asm}run"のディレクトリがある☆ "{byte,asm}run"のディレクトリがある☆ "{byte,asm}run"のディレクトリがある☆ "{byte,asm}run"のディレクトリがある☆ "{byte,asm}run"のディレクトリがある
☆ でもなんかきっちり分離されていない☆ でもなんかきっちり分離されていない☆ でもなんかきっちり分離されていない☆ でもなんかきっちり分離されていない☆ でもなんかきっちり分離されていない
☆ バイナリでも適宜byterunの下を使います☆ バイナリでも適宜byterunの下を使います☆ バイナリでも適宜byterunの下を使います☆ バイナリでも適宜byterunの下を使います☆ バイナリでも適宜byterunの下を使います
main関数ソースmain関数ソースmain関数ソースmain関数ソースmain関数ソース
デバッグ機能なしだとこんなんデバッグ機能なしだとこんなんデバッグ機能なしだとこんなんデバッグ機能なしだとこんなんデバッグ機能なしだとこんなん
/* File: byterun/main.c */
int main(int argc, char **argv)
{
caml_main(argv);
caml_sys_exit(Val_int(0));
return 0;
}
/* File: byterun/main.c */
int main(int argc, char **argv)
{
caml_main(argv);
caml_sys_exit(Val_int(0));
return 0;
}
/* File: byterun/main.c */
int main(int argc, char **argv)
{
caml_main(argv);
caml_sys_exit(Val_int(0));
return 0;
}
/* File: byterun/main.c */
int main(int argc, char **argv)
{
caml_main(argv);
caml_sys_exit(Val_int(0));
return 0;
}
/* File: byterun/main.c */
int main(int argc, char **argv)
{
caml_main(argv);
caml_sys_exit(Val_int(0));
return 0;
}
むちゃくちゃ簡単ですむちゃくちゃ簡単ですむちゃくちゃ簡単ですむちゃくちゃ簡単ですむちゃくちゃ簡単です
caml_main関数caml_main関数caml_main関数caml_main関数caml_main関数
caml_init_ieee_floats関数caml_init_ieee_floats関数caml_init_ieee_floats関数caml_init_ieee_floats関数caml_init_ieee_floats関数
/* File: byterun/floats.c */
/* The [caml_init_ieee_float] function should initialize
floating-point hardware so that it behaves as much as possible
like the IEEE standard.
In particular, return special numbers like Infinity and NaN
instead of signalling exceptions. Currently, everyone is in
IEEE mode at program startup, except FreeBSD prior to 4.0R. */
/* --snip-- */
void caml_init_ieee_floats(void)
{
#if defined(__FreeBSD__) && (__FreeBSD_version < 400017)
fpsetmask(0);
#endif
}
/* File: byterun/floats.c */
/* The [caml_init_ieee_float] function should initialize
floating-point hardware so that it behaves as much as possible
like the IEEE standard.
In particular, return special numbers like Infinity and NaN
instead of signalling exceptions. Currently, everyone is in
IEEE mode at program startup, except FreeBSD prior to 4.0R. */
/* --snip-- */
void caml_init_ieee_floats(void)
{
#if defined(__FreeBSD__) && (__FreeBSD_version < 400017)
fpsetmask(0);
#endif
}
/* File: byterun/floats.c */
/* The [caml_init_ieee_float] function should initialize
floating-point hardware so that it behaves as much as possible
like the IEEE standard.
In particular, return special numbers like Infinity and NaN
instead of signalling exceptions. Currently, everyone is in
IEEE mode at program startup, except FreeBSD prior to 4.0R. */
/* --snip-- */
void caml_init_ieee_floats(void)
{
#if defined(__FreeBSD__) && (__FreeBSD_version < 400017)
fpsetmask(0);
#endif
}
/* File: byterun/floats.c */
/* The [caml_init_ieee_float] function should initialize
floating-point hardware so that it behaves as much as possible
like the IEEE standard.
In particular, return special numbers like Infinity and NaN
instead of signalling exceptions. Currently, everyone is in
IEEE mode at program startup, except FreeBSD prior to 4.0R. */
/* --snip-- */
void caml_init_ieee_floats(void)
{
#if defined(__FreeBSD__) && (__FreeBSD_version < 400017)
fpsetmask(0);
#endif
}
/* File: byterun/floats.c */
/* The [caml_init_ieee_float] function should initialize
floating-point hardware so that it behaves as much as possible
like the IEEE standard.
In particular, return special numbers like Infinity and NaN
instead of signalling exceptions. Currently, everyone is in
IEEE mode at program startup, except FreeBSD prior to 4.0R. */
/* --snip-- */
void caml_init_ieee_floats(void)
{
#if defined(__FreeBSD__) && (__FreeBSD_version < 400017)
fpsetmask(0);
#endif
}
☆ FreeBSDへのバグ対策?☆ FreeBSDへのバグ対策?☆ FreeBSDへのバグ対策?☆ FreeBSDへのバグ対策?☆ FreeBSDへのバグ対策?
☆ 気にしないことにしましょう☆ 気にしないことにしましょう☆ 気にしないことにしましょう☆ 気にしないことにしましょう☆ 気にしないことにしましょう
caml_init_custom_operations #1caml_init_custom_operations #1caml_init_custom_operations #1caml_init_custom_operations #1caml_init_custom_operations #1
ボックス化されたintのプリミティブ関数を登録ボックス化されたintのプリミティブ関数を登録ボックス化されたintのプリミティブ関数を登録ボックス化されたintのプリミティブ関数を登録ボックス化されたintのプリミティブ関数を登録
/* File: byterun/custom.c */
void caml_init_custom_operations(void)
{
caml_register_custom_operations(&caml_int32_ops);
caml_register_custom_operations(&caml_nativeint_ops);
caml_register_custom_operations(&caml_int64_ops);
}
/* File: byterun/custom.c */
void caml_init_custom_operations(void)
{
caml_register_custom_operations(&caml_int32_ops);
caml_register_custom_operations(&caml_nativeint_ops);
caml_register_custom_operations(&caml_int64_ops);
}
/* File: byterun/custom.c */
void caml_init_custom_operations(void)
{
caml_register_custom_operations(&caml_int32_ops);
caml_register_custom_operations(&caml_nativeint_ops);
caml_register_custom_operations(&caml_int64_ops);
}
/* File: byterun/custom.c */
void caml_init_custom_operations(void)
{
caml_register_custom_operations(&caml_int32_ops);
caml_register_custom_operations(&caml_nativeint_ops);
caml_register_custom_operations(&caml_int64_ops);
}
/* File: byterun/custom.c */
void caml_init_custom_operations(void)
{
caml_register_custom_operations(&caml_int32_ops);
caml_register_custom_operations(&caml_nativeint_ops);
caml_register_custom_operations(&caml_int64_ops);
}
caml_init_custom_operations #2caml_init_custom_operations #2caml_init_custom_operations #2caml_init_custom_operations #2caml_init_custom_operations #2
でもたぶんこれバイトコードでだけ必要?でもたぶんこれバイトコードでだけ必要?でもたぶんこれバイトコードでだけ必要?でもたぶんこれバイトコードでだけ必要?でもたぶんこれバイトコードでだけ必要?
$ grep "caml_.*_ops" asmcomp/cmmgen.ml
Pnativeint -> "caml_nativeint_ops"
| Pint32 -> "caml_int32_ops"
| Pint64 -> "caml_int64_ops"
Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n ::
cont
Csymbol_address("caml_int32_ops") :: Cint n :: cont
Csymbol_address("caml_nativeint_ops") :: Cint n :: cont
Csymbol_address("caml_int64_ops") :: Cint lo :: cont
Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo ::
cont
Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi ::
cont
$ grep "caml_.*_ops" asmcomp/cmmgen.ml
Pnativeint -> "caml_nativeint_ops"
| Pint32 -> "caml_int32_ops"
| Pint64 -> "caml_int64_ops"
Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n ::
cont
Csymbol_address("caml_int32_ops") :: Cint n :: cont
Csymbol_address("caml_nativeint_ops") :: Cint n :: cont
Csymbol_address("caml_int64_ops") :: Cint lo :: cont
Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo ::
cont
Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi ::
cont
$ grep "caml_.*_ops" asmcomp/cmmgen.ml
Pnativeint -> "caml_nativeint_ops"
| Pint32 -> "caml_int32_ops"
| Pint64 -> "caml_int64_ops"
Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n ::
cont
Csymbol_address("caml_int32_ops") :: Cint n :: cont
Csymbol_address("caml_nativeint_ops") :: Cint n :: cont
Csymbol_address("caml_int64_ops") :: Cint lo :: cont
Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo ::
cont
Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi ::
cont
$ grep "caml_.*_ops" asmcomp/cmmgen.ml
Pnativeint -> "caml_nativeint_ops"
| Pint32 -> "caml_int32_ops"
| Pint64 -> "caml_int64_ops"
Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n ::
cont
Csymbol_address("caml_int32_ops") :: Cint n :: cont
Csymbol_address("caml_nativeint_ops") :: Cint n :: cont
Csymbol_address("caml_int64_ops") :: Cint lo :: cont
Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo ::
cont
Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi ::
cont
$ grep "caml_.*_ops" asmcomp/cmmgen.ml
Pnativeint -> "caml_nativeint_ops"
| Pint32 -> "caml_int32_ops"
| Pint64 -> "caml_int64_ops"
Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n ::
cont
Csymbol_address("caml_int32_ops") :: Cint n :: cont
Csymbol_address("caml_nativeint_ops") :: Cint n :: cont
Csymbol_address("caml_int64_ops") :: Cint lo :: cont
Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo ::
cont
Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi ::
cont
ocamloptではシンボルから直接呼び出しにocamloptではシンボルから直接呼び出しにocamloptではシンボルから直接呼び出しにocamloptではシンボルから直接呼び出しにocamloptではシンボルから直接呼び出しに
parse_camlrunparam関数parse_camlrunparam関数parse_camlrunparam関数parse_camlrunparam関数parse_camlrunparam関数
OCAMLRUNPARAM環境変数を見るだけOCAMLRUNPARAM環境変数を見るだけOCAMLRUNPARAM環境変数を見るだけOCAMLRUNPARAM環境変数を見るだけOCAMLRUNPARAM環境変数を見るだけ
http://caml.inria.fr/pub/docs/manual-ocaml/manual024.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual024.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual024.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual024.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual024.html
/* File: asmrun/startup.c */
static void parse_camlrunparam(void)
{
char *opt = getenv ("OCAMLRUNPARAM");
uintnat p;
if (opt == NULL) opt = getenv ("CAMLRUNPARAM");
if (opt != NULL){
while (*opt != '0'){
switch (*opt++){
case 's': scanmult (opt, &minor_heap_init); break;
case 'i': scanmult (opt, &heap_chunk_init); break;
case 'h': scanmult (opt, &heap_size_init); break;
case 'l': scanmult (opt, &max_stack_init); break;
case 'o': scanmult (opt, &percent_free_init); break;
case 'O': scanmult (opt, &max_percent_free_init); break;
case 'v': scanmult (opt, &caml_verb_gc); break;
/* File: asmrun/startup.c */
static void parse_camlrunparam(void)
{
char *opt = getenv ("OCAMLRUNPARAM");
uintnat p;
if (opt == NULL) opt = getenv ("CAMLRUNPARAM");
if (opt != NULL){
while (*opt != '0'){
switch (*opt++){
case 's': scanmult (opt, &minor_heap_init); break;
case 'i': scanmult (opt, &heap_chunk_init); break;
case 'h': scanmult (opt, &heap_size_init); break;
case 'l': scanmult (opt, &max_stack_init); break;
case 'o': scanmult (opt, &percent_free_init); break;
case 'O': scanmult (opt, &max_percent_free_init); break;
case 'v': scanmult (opt, &caml_verb_gc); break;
/* File: asmrun/startup.c */
static void parse_camlrunparam(void)
{
char *opt = getenv ("OCAMLRUNPARAM");
uintnat p;
if (opt == NULL) opt = getenv ("CAMLRUNPARAM");
if (opt != NULL){
while (*opt != '0'){
switch (*opt++){
case 's': scanmult (opt, &minor_heap_init); break;
case 'i': scanmult (opt, &heap_chunk_init); break;
case 'h': scanmult (opt, &heap_size_init); break;
case 'l': scanmult (opt, &max_stack_init); break;
case 'o': scanmult (opt, &percent_free_init); break;
case 'O': scanmult (opt, &max_percent_free_init); break;
case 'v': scanmult (opt, &caml_verb_gc); break;
/* File: asmrun/startup.c */
static void parse_camlrunparam(void)
{
char *opt = getenv ("OCAMLRUNPARAM");
uintnat p;
if (opt == NULL) opt = getenv ("CAMLRUNPARAM");
if (opt != NULL){
while (*opt != '0'){
switch (*opt++){
case 's': scanmult (opt, &minor_heap_init); break;
case 'i': scanmult (opt, &heap_chunk_init); break;
case 'h': scanmult (opt, &heap_size_init); break;
case 'l': scanmult (opt, &max_stack_init); break;
case 'o': scanmult (opt, &percent_free_init); break;
case 'O': scanmult (opt, &max_percent_free_init); break;
case 'v': scanmult (opt, &caml_verb_gc); break;
/* File: asmrun/startup.c */
static void parse_camlrunparam(void)
{
char *opt = getenv ("OCAMLRUNPARAM");
uintnat p;
if (opt == NULL) opt = getenv ("CAMLRUNPARAM");
if (opt != NULL){
while (*opt != '0'){
switch (*opt++){
case 's': scanmult (opt, &minor_heap_init); break;
case 'i': scanmult (opt, &heap_chunk_init); break;
case 'h': scanmult (opt, &heap_size_init); break;
case 'l': scanmult (opt, &max_stack_init); break;
case 'o': scanmult (opt, &percent_free_init); break;
case 'O': scanmult (opt, &max_percent_free_init); break;
case 'v': scanmult (opt, &caml_verb_gc); break;
caml_init_gc関数caml_init_gc関数caml_init_gc関数caml_init_gc関数caml_init_gc関数
☆ メジャー/マイナーGC用のヒープ初期化☆ メジャー/マイナーGC用のヒープ初期化☆ メジャー/マイナーGC用のヒープ初期化☆ メジャー/マイナーGC用のヒープ初期化☆ メジャー/マイナーGC用のヒープ初期化
☆ Real World OCaml読んだ方がいいかも!☆ Real World OCaml読んだ方がいいかも!☆ Real World OCaml読んだ方がいいかも!☆ Real World OCaml読んだ方がいいかも!☆ Real World OCaml読んだ方がいいかも!
init_atoms関数init_atoms関数init_atoms関数init_atoms関数init_atoms関数
☆ これよくわからなかったです orz☆ これよくわからなかったです orz☆ これよくわからなかったです orz☆ これよくわからなかったです orz☆ これよくわからなかったです orz
☆ caml_data_segmentsと☆ caml_data_segmentsと☆ caml_data_segmentsと☆ caml_data_segmentsと☆ caml_data_segmentsと
☆ caml_code_segmentsを解析している?☆ caml_code_segmentsを解析している?☆ caml_code_segmentsを解析している?☆ caml_code_segmentsを解析している?☆ caml_code_segmentsを解析している?
☆ 目的がよくわからない...☆ 目的がよくわからない...☆ 目的がよくわからない...☆ 目的がよくわからない...☆ 目的がよくわからない...
caml_init_signals関数caml_init_signals関数caml_init_signals関数caml_init_signals関数caml_init_signals関数
SEGVシグナルハンドラを通常コンテキストと
は別のスタックで実行するように設定
SEGVシグナルハンドラを通常コンテキストと
は別のスタックで実行するように設定
SEGVシグナルハンドラを通常コンテキストと
は別のスタックで実行するように設定
SEGVシグナルハンドラを通常コンテキストと
は別のスタックで実行するように設定
SEGVシグナルハンドラを通常コンテキストと
は別のスタックで実行するように設定
/* File: asmrun/signals_asm.c */
void caml_init_signals(void)
{
/* Stack overflow handling */
stack_t stk;
struct sigaction act;
stk.ss_sp = sig_alt_stack;
stk.ss_size = SIGSTKSZ;
stk.ss_flags = 0;
SET_SIGACT(act, segv_handler);
act.sa_flags |= SA_ONSTACK | SA_NODEFER;
sigemptyset(&act.sa_mask);
system_stack_top = (char *) &act;
if (sigaltstack(&stk, NULL) == 0) {
sigaction(SIGSEGV, &act, NULL);
}
}
/* File: asmrun/signals_asm.c */
void caml_init_signals(void)
{
/* Stack overflow handling */
stack_t stk;
struct sigaction act;
stk.ss_sp = sig_alt_stack;
stk.ss_size = SIGSTKSZ;
stk.ss_flags = 0;
SET_SIGACT(act, segv_handler);
act.sa_flags |= SA_ONSTACK | SA_NODEFER;
sigemptyset(&act.sa_mask);
system_stack_top = (char *) &act;
if (sigaltstack(&stk, NULL) == 0) {
sigaction(SIGSEGV, &act, NULL);
}
}
/* File: asmrun/signals_asm.c */
void caml_init_signals(void)
{
/* Stack overflow handling */
stack_t stk;
struct sigaction act;
stk.ss_sp = sig_alt_stack;
stk.ss_size = SIGSTKSZ;
stk.ss_flags = 0;
SET_SIGACT(act, segv_handler);
act.sa_flags |= SA_ONSTACK | SA_NODEFER;
sigemptyset(&act.sa_mask);
system_stack_top = (char *) &act;
if (sigaltstack(&stk, NULL) == 0) {
sigaction(SIGSEGV, &act, NULL);
}
}
/* File: asmrun/signals_asm.c */
void caml_init_signals(void)
{
/* Stack overflow handling */
stack_t stk;
struct sigaction act;
stk.ss_sp = sig_alt_stack;
stk.ss_size = SIGSTKSZ;
stk.ss_flags = 0;
SET_SIGACT(act, segv_handler);
act.sa_flags |= SA_ONSTACK | SA_NODEFER;
sigemptyset(&act.sa_mask);
system_stack_top = (char *) &act;
if (sigaltstack(&stk, NULL) == 0) {
sigaction(SIGSEGV, &act, NULL);
}
}
/* File: asmrun/signals_asm.c */
void caml_init_signals(void)
{
/* Stack overflow handling */
stack_t stk;
struct sigaction act;
stk.ss_sp = sig_alt_stack;
stk.ss_size = SIGSTKSZ;
stk.ss_flags = 0;
SET_SIGACT(act, segv_handler);
act.sa_flags |= SA_ONSTACK | SA_NODEFER;
sigemptyset(&act.sa_mask);
system_stack_top = (char *) &act;
if (sigaltstack(&stk, NULL) == 0) {
sigaction(SIGSEGV, &act, NULL);
}
}
segv_handler関数segv_handler関数segv_handler関数segv_handler関数segv_handler関数
☆ SEGVシグナルで起動☆ SEGVシグナルで起動☆ SEGVシグナルで起動☆ SEGVシグナルで起動☆ SEGVシグナルで起動
☆ スタック溢れが起きていたら例外発生☆ スタック溢れが起きていたら例外発生☆ スタック溢れが起きていたら例外発生☆ スタック溢れが起きていたら例外発生☆ スタック溢れが起きていたら例外発生
☆ 最終的にcaml_raise_exceptionを呼ぶ☆ 最終的にcaml_raise_exceptionを呼ぶ☆ 最終的にcaml_raise_exceptionを呼ぶ☆ 最終的にcaml_raise_exceptionを呼ぶ☆ 最終的にcaml_raise_exceptionを呼ぶ
OCamlの例外キャッチOCamlの例外キャッチOCamlの例外キャッチOCamlの例外キャッチOCamlの例外キャッチ
OCamlの例外スローOCamlの例外スローOCamlの例外スローOCamlの例外スローOCamlの例外スロー
つまり?つまり?つまり?つまり?つまり?
OCamlサイドOCamlサイドOCamlサイドOCamlサイドOCamlサイド
☆ r14レジスタ: try時スタック☆ r14レジスタ: try時スタック☆ r14レジスタ: try時スタック☆ r14レジスタ: try時スタック☆ r14レジスタ: try時スタック
☆ r15レジスタ: GCヒープへのポインタ☆ r15レジスタ: GCヒープへのポインタ☆ r15レジスタ: GCヒープへのポインタ☆ r15レジスタ: GCヒープへのポインタ☆ r15レジスタ: GCヒープへのポインタ
C言語サイドC言語サイドC言語サイドC言語サイドC言語サイド
☆ caml_exception_pointer: try時スタック☆ caml_exception_pointer: try時スタック☆ caml_exception_pointer: try時スタック☆ caml_exception_pointer: try時スタック☆ caml_exception_pointer: try時スタック
☆ caml_young_ptr: GCヒープへのポインタ☆ caml_young_ptr: GCヒープへのポインタ☆ caml_young_ptr: GCヒープへのポインタ☆ caml_young_ptr: GCヒープへのポインタ☆ caml_young_ptr: GCヒープへのポインタ
いつでも戻れますねいつでも戻れますねいつでも戻れますねいつでも戻れますねいつでも戻れますね
caml_debugger_init関数caml_debugger_init関数caml_debugger_init関数caml_debugger_init関数caml_debugger_init関数
CAML_DEBUG_SOCKET環境変数が定義
されていたらBSDソケットを使ったデバッグ環
境を設定
CAML_DEBUG_SOCKET環境変数が定義
されていたらBSDソケットを使ったデバッグ環
境を設定
CAML_DEBUG_SOCKET環境変数が定義
されていたらBSDソケットを使ったデバッグ環
境を設定
CAML_DEBUG_SOCKET環境変数が定義
されていたらBSDソケットを使ったデバッグ環
境を設定
CAML_DEBUG_SOCKET環境変数が定義
されていたらBSDソケットを使ったデバッグ環
境を設定
http://caml.inria.fr/pub/docs/manual-ocaml/manual030.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual030.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual030.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual030.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual030.html
そんなものがあったのか...そんなものがあったのか...そんなものがあったのか...そんなものがあったのか...そんなものがあったのか...
caml_sys_init関数caml_sys_init関数caml_sys_init関数caml_sys_init関数caml_sys_init関数
プログラム名と引数の保管プログラム名と引数の保管プログラム名と引数の保管プログラム名と引数の保管プログラム名と引数の保管
/* File: byterun/sys.c */
void caml_sys_init(char * exe_name, char **argv)
{
caml_exe_name = exe_name;
caml_main_argv = argv;
}
/* File: byterun/sys.c */
void caml_sys_init(char * exe_name, char **argv)
{
caml_exe_name = exe_name;
caml_main_argv = argv;
}
/* File: byterun/sys.c */
void caml_sys_init(char * exe_name, char **argv)
{
caml_exe_name = exe_name;
caml_main_argv = argv;
}
/* File: byterun/sys.c */
void caml_sys_init(char * exe_name, char **argv)
{
caml_exe_name = exe_name;
caml_main_argv = argv;
}
/* File: byterun/sys.c */
void caml_sys_init(char * exe_name, char **argv)
{
caml_exe_name = exe_name;
caml_main_argv = argv;
}
まぁありがちまぁありがちまぁありがちまぁありがちまぁありがち
sigsetjmpsigsetjmpsigsetjmpsigsetjmpsigsetjmp
スレッドが終了するとlongjmpスレッドが終了するとlongjmpスレッドが終了するとlongjmpスレッドが終了するとlongjmpスレッドが終了するとlongjmp
caml_start_program関数caml_start_program関数caml_start_program関数caml_start_program関数caml_start_program関数
☆ calleeのレジスタ退避☆ calleeのレジスタ退避☆ calleeのレジスタ退避☆ calleeのレジスタ退避☆ calleeのレジスタ退避
☆ caml_gc_regsをpush☆ caml_gc_regsをpush☆ caml_gc_regsをpush☆ caml_gc_regsをpush☆ caml_gc_regsをpush
☆ caml_last_return_addressをpush☆ caml_last_return_addressをpush☆ caml_last_return_addressをpush☆ caml_last_return_addressをpush☆ caml_last_return_addressをpush
☆ caml_bottom_of_stackをpush☆ caml_bottom_of_stackをpush☆ caml_bottom_of_stackをpush☆ caml_bottom_of_stackをpush☆ caml_bottom_of_stackをpush
☆ caml_young_ptrを%r15に☆ caml_young_ptrを%r15に☆ caml_young_ptrを%r15に☆ caml_young_ptrを%r15に☆ caml_young_ptrを%r15に
☆ caml_exception_pointerを%r14に☆ caml_exception_pointerを%r14に☆ caml_exception_pointerを%r14に☆ caml_exception_pointerを%r14に☆ caml_exception_pointerを%r14に
☆ caml_program関数呼び出し☆ caml_program関数呼び出し☆ caml_program関数呼び出し☆ caml_program関数呼び出し☆ caml_program関数呼び出し
caml_programcaml_programcaml_programcaml_programcaml_program
コンパイル時に生成されるstartup.sで定義コンパイル時に生成されるstartup.sで定義コンパイル時に生成されるstartup.sで定義コンパイル時に生成されるstartup.sで定義コンパイル時に生成されるstartup.sで定義
camlPervasives__entrycamlPervasives__entrycamlPervasives__entrycamlPervasives__entrycamlPervasives__entry
☆ Pervasivesモジュール初期化☆ Pervasivesモジュール初期化☆ Pervasivesモジュール初期化☆ Pervasivesモジュール初期化☆ Pervasivesモジュール初期化
メジャーGCタイミングで全flushメジャーGCタイミングで全flushメジャーGCタイミングで全flushメジャーGCタイミングで全flushメジャーGCタイミングで全flush
camlHello__entrycamlHello__entrycamlHello__entrycamlHello__entrycamlHello__entry
最初のゴールに到着しました最初のゴールに到着しました最初のゴールに到着しました最初のゴールに到着しました最初のゴールに到着しました
[4] 文字列を画面に印字[4] 文字列を画面に印字[4] 文字列を画面に印字[4] 文字列を画面に印字[4] 文字列を画面に印字
☆ print_endlineが開始☆ print_endlineが開始☆ print_endlineが開始☆ print_endlineが開始☆ print_endlineが開始
print_endlineはバッファへ書き込むprint_endlineはバッファへ書き込むprint_endlineはバッファへ書き込むprint_endlineはバッファへ書き込むprint_endlineはバッファへ書き込む
[5] シグナルの扱い[5] シグナルの扱い[5] シグナルの扱い[5] シグナルの扱い[5] シグナルの扱い
blocking_sectionって何?blocking_sectionって何?blocking_sectionって何?blocking_sectionって何?blocking_sectionって何?
/* File: byterun/io.c */
CAMLexport struct channel * caml_open_descriptor_in(int fd)
{
struct channel * channel;
channel = (struct channel *)
caml_stat_alloc(sizeof(struct channel));
channel->fd = fd;
caml_enter_blocking_section();
channel->offset = lseek(fd, 0, SEEK_CUR);
caml_leave_blocking_section();
channel->curr = channel->max = channel->buff;
channel->end = channel->buff + IO_BUFFER_SIZE;
/* File: byterun/io.c */
CAMLexport struct channel * caml_open_descriptor_in(int fd)
{
struct channel * channel;
channel = (struct channel *)
caml_stat_alloc(sizeof(struct channel));
channel->fd = fd;
caml_enter_blocking_section();
channel->offset = lseek(fd, 0, SEEK_CUR);
caml_leave_blocking_section();
channel->curr = channel->max = channel->buff;
channel->end = channel->buff + IO_BUFFER_SIZE;
/* File: byterun/io.c */
CAMLexport struct channel * caml_open_descriptor_in(int fd)
{
struct channel * channel;
channel = (struct channel *)
caml_stat_alloc(sizeof(struct channel));
channel->fd = fd;
caml_enter_blocking_section();
channel->offset = lseek(fd, 0, SEEK_CUR);
caml_leave_blocking_section();
channel->curr = channel->max = channel->buff;
channel->end = channel->buff + IO_BUFFER_SIZE;
/* File: byterun/io.c */
CAMLexport struct channel * caml_open_descriptor_in(int fd)
{
struct channel * channel;
channel = (struct channel *)
caml_stat_alloc(sizeof(struct channel));
channel->fd = fd;
caml_enter_blocking_section();
channel->offset = lseek(fd, 0, SEEK_CUR);
caml_leave_blocking_section();
channel->curr = channel->max = channel->buff;
channel->end = channel->buff + IO_BUFFER_SIZE;
/* File: byterun/io.c */
CAMLexport struct channel * caml_open_descriptor_in(int fd)
{
struct channel * channel;
channel = (struct channel *)
caml_stat_alloc(sizeof(struct channel));
channel->fd = fd;
caml_enter_blocking_section();
channel->offset = lseek(fd, 0, SEEK_CUR);
caml_leave_blocking_section();
channel->curr = channel->max = channel->buff;
channel->end = channel->buff + IO_BUFFER_SIZE;
システムコールを囲むように配置されている...システムコールを囲むように配置されている...システムコールを囲むように配置されている...システムコールを囲むように配置されている...システムコールを囲むように配置されている...
シグナルハンドラの実行シグナルハンドラの実行シグナルハンドラの実行シグナルハンドラの実行シグナルハンドラの実行
ハンドラ登録とシグナル受信ハンドラ登録とシグナル受信ハンドラ登録とシグナル受信ハンドラ登録とシグナル受信ハンドラ登録とシグナル受信
宣伝: Ajhc Haskellコンパイラ宣伝: Ajhc Haskellコンパイラ宣伝: Ajhc Haskellコンパイラ宣伝: Ajhc Haskellコンパイラ宣伝: Ajhc Haskellコンパイラ
☆ http://ajhc.metasepi.org/☆ http://ajhc.metasepi.org/☆ http://ajhc.metasepi.org/☆ http://ajhc.metasepi.org/☆ http://ajhc.metasepi.org/
☆ 組込を狙ったHaskellコンパイラ☆ 組込を狙ったHaskellコンパイラ☆ 組込を狙ったHaskellコンパイラ☆ 組込を狙ったHaskellコンパイラ☆ 組込を狙ったHaskellコンパイラ
☆ Haskell => C言語 への変換器☆ Haskell => C言語 への変換器☆ Haskell => C言語 への変換器☆ Haskell => C言語 への変換器☆ Haskell => C言語 への変換器
☆ jhc Haskellコンパイラのfork☆ jhc Haskellコンパイラのfork☆ jhc Haskellコンパイラのfork☆ jhc Haskellコンパイラのfork☆ jhc Haskellコンパイラのfork
☆ mbedプラットフォームなどで動作☆ mbedプラットフォームなどで動作☆ mbedプラットフォームなどで動作☆ mbedプラットフォームなどで動作☆ mbedプラットフォームなどで動作
☆ 要求RAMサイズ = 30kBぐらい☆ 要求RAMサイズ = 30kBぐらい☆ 要求RAMサイズ = 30kBぐらい☆ 要求RAMサイズ = 30kBぐらい☆ 要求RAMサイズ = 30kBぐらい
☆ もちろんPOSIXの上でも動きます☆ もちろんPOSIXの上でも動きます☆ もちろんPOSIXの上でも動きます☆ もちろんPOSIXの上でも動きます☆ もちろんPOSIXの上でも動きます
宣伝: 「簡約!?λカ娘 Go!」はイカが?宣伝: 「簡約!?λカ娘 Go!」はイカが?宣伝: 「簡約!?λカ娘 Go!」はイカが?宣伝: 「簡約!?λカ娘 Go!」はイカが?宣伝: 「簡約!?λカ娘 Go!」はイカが?
http://www.paraiso-lang.org/ikmsm/http://www.paraiso-lang.org/ikmsm/http://www.paraiso-lang.org/ikmsm/http://www.paraiso-lang.org/ikmsm/http://www.paraiso-lang.org/ikmsm/
☆ Lensライブラリの解説☆ Lensライブラリの解説☆ Lensライブラリの解説☆ Lensライブラリの解説☆ Lensライブラリの解説
☆ パーサの解説☆ パーサの解説☆ パーサの解説☆ パーサの解説☆ パーサの解説
☆ 圏論とモナド☆ 圏論とモナド☆ 圏論とモナド☆ 圏論とモナド☆ 圏論とモナド
☆ 囲碁AI☆ 囲碁AI☆ 囲碁AI☆ 囲碁AI☆ 囲碁AI
☆ Ajhcコンパイラの開発秘話☆ Ajhcコンパイラの開発秘話☆ Ajhcコンパイラの開発秘話☆ Ajhcコンパイラの開発秘話☆ Ajhcコンパイラの開発秘話
などなどの話題を掲載!などなどの話題を掲載!などなどの話題を掲載!などなどの話題を掲載!などなどの話題を掲載!

Mais conteúdo relacionado

Mais procurados

ReVIEWとLibreOfficeとOMakeで本を書きましょう!
ReVIEWとLibreOfficeとOMakeで本を書きましょう!ReVIEWとLibreOfficeとOMakeで本を書きましょう!
ReVIEWとLibreOfficeとOMakeで本を書きましょう!Kiwamu Okabe
 
組込Haskellとλカ娘本の紹介
組込Haskellとλカ娘本の紹介組込Haskellとλカ娘本の紹介
組込Haskellとλカ娘本の紹介Kiwamu Okabe
 
Apacheの展望とmod_perlの超絶技巧 #yapcasia
Apacheの展望とmod_perlの超絶技巧 #yapcasiaApacheの展望とmod_perlの超絶技巧 #yapcasia
Apacheの展望とmod_perlの超絶技巧 #yapcasia鉄次 尾形
 
Firefox Add-on SDK 入門
Firefox Add-on SDK 入門Firefox Add-on SDK 入門
Firefox Add-on SDK 入門Shoot Morii
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目龍一 田中
 
GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法博文 斉藤
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Yasutaka Kawamoto
 
20120516 第7回ウフィカ社内ハンズオン Git基礎
20120516 第7回ウフィカ社内ハンズオン Git基礎20120516 第7回ウフィカ社内ハンズオン Git基礎
20120516 第7回ウフィカ社内ハンズオン Git基礎Makoto Yamazaki
 
debexpo(mentors.d.n)をハックするには
debexpo(mentors.d.n)をハックするにはdebexpo(mentors.d.n)をハックするには
debexpo(mentors.d.n)をハックするにはkenhys
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoShoot Morii
 
Dockerのディスクについて ~ファイルシステム・マウント方法など~
Dockerのディスクについて ~ファイルシステム・マウント方法など~Dockerのディスクについて ~ファイルシステム・マウント方法など~
Dockerのディスクについて ~ファイルシステム・マウント方法など~HommasSlide
 
2017年春のPerl
2017年春のPerl2017年春のPerl
2017年春のPerlcharsbar
 
mbedではじめる組み込みHaskellプログラミング
mbedではじめる組み込みHaskellプログラミングmbedではじめる組み込みHaskellプログラミング
mbedではじめる組み込みHaskellプログラミングKiwamu Okabe
 
Clojureで作る"simple"なDSL
Clojureで作る"simple"なDSLClojureで作る"simple"なDSL
Clojureで作る"simple"なDSLKent Ohashi
 
オンプレ&HTTP Proxyな環境でRancherOS入れてみた話
オンプレ&HTTP Proxyな環境でRancherOS入れてみた話オンプレ&HTTP Proxyな環境でRancherOS入れてみた話
オンプレ&HTTP Proxyな環境でRancherOS入れてみた話YASUKAZU NAGATOMI
 

Mais procurados (20)

ReVIEWとLibreOfficeとOMakeで本を書きましょう!
ReVIEWとLibreOfficeとOMakeで本を書きましょう!ReVIEWとLibreOfficeとOMakeで本を書きましょう!
ReVIEWとLibreOfficeとOMakeで本を書きましょう!
 
組込Haskellとλカ娘本の紹介
組込Haskellとλカ娘本の紹介組込Haskellとλカ娘本の紹介
組込Haskellとλカ娘本の紹介
 
Apacheの展望とmod_perlの超絶技巧 #yapcasia
Apacheの展望とmod_perlの超絶技巧 #yapcasiaApacheの展望とmod_perlの超絶技巧 #yapcasia
Apacheの展望とmod_perlの超絶技巧 #yapcasia
 
Firefox Add-on SDK 入門
Firefox Add-on SDK 入門Firefox Add-on SDK 入門
Firefox Add-on SDK 入門
 
Yesod on Heroku
Yesod on HerokuYesod on Heroku
Yesod on Heroku
 
Web技術勉強会23回目
Web技術勉強会23回目Web技術勉強会23回目
Web技術勉強会23回目
 
GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法GNU awk (gawk) を用いた Apache ログ解析方法
GNU awk (gawk) を用いた Apache ログ解析方法
 
Git (実践入門編)
Git (実践入門編)Git (実践入門編)
Git (実践入門編)
 
Gossip事始め
Gossip事始めGossip事始め
Gossip事始め
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方
 
20120516 第7回ウフィカ社内ハンズオン Git基礎
20120516 第7回ウフィカ社内ハンズオン Git基礎20120516 第7回ウフィカ社内ハンズオン Git基礎
20120516 第7回ウフィカ社内ハンズオン Git基礎
 
debexpo(mentors.d.n)をハックするには
debexpo(mentors.d.n)をハックするにはdebexpo(mentors.d.n)をハックするには
debexpo(mentors.d.n)をハックするには
 
ICHIGEKI-MT 2015/03/14
ICHIGEKI-MT 2015/03/14ICHIGEKI-MT 2015/03/14
ICHIGEKI-MT 2015/03/14
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
 
Dockerのディスクについて ~ファイルシステム・マウント方法など~
Dockerのディスクについて ~ファイルシステム・マウント方法など~Dockerのディスクについて ~ファイルシステム・マウント方法など~
Dockerのディスクについて ~ファイルシステム・マウント方法など~
 
2017年春のPerl
2017年春のPerl2017年春のPerl
2017年春のPerl
 
mbedではじめる組み込みHaskellプログラミング
mbedではじめる組み込みHaskellプログラミングmbedではじめる組み込みHaskellプログラミング
mbedではじめる組み込みHaskellプログラミング
 
Python入門
Python入門Python入門
Python入門
 
Clojureで作る"simple"なDSL
Clojureで作る"simple"なDSLClojureで作る"simple"なDSL
Clojureで作る"simple"なDSL
 
オンプレ&HTTP Proxyな環境でRancherOS入れてみた話
オンプレ&HTTP Proxyな環境でRancherOS入れてみた話オンプレ&HTTP Proxyな環境でRancherOS入れてみた話
オンプレ&HTTP Proxyな環境でRancherOS入れてみた話
 

Destaque

Tread Gently – Go Green - Ideas and Activities For Youth Groups
Tread Gently – Go Green - Ideas and Activities For Youth Groups  Tread Gently – Go Green - Ideas and Activities For Youth Groups
Tread Gently – Go Green - Ideas and Activities For Youth Groups PX6
 
Yuri Gagarin Poster 2011
Yuri Gagarin Poster 2011Yuri Gagarin Poster 2011
Yuri Gagarin Poster 2011Patrick_Myles
 
SyMAP Master's Thesis Presentation
SyMAP Master's Thesis PresentationSyMAP Master's Thesis Presentation
SyMAP Master's Thesis Presentationaustinps
 
Samsung Camera i85 User Manual
Samsung Camera i85 User ManualSamsung Camera i85 User Manual
Samsung Camera i85 User ManualImaging Samsung
 
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika AldabaLightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldabaux singapore
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting PersonalKirsty Hulse
 

Destaque (6)

Tread Gently – Go Green - Ideas and Activities For Youth Groups
Tread Gently – Go Green - Ideas and Activities For Youth Groups  Tread Gently – Go Green - Ideas and Activities For Youth Groups
Tread Gently – Go Green - Ideas and Activities For Youth Groups
 
Yuri Gagarin Poster 2011
Yuri Gagarin Poster 2011Yuri Gagarin Poster 2011
Yuri Gagarin Poster 2011
 
SyMAP Master's Thesis Presentation
SyMAP Master's Thesis PresentationSyMAP Master's Thesis Presentation
SyMAP Master's Thesis Presentation
 
Samsung Camera i85 User Manual
Samsung Camera i85 User ManualSamsung Camera i85 User Manual
Samsung Camera i85 User Manual
 
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika AldabaLightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
Lightning Talk #9: How UX and Data Storytelling Can Shape Policy by Mika Aldaba
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting Personal
 

Semelhante a ocamloptの全体像

Debianを用いたCortex-M3マイコン開発事例のご紹介
Debianを用いたCortex-M3マイコン開発事例のご紹介Debianを用いたCortex-M3マイコン開発事例のご紹介
Debianを用いたCortex-M3マイコン開発事例のご紹介Kiwamu Okabe
 
Itcamp長崎2012 capistrano
Itcamp長崎2012 capistranoItcamp長崎2012 capistrano
Itcamp長崎2012 capistranokumachang_LL
 
super_unkoをスーパーキレイにした
super_unkoをスーパーキレイにしたsuper_unkoをスーパーキレイにした
super_unkoをスーパーキレイにしたjiro4989
 
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2tamtam180
 
Getting Started GraalVM (再アップロード)
Getting Started GraalVM (再アップロード)Getting Started GraalVM (再アップロード)
Getting Started GraalVM (再アップロード)tamtam180
 
Ajhcコンパイラの押売りに来ました
Ajhcコンパイラの押売りに来ましたAjhcコンパイラの押売りに来ました
Ajhcコンパイラの押売りに来ましたKiwamu Okabe
 
家に帰るまでが遠足です
家に帰るまでが遠足です家に帰るまでが遠足です
家に帰るまでが遠足ですCryolite
 
恋に落ちるデプロイツール
恋に落ちるデプロイツール恋に落ちるデプロイツール
恋に落ちるデプロイツールtotty jp
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Ransui Iso
 
組込向けHaskellコンパイラAjhc / mbedマイコンどうでしょう編
組込向けHaskellコンパイラAjhc / mbedマイコンどうでしょう編組込向けHaskellコンパイラAjhc / mbedマイコンどうでしょう編
組込向けHaskellコンパイラAjhc / mbedマイコンどうでしょう編Kiwamu Okabe
 
mbed+Haskellどうでしょう
mbed+Haskellどうでしょうmbed+Haskellどうでしょう
mbed+HaskellどうでしょうKiwamu Okabe
 
Programming camp Codereading
Programming camp CodereadingProgramming camp Codereading
Programming camp CodereadingHiro Yoshioka
 
ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!Yohei Fushii
 
いまさら聞けないRake入門
いまさら聞けないRake入門いまさら聞けないRake入門
いまさら聞けないRake入門Tomoya Kawanishi
 
Dive into the Cloud with our buddy, lovely PHP!
Dive into the Cloud with our buddy, lovely PHP!Dive into the Cloud with our buddy, lovely PHP!
Dive into the Cloud with our buddy, lovely PHP!Sotaro Omura
 

Semelhante a ocamloptの全体像 (20)

Debianを用いたCortex-M3マイコン開発事例のご紹介
Debianを用いたCortex-M3マイコン開発事例のご紹介Debianを用いたCortex-M3マイコン開発事例のご紹介
Debianを用いたCortex-M3マイコン開発事例のご紹介
 
Itcamp長崎2012 capistrano
Itcamp長崎2012 capistranoItcamp長崎2012 capistrano
Itcamp長崎2012 capistrano
 
super_unkoをスーパーキレイにした
super_unkoをスーパーキレイにしたsuper_unkoをスーパーキレイにした
super_unkoをスーパーキレイにした
 
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
Getting Started GraalVM / GraalVM超入門 #jjug_ccc #ccc_c2
 
Getting Started GraalVM (再アップロード)
Getting Started GraalVM (再アップロード)Getting Started GraalVM (再アップロード)
Getting Started GraalVM (再アップロード)
 
らくちん Go言語
らくちん Go言語らくちん Go言語
らくちん Go言語
 
Ajhcコンパイラの押売りに来ました
Ajhcコンパイラの押売りに来ましたAjhcコンパイラの押売りに来ました
Ajhcコンパイラの押売りに来ました
 
家に帰るまでが遠足です
家に帰るまでが遠足です家に帰るまでが遠足です
家に帰るまでが遠足です
 
恋に落ちるデプロイツール
恋に落ちるデプロイツール恋に落ちるデプロイツール
恋に落ちるデプロイツール
 
Haikara
HaikaraHaikara
Haikara
 
Ilstudy001_20110806
Ilstudy001_20110806Ilstudy001_20110806
Ilstudy001_20110806
 
Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6Lisp Tutorial for Pythonista Day 6
Lisp Tutorial for Pythonista Day 6
 
組込向けHaskellコンパイラAjhc / mbedマイコンどうでしょう編
組込向けHaskellコンパイラAjhc / mbedマイコンどうでしょう編組込向けHaskellコンパイラAjhc / mbedマイコンどうでしょう編
組込向けHaskellコンパイラAjhc / mbedマイコンどうでしょう編
 
mbed+Haskellどうでしょう
mbed+Haskellどうでしょうmbed+Haskellどうでしょう
mbed+Haskellどうでしょう
 
Programming camp Codereading
Programming camp CodereadingProgramming camp Codereading
Programming camp Codereading
 
ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!ホームディレクトリに埋もれた便利なコードをさがせ!
ホームディレクトリに埋もれた便利なコードをさがせ!
 
いまさら聞けないRake入門
いまさら聞けないRake入門いまさら聞けないRake入門
いまさら聞けないRake入門
 
Niigata.pm #1
Niigata.pm #1Niigata.pm #1
Niigata.pm #1
 
実は怖くないDevOps
実は怖くないDevOps実は怖くないDevOps
実は怖くないDevOps
 
Dive into the Cloud with our buddy, lovely PHP!
Dive into the Cloud with our buddy, lovely PHP!Dive into the Cloud with our buddy, lovely PHP!
Dive into the Cloud with our buddy, lovely PHP!
 

Último

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 

Último (8)

NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 

ocamloptの全体像

  • 2. 私は誰?私は誰?私は誰?私は誰?私は誰? ☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q☆ Twitter: @master_q ☆ Metasepiプロジェクト主催☆ Metasepiプロジェクト主催☆ Metasepiプロジェクト主催☆ Metasepiプロジェクト主催☆ Metasepiプロジェクト主催 ☆ Ajhc Haskellコンパイラ開発者☆ Ajhc Haskellコンパイラ開発者☆ Ajhc Haskellコンパイラ開発者☆ Ajhc Haskellコンパイラ開発者☆ Ajhc Haskellコンパイラ開発者 ☆ Debian Maintainer☆ Debian Maintainer☆ Debian Maintainer☆ Debian Maintainer☆ Debian Maintainer ☆ 前はデジタルサイネージの開発してました☆ 前はデジタルサイネージの開発してました☆ 前はデジタルサイネージの開発してました☆ 前はデジタルサイネージの開発してました☆ 前はデジタルサイネージの開発してました ☆ その昔はNetBSDでコピー機作ってた☆ その昔はNetBSDでコピー機作ってた☆ その昔はNetBSDでコピー機作ってた☆ その昔はNetBSDでコピー機作ってた☆ その昔はNetBSDでコピー機作ってた
  • 3. ぼくとOCamlぼくとOCamlぼくとOCamlぼくとOCamlぼくとOCaml ☆ 最初の会社で社内勉強会☆ 最初の会社で社内勉強会☆ 最初の会社で社内勉強会☆ 最初の会社で社内勉強会☆ 最初の会社で社内勉強会 ☆ letの嵐にとまどう☆ letの嵐にとまどう☆ letの嵐にとまどう☆ letの嵐にとまどう☆ letの嵐にとまどう ☆ 数年後にPFDSを読む☆ 数年後にPFDSを読む☆ 数年後にPFDSを読む☆ 数年後にPFDSを読む☆ 数年後にPFDSを読む ☆ lazyきもちいい!☆ lazyきもちいい!☆ lazyきもちいい!☆ lazyきもちいい!☆ lazyきもちいい! ☆ camlp4に脳味噌を焼きはらわれる...☆ camlp4に脳味噌を焼きはらわれる...☆ camlp4に脳味噌を焼きはらわれる...☆ camlp4に脳味噌を焼きはらわれる...☆ camlp4に脳味噌を焼きはらわれる... ☆ camloebaさんに脅されてocamlopt読む☆ camloebaさんに脅されてocamlopt読む☆ camloebaさんに脅されてocamlopt読む☆ camloebaさんに脅されてocamlopt読む☆ camloebaさんに脅されてocamlopt読む ☆ OCamlコードわかりやすい! <= イマココ☆ OCamlコードわかりやすい! <= イマココ☆ OCamlコードわかりやすい! <= イマココ☆ OCamlコードわかりやすい! <= イマココ☆ OCamlコードわかりやすい! <= イマココ
  • 4. 今日のもくじ今日のもくじ今日のもくじ今日のもくじ今日のもくじ ☆ [1] ocamloptについて簡単に☆ [1] ocamloptについて簡単に☆ [1] ocamloptについて簡単に☆ [1] ocamloptについて簡単に☆ [1] ocamloptについて簡単に ☆ [2] ソース探検のシナリオ☆ [2] ソース探検のシナリオ☆ [2] ソース探検のシナリオ☆ [2] ソース探検のシナリオ☆ [2] ソース探検のシナリオ ☆ [3] プログラムの起動☆ [3] プログラムの起動☆ [3] プログラムの起動☆ [3] プログラムの起動☆ [3] プログラムの起動 ☆ [4] 文字列を画面に印字☆ [4] 文字列を画面に印字☆ [4] 文字列を画面に印字☆ [4] 文字列を画面に印字☆ [4] 文字列を画面に印字 ☆ [5] シグナルの扱い☆ [5] シグナルの扱い☆ [5] シグナルの扱い☆ [5] シグナルの扱い☆ [5] シグナルの扱い
  • 5. [1] ocamloptについて簡単に[1] ocamloptについて簡単に[1] ocamloptについて簡単に[1] ocamloptについて簡単に[1] ocamloptについて簡単に まずはOCaml 4.00.1をインストールまずはOCaml 4.00.1をインストールまずはOCaml 4.00.1をインストールまずはOCaml 4.00.1をインストールまずはOCaml 4.00.1をインストール $ git clone git@github.com:ocaml/ocaml.git $ cd ocaml $ git checkout 4.00.1 $ sudo apt-get build-dep ocaml $ ./configure -with-debug-runtime $ make world.opt $ sudo make install $ which ocamlopt /usr/local/bin/ocamlopt $ ocamlopt -version 4.00.1 $ git clone git@github.com:ocaml/ocaml.git $ cd ocaml $ git checkout 4.00.1 $ sudo apt-get build-dep ocaml $ ./configure -with-debug-runtime $ make world.opt $ sudo make install $ which ocamlopt /usr/local/bin/ocamlopt $ ocamlopt -version 4.00.1 $ git clone git@github.com:ocaml/ocaml.git $ cd ocaml $ git checkout 4.00.1 $ sudo apt-get build-dep ocaml $ ./configure -with-debug-runtime $ make world.opt $ sudo make install $ which ocamlopt /usr/local/bin/ocamlopt $ ocamlopt -version 4.00.1 $ git clone git@github.com:ocaml/ocaml.git $ cd ocaml $ git checkout 4.00.1 $ sudo apt-get build-dep ocaml $ ./configure -with-debug-runtime $ make world.opt $ sudo make install $ which ocamlopt /usr/local/bin/ocamlopt $ ocamlopt -version 4.00.1 $ git clone git@github.com:ocaml/ocaml.git $ cd ocaml $ git checkout 4.00.1 $ sudo apt-get build-dep ocaml $ ./configure -with-debug-runtime $ make world.opt $ sudo make install $ which ocamlopt /usr/local/bin/ocamlopt $ ocamlopt -version 4.00.1 想定環境想定環境想定環境想定環境想定環境 ☆ Debian GNU/Linux sid amd64☆ Debian GNU/Linux sid amd64☆ Debian GNU/Linux sid amd64☆ Debian GNU/Linux sid amd64☆ Debian GNU/Linux sid amd64
  • 6. ocamloptってなんどすか?ocamloptってなんどすか?ocamloptってなんどすか?ocamloptってなんどすか?ocamloptってなんどすか? OCamlソースを実行バイナリにするコンパイラOCamlソースを実行バイナリにするコンパイラOCamlソースを実行バイナリにするコンパイラOCamlソースを実行バイナリにするコンパイラOCamlソースを実行バイナリにするコンパイラ $ cat hello.ml let hello _ = print_endline "Hello world!";; let _ = hello (); $ ocamlopt -g -runtime-variant d -o hello.bin hello.ml $ file hello.bin hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not stripped $ ./hello.bin ### OCaml runtime: debug mode ### Initial minor heap size: 2048k bytes Initial major heap size: 992k bytes Initial space overhead: 80% Initial max overhead: 500% Initial heap increment: 992k bytes Initial allocation policy: 0 Hello world! $ cat hello.ml let hello _ = print_endline "Hello world!";; let _ = hello (); $ ocamlopt -g -runtime-variant d -o hello.bin hello.ml $ file hello.bin hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not stripped $ ./hello.bin ### OCaml runtime: debug mode ### Initial minor heap size: 2048k bytes Initial major heap size: 992k bytes Initial space overhead: 80% Initial max overhead: 500% Initial heap increment: 992k bytes Initial allocation policy: 0 Hello world! $ cat hello.ml let hello _ = print_endline "Hello world!";; let _ = hello (); $ ocamlopt -g -runtime-variant d -o hello.bin hello.ml $ file hello.bin hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not stripped $ ./hello.bin ### OCaml runtime: debug mode ### Initial minor heap size: 2048k bytes Initial major heap size: 992k bytes Initial space overhead: 80% Initial max overhead: 500% Initial heap increment: 992k bytes Initial allocation policy: 0 Hello world! $ cat hello.ml let hello _ = print_endline "Hello world!";; let _ = hello (); $ ocamlopt -g -runtime-variant d -o hello.bin hello.ml $ file hello.bin hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not stripped $ ./hello.bin ### OCaml runtime: debug mode ### Initial minor heap size: 2048k bytes Initial major heap size: 992k bytes Initial space overhead: 80% Initial max overhead: 500% Initial heap increment: 992k bytes Initial allocation policy: 0 Hello world! $ cat hello.ml let hello _ = print_endline "Hello world!";; let _ = hello (); $ ocamlopt -g -runtime-variant d -o hello.bin hello.ml $ file hello.bin hello.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=402030a9bb82606a9d38f73e6ec25455f96d3caf, not stripped $ ./hello.bin ### OCaml runtime: debug mode ### Initial minor heap size: 2048k bytes Initial major heap size: 992k bytes Initial space overhead: 80% Initial max overhead: 500% Initial heap increment: 992k bytes Initial allocation policy: 0 Hello world!
  • 7. -with-debug-runtime? -g?-with-debug-runtime? -g?-with-debug-runtime? -g?-with-debug-runtime? -g?-with-debug-runtime? -g? ☆ objdump -S hello.bin してみると...☆ objdump -S hello.bin してみると...☆ objdump -S hello.bin してみると...☆ objdump -S hello.bin してみると...☆ objdump -S hello.bin してみると...
  • 8. どーいうことだってばよ!?どーいうことだってばよ!?どーいうことだってばよ!?どーいうことだってばよ!?どーいうことだってばよ!? ☆ objdumpやgdbで☆ objdumpやgdbで☆ objdumpやgdbで☆ objdumpやgdbで☆ objdumpやgdbで ☆ 実行バイナリの中の☆ 実行バイナリの中の☆ 実行バイナリの中の☆ 実行バイナリの中の☆ 実行バイナリの中の ☆ コンパイル結果マシン語と☆ コンパイル結果マシン語と☆ コンパイル結果マシン語と☆ コンパイル結果マシン語と☆ コンパイル結果マシン語と ☆ ランタイムのマシン語の両方を☆ ランタイムのマシン語の両方を☆ ランタイムのマシン語の両方を☆ ランタイムのマシン語の両方を☆ ランタイムのマシン語の両方を ☆ ソースコードレベルデバッグできる☆ ソースコードレベルデバッグできる☆ ソースコードレベルデバッグできる☆ ソースコードレベルデバッグできる☆ ソースコードレベルデバッグできる すばらしい!すばらしい!すばらしい!すばらしい!すばらしい!
  • 9. [2] ソース探検のシナリオ[2] ソース探検のシナリオ[2] ソース探検のシナリオ[2] ソース探検のシナリオ[2] ソース探検のシナリオ
  • 10. [3] プログラムの起動[3] プログラムの起動[3] プログラムの起動[3] プログラムの起動[3] プログラムの起動 ☆ main関数から実行が開始されて☆ main関数から実行が開始されて☆ main関数から実行が開始されて☆ main関数から実行が開始されて☆ main関数から実行が開始されて ☆ camlHello__entry関数がプログラム入口☆ camlHello__entry関数がプログラム入口☆ camlHello__entry関数がプログラム入口☆ camlHello__entry関数がプログラム入口☆ camlHello__entry関数がプログラム入口 $ ocamlopt -o hello.bin hello.ml $ gdb hello.bin (gdb) b camlHello__entry Breakpoint 1 at 0x402260 (gdb) run ... Breakpoint 1, 0x0000000000402260 in camlHello__entry () (gdb) bt #0 0x0000000000402260 in camlHello__entry () #1 0x0000000000401e89 in caml_program () #2 0x0000000000410d82 in caml_start_program () #3 0x0000000000411245 in caml_main () #4 0x000000000040414e in main () $ ocamlopt -o hello.bin hello.ml $ gdb hello.bin (gdb) b camlHello__entry Breakpoint 1 at 0x402260 (gdb) run ... Breakpoint 1, 0x0000000000402260 in camlHello__entry () (gdb) bt #0 0x0000000000402260 in camlHello__entry () #1 0x0000000000401e89 in caml_program () #2 0x0000000000410d82 in caml_start_program () #3 0x0000000000411245 in caml_main () #4 0x000000000040414e in main () $ ocamlopt -o hello.bin hello.ml $ gdb hello.bin (gdb) b camlHello__entry Breakpoint 1 at 0x402260 (gdb) run ... Breakpoint 1, 0x0000000000402260 in camlHello__entry () (gdb) bt #0 0x0000000000402260 in camlHello__entry () #1 0x0000000000401e89 in caml_program () #2 0x0000000000410d82 in caml_start_program () #3 0x0000000000411245 in caml_main () #4 0x000000000040414e in main () $ ocamlopt -o hello.bin hello.ml $ gdb hello.bin (gdb) b camlHello__entry Breakpoint 1 at 0x402260 (gdb) run ... Breakpoint 1, 0x0000000000402260 in camlHello__entry () (gdb) bt #0 0x0000000000402260 in camlHello__entry () #1 0x0000000000401e89 in caml_program () #2 0x0000000000410d82 in caml_start_program () #3 0x0000000000411245 in caml_main () #4 0x000000000040414e in main () $ ocamlopt -o hello.bin hello.ml $ gdb hello.bin (gdb) b camlHello__entry Breakpoint 1 at 0x402260 (gdb) run ... Breakpoint 1, 0x0000000000402260 in camlHello__entry () (gdb) bt #0 0x0000000000402260 in camlHello__entry () #1 0x0000000000401e89 in caml_program () #2 0x0000000000410d82 in caml_start_program () #3 0x0000000000411245 in caml_main () #4 0x000000000040414e in main ()
  • 11. main関数はどこに?main関数はどこに?main関数はどこに?main関数はどこに?main関数はどこに? ☆ "byterun/main.c"です☆ "byterun/main.c"です☆ "byterun/main.c"です☆ "byterun/main.c"です☆ "byterun/main.c"です ☆ え?バイトコード?☆ え?バイトコード?☆ え?バイトコード?☆ え?バイトコード?☆ え?バイトコード? ☆ "{byte,asm}run"のディレクトリがある☆ "{byte,asm}run"のディレクトリがある☆ "{byte,asm}run"のディレクトリがある☆ "{byte,asm}run"のディレクトリがある☆ "{byte,asm}run"のディレクトリがある ☆ でもなんかきっちり分離されていない☆ でもなんかきっちり分離されていない☆ でもなんかきっちり分離されていない☆ でもなんかきっちり分離されていない☆ でもなんかきっちり分離されていない ☆ バイナリでも適宜byterunの下を使います☆ バイナリでも適宜byterunの下を使います☆ バイナリでも適宜byterunの下を使います☆ バイナリでも適宜byterunの下を使います☆ バイナリでも適宜byterunの下を使います
  • 12. main関数ソースmain関数ソースmain関数ソースmain関数ソースmain関数ソース デバッグ機能なしだとこんなんデバッグ機能なしだとこんなんデバッグ機能なしだとこんなんデバッグ機能なしだとこんなんデバッグ機能なしだとこんなん /* File: byterun/main.c */ int main(int argc, char **argv) { caml_main(argv); caml_sys_exit(Val_int(0)); return 0; } /* File: byterun/main.c */ int main(int argc, char **argv) { caml_main(argv); caml_sys_exit(Val_int(0)); return 0; } /* File: byterun/main.c */ int main(int argc, char **argv) { caml_main(argv); caml_sys_exit(Val_int(0)); return 0; } /* File: byterun/main.c */ int main(int argc, char **argv) { caml_main(argv); caml_sys_exit(Val_int(0)); return 0; } /* File: byterun/main.c */ int main(int argc, char **argv) { caml_main(argv); caml_sys_exit(Val_int(0)); return 0; } むちゃくちゃ簡単ですむちゃくちゃ簡単ですむちゃくちゃ簡単ですむちゃくちゃ簡単ですむちゃくちゃ簡単です
  • 14. caml_init_ieee_floats関数caml_init_ieee_floats関数caml_init_ieee_floats関数caml_init_ieee_floats関数caml_init_ieee_floats関数 /* File: byterun/floats.c */ /* The [caml_init_ieee_float] function should initialize floating-point hardware so that it behaves as much as possible like the IEEE standard. In particular, return special numbers like Infinity and NaN instead of signalling exceptions. Currently, everyone is in IEEE mode at program startup, except FreeBSD prior to 4.0R. */ /* --snip-- */ void caml_init_ieee_floats(void) { #if defined(__FreeBSD__) && (__FreeBSD_version < 400017) fpsetmask(0); #endif } /* File: byterun/floats.c */ /* The [caml_init_ieee_float] function should initialize floating-point hardware so that it behaves as much as possible like the IEEE standard. In particular, return special numbers like Infinity and NaN instead of signalling exceptions. Currently, everyone is in IEEE mode at program startup, except FreeBSD prior to 4.0R. */ /* --snip-- */ void caml_init_ieee_floats(void) { #if defined(__FreeBSD__) && (__FreeBSD_version < 400017) fpsetmask(0); #endif } /* File: byterun/floats.c */ /* The [caml_init_ieee_float] function should initialize floating-point hardware so that it behaves as much as possible like the IEEE standard. In particular, return special numbers like Infinity and NaN instead of signalling exceptions. Currently, everyone is in IEEE mode at program startup, except FreeBSD prior to 4.0R. */ /* --snip-- */ void caml_init_ieee_floats(void) { #if defined(__FreeBSD__) && (__FreeBSD_version < 400017) fpsetmask(0); #endif } /* File: byterun/floats.c */ /* The [caml_init_ieee_float] function should initialize floating-point hardware so that it behaves as much as possible like the IEEE standard. In particular, return special numbers like Infinity and NaN instead of signalling exceptions. Currently, everyone is in IEEE mode at program startup, except FreeBSD prior to 4.0R. */ /* --snip-- */ void caml_init_ieee_floats(void) { #if defined(__FreeBSD__) && (__FreeBSD_version < 400017) fpsetmask(0); #endif } /* File: byterun/floats.c */ /* The [caml_init_ieee_float] function should initialize floating-point hardware so that it behaves as much as possible like the IEEE standard. In particular, return special numbers like Infinity and NaN instead of signalling exceptions. Currently, everyone is in IEEE mode at program startup, except FreeBSD prior to 4.0R. */ /* --snip-- */ void caml_init_ieee_floats(void) { #if defined(__FreeBSD__) && (__FreeBSD_version < 400017) fpsetmask(0); #endif } ☆ FreeBSDへのバグ対策?☆ FreeBSDへのバグ対策?☆ FreeBSDへのバグ対策?☆ FreeBSDへのバグ対策?☆ FreeBSDへのバグ対策? ☆ 気にしないことにしましょう☆ 気にしないことにしましょう☆ 気にしないことにしましょう☆ 気にしないことにしましょう☆ 気にしないことにしましょう
  • 15. caml_init_custom_operations #1caml_init_custom_operations #1caml_init_custom_operations #1caml_init_custom_operations #1caml_init_custom_operations #1 ボックス化されたintのプリミティブ関数を登録ボックス化されたintのプリミティブ関数を登録ボックス化されたintのプリミティブ関数を登録ボックス化されたintのプリミティブ関数を登録ボックス化されたintのプリミティブ関数を登録 /* File: byterun/custom.c */ void caml_init_custom_operations(void) { caml_register_custom_operations(&caml_int32_ops); caml_register_custom_operations(&caml_nativeint_ops); caml_register_custom_operations(&caml_int64_ops); } /* File: byterun/custom.c */ void caml_init_custom_operations(void) { caml_register_custom_operations(&caml_int32_ops); caml_register_custom_operations(&caml_nativeint_ops); caml_register_custom_operations(&caml_int64_ops); } /* File: byterun/custom.c */ void caml_init_custom_operations(void) { caml_register_custom_operations(&caml_int32_ops); caml_register_custom_operations(&caml_nativeint_ops); caml_register_custom_operations(&caml_int64_ops); } /* File: byterun/custom.c */ void caml_init_custom_operations(void) { caml_register_custom_operations(&caml_int32_ops); caml_register_custom_operations(&caml_nativeint_ops); caml_register_custom_operations(&caml_int64_ops); } /* File: byterun/custom.c */ void caml_init_custom_operations(void) { caml_register_custom_operations(&caml_int32_ops); caml_register_custom_operations(&caml_nativeint_ops); caml_register_custom_operations(&caml_int64_ops); }
  • 16. caml_init_custom_operations #2caml_init_custom_operations #2caml_init_custom_operations #2caml_init_custom_operations #2caml_init_custom_operations #2 でもたぶんこれバイトコードでだけ必要?でもたぶんこれバイトコードでだけ必要?でもたぶんこれバイトコードでだけ必要?でもたぶんこれバイトコードでだけ必要?でもたぶんこれバイトコードでだけ必要? $ grep "caml_.*_ops" asmcomp/cmmgen.ml Pnativeint -> "caml_nativeint_ops" | Pint32 -> "caml_int32_ops" | Pint64 -> "caml_int64_ops" Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n :: cont Csymbol_address("caml_int32_ops") :: Cint n :: cont Csymbol_address("caml_nativeint_ops") :: Cint n :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi :: cont $ grep "caml_.*_ops" asmcomp/cmmgen.ml Pnativeint -> "caml_nativeint_ops" | Pint32 -> "caml_int32_ops" | Pint64 -> "caml_int64_ops" Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n :: cont Csymbol_address("caml_int32_ops") :: Cint n :: cont Csymbol_address("caml_nativeint_ops") :: Cint n :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi :: cont $ grep "caml_.*_ops" asmcomp/cmmgen.ml Pnativeint -> "caml_nativeint_ops" | Pint32 -> "caml_int32_ops" | Pint64 -> "caml_int64_ops" Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n :: cont Csymbol_address("caml_int32_ops") :: Cint n :: cont Csymbol_address("caml_nativeint_ops") :: Cint n :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi :: cont $ grep "caml_.*_ops" asmcomp/cmmgen.ml Pnativeint -> "caml_nativeint_ops" | Pint32 -> "caml_int32_ops" | Pint64 -> "caml_int64_ops" Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n :: cont Csymbol_address("caml_int32_ops") :: Cint n :: cont Csymbol_address("caml_nativeint_ops") :: Cint n :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi :: cont $ grep "caml_.*_ops" asmcomp/cmmgen.ml Pnativeint -> "caml_nativeint_ops" | Pint32 -> "caml_int32_ops" | Pint64 -> "caml_int64_ops" Csymbol_address("caml_int32_ops") :: Cint32 n :: Cint32 0n :: cont Csymbol_address("caml_int32_ops") :: Cint n :: cont Csymbol_address("caml_nativeint_ops") :: Cint n :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint hi :: Cint lo :: cont Csymbol_address("caml_int64_ops") :: Cint lo :: Cint hi :: cont ocamloptではシンボルから直接呼び出しにocamloptではシンボルから直接呼び出しにocamloptではシンボルから直接呼び出しにocamloptではシンボルから直接呼び出しにocamloptではシンボルから直接呼び出しに
  • 17. parse_camlrunparam関数parse_camlrunparam関数parse_camlrunparam関数parse_camlrunparam関数parse_camlrunparam関数 OCAMLRUNPARAM環境変数を見るだけOCAMLRUNPARAM環境変数を見るだけOCAMLRUNPARAM環境変数を見るだけOCAMLRUNPARAM環境変数を見るだけOCAMLRUNPARAM環境変数を見るだけ http://caml.inria.fr/pub/docs/manual-ocaml/manual024.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual024.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual024.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual024.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual024.html /* File: asmrun/startup.c */ static void parse_camlrunparam(void) { char *opt = getenv ("OCAMLRUNPARAM"); uintnat p; if (opt == NULL) opt = getenv ("CAMLRUNPARAM"); if (opt != NULL){ while (*opt != '0'){ switch (*opt++){ case 's': scanmult (opt, &minor_heap_init); break; case 'i': scanmult (opt, &heap_chunk_init); break; case 'h': scanmult (opt, &heap_size_init); break; case 'l': scanmult (opt, &max_stack_init); break; case 'o': scanmult (opt, &percent_free_init); break; case 'O': scanmult (opt, &max_percent_free_init); break; case 'v': scanmult (opt, &caml_verb_gc); break; /* File: asmrun/startup.c */ static void parse_camlrunparam(void) { char *opt = getenv ("OCAMLRUNPARAM"); uintnat p; if (opt == NULL) opt = getenv ("CAMLRUNPARAM"); if (opt != NULL){ while (*opt != '0'){ switch (*opt++){ case 's': scanmult (opt, &minor_heap_init); break; case 'i': scanmult (opt, &heap_chunk_init); break; case 'h': scanmult (opt, &heap_size_init); break; case 'l': scanmult (opt, &max_stack_init); break; case 'o': scanmult (opt, &percent_free_init); break; case 'O': scanmult (opt, &max_percent_free_init); break; case 'v': scanmult (opt, &caml_verb_gc); break; /* File: asmrun/startup.c */ static void parse_camlrunparam(void) { char *opt = getenv ("OCAMLRUNPARAM"); uintnat p; if (opt == NULL) opt = getenv ("CAMLRUNPARAM"); if (opt != NULL){ while (*opt != '0'){ switch (*opt++){ case 's': scanmult (opt, &minor_heap_init); break; case 'i': scanmult (opt, &heap_chunk_init); break; case 'h': scanmult (opt, &heap_size_init); break; case 'l': scanmult (opt, &max_stack_init); break; case 'o': scanmult (opt, &percent_free_init); break; case 'O': scanmult (opt, &max_percent_free_init); break; case 'v': scanmult (opt, &caml_verb_gc); break; /* File: asmrun/startup.c */ static void parse_camlrunparam(void) { char *opt = getenv ("OCAMLRUNPARAM"); uintnat p; if (opt == NULL) opt = getenv ("CAMLRUNPARAM"); if (opt != NULL){ while (*opt != '0'){ switch (*opt++){ case 's': scanmult (opt, &minor_heap_init); break; case 'i': scanmult (opt, &heap_chunk_init); break; case 'h': scanmult (opt, &heap_size_init); break; case 'l': scanmult (opt, &max_stack_init); break; case 'o': scanmult (opt, &percent_free_init); break; case 'O': scanmult (opt, &max_percent_free_init); break; case 'v': scanmult (opt, &caml_verb_gc); break; /* File: asmrun/startup.c */ static void parse_camlrunparam(void) { char *opt = getenv ("OCAMLRUNPARAM"); uintnat p; if (opt == NULL) opt = getenv ("CAMLRUNPARAM"); if (opt != NULL){ while (*opt != '0'){ switch (*opt++){ case 's': scanmult (opt, &minor_heap_init); break; case 'i': scanmult (opt, &heap_chunk_init); break; case 'h': scanmult (opt, &heap_size_init); break; case 'l': scanmult (opt, &max_stack_init); break; case 'o': scanmult (opt, &percent_free_init); break; case 'O': scanmult (opt, &max_percent_free_init); break; case 'v': scanmult (opt, &caml_verb_gc); break;
  • 18. caml_init_gc関数caml_init_gc関数caml_init_gc関数caml_init_gc関数caml_init_gc関数 ☆ メジャー/マイナーGC用のヒープ初期化☆ メジャー/マイナーGC用のヒープ初期化☆ メジャー/マイナーGC用のヒープ初期化☆ メジャー/マイナーGC用のヒープ初期化☆ メジャー/マイナーGC用のヒープ初期化 ☆ Real World OCaml読んだ方がいいかも!☆ Real World OCaml読んだ方がいいかも!☆ Real World OCaml読んだ方がいいかも!☆ Real World OCaml読んだ方がいいかも!☆ Real World OCaml読んだ方がいいかも!
  • 19. init_atoms関数init_atoms関数init_atoms関数init_atoms関数init_atoms関数 ☆ これよくわからなかったです orz☆ これよくわからなかったです orz☆ これよくわからなかったです orz☆ これよくわからなかったです orz☆ これよくわからなかったです orz ☆ caml_data_segmentsと☆ caml_data_segmentsと☆ caml_data_segmentsと☆ caml_data_segmentsと☆ caml_data_segmentsと ☆ caml_code_segmentsを解析している?☆ caml_code_segmentsを解析している?☆ caml_code_segmentsを解析している?☆ caml_code_segmentsを解析している?☆ caml_code_segmentsを解析している? ☆ 目的がよくわからない...☆ 目的がよくわからない...☆ 目的がよくわからない...☆ 目的がよくわからない...☆ 目的がよくわからない...
  • 20. caml_init_signals関数caml_init_signals関数caml_init_signals関数caml_init_signals関数caml_init_signals関数 SEGVシグナルハンドラを通常コンテキストと は別のスタックで実行するように設定 SEGVシグナルハンドラを通常コンテキストと は別のスタックで実行するように設定 SEGVシグナルハンドラを通常コンテキストと は別のスタックで実行するように設定 SEGVシグナルハンドラを通常コンテキストと は別のスタックで実行するように設定 SEGVシグナルハンドラを通常コンテキストと は別のスタックで実行するように設定 /* File: asmrun/signals_asm.c */ void caml_init_signals(void) { /* Stack overflow handling */ stack_t stk; struct sigaction act; stk.ss_sp = sig_alt_stack; stk.ss_size = SIGSTKSZ; stk.ss_flags = 0; SET_SIGACT(act, segv_handler); act.sa_flags |= SA_ONSTACK | SA_NODEFER; sigemptyset(&act.sa_mask); system_stack_top = (char *) &act; if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); } } /* File: asmrun/signals_asm.c */ void caml_init_signals(void) { /* Stack overflow handling */ stack_t stk; struct sigaction act; stk.ss_sp = sig_alt_stack; stk.ss_size = SIGSTKSZ; stk.ss_flags = 0; SET_SIGACT(act, segv_handler); act.sa_flags |= SA_ONSTACK | SA_NODEFER; sigemptyset(&act.sa_mask); system_stack_top = (char *) &act; if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); } } /* File: asmrun/signals_asm.c */ void caml_init_signals(void) { /* Stack overflow handling */ stack_t stk; struct sigaction act; stk.ss_sp = sig_alt_stack; stk.ss_size = SIGSTKSZ; stk.ss_flags = 0; SET_SIGACT(act, segv_handler); act.sa_flags |= SA_ONSTACK | SA_NODEFER; sigemptyset(&act.sa_mask); system_stack_top = (char *) &act; if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); } } /* File: asmrun/signals_asm.c */ void caml_init_signals(void) { /* Stack overflow handling */ stack_t stk; struct sigaction act; stk.ss_sp = sig_alt_stack; stk.ss_size = SIGSTKSZ; stk.ss_flags = 0; SET_SIGACT(act, segv_handler); act.sa_flags |= SA_ONSTACK | SA_NODEFER; sigemptyset(&act.sa_mask); system_stack_top = (char *) &act; if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); } } /* File: asmrun/signals_asm.c */ void caml_init_signals(void) { /* Stack overflow handling */ stack_t stk; struct sigaction act; stk.ss_sp = sig_alt_stack; stk.ss_size = SIGSTKSZ; stk.ss_flags = 0; SET_SIGACT(act, segv_handler); act.sa_flags |= SA_ONSTACK | SA_NODEFER; sigemptyset(&act.sa_mask); system_stack_top = (char *) &act; if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); } }
  • 21. segv_handler関数segv_handler関数segv_handler関数segv_handler関数segv_handler関数 ☆ SEGVシグナルで起動☆ SEGVシグナルで起動☆ SEGVシグナルで起動☆ SEGVシグナルで起動☆ SEGVシグナルで起動 ☆ スタック溢れが起きていたら例外発生☆ スタック溢れが起きていたら例外発生☆ スタック溢れが起きていたら例外発生☆ スタック溢れが起きていたら例外発生☆ スタック溢れが起きていたら例外発生 ☆ 最終的にcaml_raise_exceptionを呼ぶ☆ 最終的にcaml_raise_exceptionを呼ぶ☆ 最終的にcaml_raise_exceptionを呼ぶ☆ 最終的にcaml_raise_exceptionを呼ぶ☆ 最終的にcaml_raise_exceptionを呼ぶ
  • 24. つまり?つまり?つまり?つまり?つまり? OCamlサイドOCamlサイドOCamlサイドOCamlサイドOCamlサイド ☆ r14レジスタ: try時スタック☆ r14レジスタ: try時スタック☆ r14レジスタ: try時スタック☆ r14レジスタ: try時スタック☆ r14レジスタ: try時スタック ☆ r15レジスタ: GCヒープへのポインタ☆ r15レジスタ: GCヒープへのポインタ☆ r15レジスタ: GCヒープへのポインタ☆ r15レジスタ: GCヒープへのポインタ☆ r15レジスタ: GCヒープへのポインタ C言語サイドC言語サイドC言語サイドC言語サイドC言語サイド ☆ caml_exception_pointer: try時スタック☆ caml_exception_pointer: try時スタック☆ caml_exception_pointer: try時スタック☆ caml_exception_pointer: try時スタック☆ caml_exception_pointer: try時スタック ☆ caml_young_ptr: GCヒープへのポインタ☆ caml_young_ptr: GCヒープへのポインタ☆ caml_young_ptr: GCヒープへのポインタ☆ caml_young_ptr: GCヒープへのポインタ☆ caml_young_ptr: GCヒープへのポインタ いつでも戻れますねいつでも戻れますねいつでも戻れますねいつでも戻れますねいつでも戻れますね
  • 25. caml_debugger_init関数caml_debugger_init関数caml_debugger_init関数caml_debugger_init関数caml_debugger_init関数 CAML_DEBUG_SOCKET環境変数が定義 されていたらBSDソケットを使ったデバッグ環 境を設定 CAML_DEBUG_SOCKET環境変数が定義 されていたらBSDソケットを使ったデバッグ環 境を設定 CAML_DEBUG_SOCKET環境変数が定義 されていたらBSDソケットを使ったデバッグ環 境を設定 CAML_DEBUG_SOCKET環境変数が定義 されていたらBSDソケットを使ったデバッグ環 境を設定 CAML_DEBUG_SOCKET環境変数が定義 されていたらBSDソケットを使ったデバッグ環 境を設定 http://caml.inria.fr/pub/docs/manual-ocaml/manual030.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual030.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual030.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual030.htmlhttp://caml.inria.fr/pub/docs/manual-ocaml/manual030.html そんなものがあったのか...そんなものがあったのか...そんなものがあったのか...そんなものがあったのか...そんなものがあったのか...
  • 26. caml_sys_init関数caml_sys_init関数caml_sys_init関数caml_sys_init関数caml_sys_init関数 プログラム名と引数の保管プログラム名と引数の保管プログラム名と引数の保管プログラム名と引数の保管プログラム名と引数の保管 /* File: byterun/sys.c */ void caml_sys_init(char * exe_name, char **argv) { caml_exe_name = exe_name; caml_main_argv = argv; } /* File: byterun/sys.c */ void caml_sys_init(char * exe_name, char **argv) { caml_exe_name = exe_name; caml_main_argv = argv; } /* File: byterun/sys.c */ void caml_sys_init(char * exe_name, char **argv) { caml_exe_name = exe_name; caml_main_argv = argv; } /* File: byterun/sys.c */ void caml_sys_init(char * exe_name, char **argv) { caml_exe_name = exe_name; caml_main_argv = argv; } /* File: byterun/sys.c */ void caml_sys_init(char * exe_name, char **argv) { caml_exe_name = exe_name; caml_main_argv = argv; } まぁありがちまぁありがちまぁありがちまぁありがちまぁありがち
  • 28. caml_start_program関数caml_start_program関数caml_start_program関数caml_start_program関数caml_start_program関数 ☆ calleeのレジスタ退避☆ calleeのレジスタ退避☆ calleeのレジスタ退避☆ calleeのレジスタ退避☆ calleeのレジスタ退避 ☆ caml_gc_regsをpush☆ caml_gc_regsをpush☆ caml_gc_regsをpush☆ caml_gc_regsをpush☆ caml_gc_regsをpush ☆ caml_last_return_addressをpush☆ caml_last_return_addressをpush☆ caml_last_return_addressをpush☆ caml_last_return_addressをpush☆ caml_last_return_addressをpush ☆ caml_bottom_of_stackをpush☆ caml_bottom_of_stackをpush☆ caml_bottom_of_stackをpush☆ caml_bottom_of_stackをpush☆ caml_bottom_of_stackをpush ☆ caml_young_ptrを%r15に☆ caml_young_ptrを%r15に☆ caml_young_ptrを%r15に☆ caml_young_ptrを%r15に☆ caml_young_ptrを%r15に ☆ caml_exception_pointerを%r14に☆ caml_exception_pointerを%r14に☆ caml_exception_pointerを%r14に☆ caml_exception_pointerを%r14に☆ caml_exception_pointerを%r14に ☆ caml_program関数呼び出し☆ caml_program関数呼び出し☆ caml_program関数呼び出し☆ caml_program関数呼び出し☆ caml_program関数呼び出し
  • 33. [4] 文字列を画面に印字[4] 文字列を画面に印字[4] 文字列を画面に印字[4] 文字列を画面に印字[4] 文字列を画面に印字 ☆ print_endlineが開始☆ print_endlineが開始☆ print_endlineが開始☆ print_endlineが開始☆ print_endlineが開始
  • 35. [5] シグナルの扱い[5] シグナルの扱い[5] シグナルの扱い[5] シグナルの扱い[5] シグナルの扱い blocking_sectionって何?blocking_sectionって何?blocking_sectionって何?blocking_sectionって何?blocking_sectionって何? /* File: byterun/io.c */ CAMLexport struct channel * caml_open_descriptor_in(int fd) { struct channel * channel; channel = (struct channel *) caml_stat_alloc(sizeof(struct channel)); channel->fd = fd; caml_enter_blocking_section(); channel->offset = lseek(fd, 0, SEEK_CUR); caml_leave_blocking_section(); channel->curr = channel->max = channel->buff; channel->end = channel->buff + IO_BUFFER_SIZE; /* File: byterun/io.c */ CAMLexport struct channel * caml_open_descriptor_in(int fd) { struct channel * channel; channel = (struct channel *) caml_stat_alloc(sizeof(struct channel)); channel->fd = fd; caml_enter_blocking_section(); channel->offset = lseek(fd, 0, SEEK_CUR); caml_leave_blocking_section(); channel->curr = channel->max = channel->buff; channel->end = channel->buff + IO_BUFFER_SIZE; /* File: byterun/io.c */ CAMLexport struct channel * caml_open_descriptor_in(int fd) { struct channel * channel; channel = (struct channel *) caml_stat_alloc(sizeof(struct channel)); channel->fd = fd; caml_enter_blocking_section(); channel->offset = lseek(fd, 0, SEEK_CUR); caml_leave_blocking_section(); channel->curr = channel->max = channel->buff; channel->end = channel->buff + IO_BUFFER_SIZE; /* File: byterun/io.c */ CAMLexport struct channel * caml_open_descriptor_in(int fd) { struct channel * channel; channel = (struct channel *) caml_stat_alloc(sizeof(struct channel)); channel->fd = fd; caml_enter_blocking_section(); channel->offset = lseek(fd, 0, SEEK_CUR); caml_leave_blocking_section(); channel->curr = channel->max = channel->buff; channel->end = channel->buff + IO_BUFFER_SIZE; /* File: byterun/io.c */ CAMLexport struct channel * caml_open_descriptor_in(int fd) { struct channel * channel; channel = (struct channel *) caml_stat_alloc(sizeof(struct channel)); channel->fd = fd; caml_enter_blocking_section(); channel->offset = lseek(fd, 0, SEEK_CUR); caml_leave_blocking_section(); channel->curr = channel->max = channel->buff; channel->end = channel->buff + IO_BUFFER_SIZE; システムコールを囲むように配置されている...システムコールを囲むように配置されている...システムコールを囲むように配置されている...システムコールを囲むように配置されている...システムコールを囲むように配置されている...
  • 38. 宣伝: Ajhc Haskellコンパイラ宣伝: Ajhc Haskellコンパイラ宣伝: Ajhc Haskellコンパイラ宣伝: Ajhc Haskellコンパイラ宣伝: Ajhc Haskellコンパイラ ☆ http://ajhc.metasepi.org/☆ http://ajhc.metasepi.org/☆ http://ajhc.metasepi.org/☆ http://ajhc.metasepi.org/☆ http://ajhc.metasepi.org/ ☆ 組込を狙ったHaskellコンパイラ☆ 組込を狙ったHaskellコンパイラ☆ 組込を狙ったHaskellコンパイラ☆ 組込を狙ったHaskellコンパイラ☆ 組込を狙ったHaskellコンパイラ ☆ Haskell => C言語 への変換器☆ Haskell => C言語 への変換器☆ Haskell => C言語 への変換器☆ Haskell => C言語 への変換器☆ Haskell => C言語 への変換器 ☆ jhc Haskellコンパイラのfork☆ jhc Haskellコンパイラのfork☆ jhc Haskellコンパイラのfork☆ jhc Haskellコンパイラのfork☆ jhc Haskellコンパイラのfork ☆ mbedプラットフォームなどで動作☆ mbedプラットフォームなどで動作☆ mbedプラットフォームなどで動作☆ mbedプラットフォームなどで動作☆ mbedプラットフォームなどで動作 ☆ 要求RAMサイズ = 30kBぐらい☆ 要求RAMサイズ = 30kBぐらい☆ 要求RAMサイズ = 30kBぐらい☆ 要求RAMサイズ = 30kBぐらい☆ 要求RAMサイズ = 30kBぐらい ☆ もちろんPOSIXの上でも動きます☆ もちろんPOSIXの上でも動きます☆ もちろんPOSIXの上でも動きます☆ もちろんPOSIXの上でも動きます☆ もちろんPOSIXの上でも動きます
  • 39. 宣伝: 「簡約!?λカ娘 Go!」はイカが?宣伝: 「簡約!?λカ娘 Go!」はイカが?宣伝: 「簡約!?λカ娘 Go!」はイカが?宣伝: 「簡約!?λカ娘 Go!」はイカが?宣伝: 「簡約!?λカ娘 Go!」はイカが? http://www.paraiso-lang.org/ikmsm/http://www.paraiso-lang.org/ikmsm/http://www.paraiso-lang.org/ikmsm/http://www.paraiso-lang.org/ikmsm/http://www.paraiso-lang.org/ikmsm/ ☆ Lensライブラリの解説☆ Lensライブラリの解説☆ Lensライブラリの解説☆ Lensライブラリの解説☆ Lensライブラリの解説 ☆ パーサの解説☆ パーサの解説☆ パーサの解説☆ パーサの解説☆ パーサの解説 ☆ 圏論とモナド☆ 圏論とモナド☆ 圏論とモナド☆ 圏論とモナド☆ 圏論とモナド ☆ 囲碁AI☆ 囲碁AI☆ 囲碁AI☆ 囲碁AI☆ 囲碁AI ☆ Ajhcコンパイラの開発秘話☆ Ajhcコンパイラの開発秘話☆ Ajhcコンパイラの開発秘話☆ Ajhcコンパイラの開発秘話☆ Ajhcコンパイラの開発秘話 などなどの話題を掲載!などなどの話題を掲載!などなどの話題を掲載!などなどの話題を掲載!などなどの話題を掲載!