アサレン
朝早く目覚しに起こされたので再開。
NEXT についてココサブさんからフォロー。NEXT のカラクリについて。run_loop 手続きの先頭部分が以下。
for (;;) { DISPATCH; /*VM_DUMP("");*/ if (vm->queueNotEmpty) goto process_queue; FETCH_INSN(code); SWITCH(SCM_VM_INSN_CODE(code)) {
NEXT は上記の無限ループの先頭にある DISPATCH に戻るナニ、との事。vm.c にて以下の定義。
/* We take advantage of GCC's `computed goto' feature (see gcc.info, "Labels as Values"). */ #ifdef __GNUC__ #define SWITCH(val) goto *dispatch_table[val]; #define CASE(insn) SCM_CPP_CAT(LABEL_, insn) : #define DEFAULT LABEL_DEFAULT : #define DISPATCH /*empty*/ #define NEXT \ do { \ if (vm->queueNotEmpty) goto process_queue; \ FETCH_INSN(code); \ goto *dispatch_table[SCM_VM_INSN_CODE(code)]; \ } while (0) #else /* !__GNUC__ */ #define SWITCH(val) switch (val) #define CASE(insn) case insn : #define DISPATCH dispatch: #define NEXT goto dispatch #endif
dispatch_table は vm.c にて定義。
#ifdef __GNUC__ static void *dispatch_table[256] = { #define DEFINSN(insn, name, nargs, type) && SCM_CPP_CAT(LABEL_, insn), #include "vminsn.c" #undef DEFINSN }; #endif /* __GNUC__ */
なんか脱線しとるな。(違
まとめ
- 引数は pop して Scm_VMApply に渡している
- 手続きは val0 にセットして Scm_VMApply にも渡す
- TAIL_CALL_INSTRUCTION マクロはスルー?
- PC が指す命令が RET じゃなかったら
- 継続フレームを push
- PC には RET をセット
- Scm_VMApply 手続き呼び出し
- エラーチェック略
- 引数を push
- PC に TAIL_CALL と RET をセット
- proc を戻す
- NEXT1
で、ループの先頭に戻った後 TAIL_CALL なソレに移動して (ry
とゆー事でその先が大変なんですな。
む
てーコトは RET は push した継続フレームを取り出す処理になるのか。そうなっていますね。