Scm_VMCallCC (8)
今日も途中で力尽きそうなんですが、少しだけでもとゆーコトで。
昨晩
のナニをもう少しきちんと確認。VMのスタック操作の通常の関数呼び出し、なソレ。昨晩のナニを踏襲します。disasm したナニが以下。
gosh> (disasm (lambda () (fold + 0 '(1 2 3)) #t))
main_code (name=#f, code=0x80f7f30, size=11, const=3, stack=12):
args: #f
0 PRE-CALL(3) 9
2 GREF-PUSH #<identifier user#+>; +
4 CONSTI-PUSH(0)
5 CONST-PUSH (1 2 3)
7 GREF-CALL(3) #<identifier user#fold>; (fold + 0 '(1 2 3))
9 CONST-RET #t
#<undef>
gosh> まず_その関数のコンティニュエーションをpush_という所から。
これは上記の 0 なインストラクションにて PUSH_CONT マクロな以下の命令が実行される。
/* Push a continuation frame. next_pc is the PC from where execution
will be resumed. */
#define PUSH_CONT(next_pc) \
do { \
ScmContFrame *newcont = (ScmContFrame*)SP; \
newcont->prev = CONT; \
newcont->env = ENV; \
newcont->argp = ARGP; \
newcont->size = SP - ARGP; \
newcont->pc = next_pc; \
newcont->base = BASE; \
CONT = newcont; \
SP += CONT_FRAME_SIZE; \
ARGP = SP; \
} while (0)ScmContFrame オブジェクトの属性に各レジスタの値がセットされている。いずれもポインタ値をセットしているはず。ようやく気になり始めたんですが、マクロな引数で渡されている next_pc ってか PC が指してるデータの状態ってどうなってるんだろ。
相当脱線
してる気がしますが分かってないので仕方ない。vm.c の以下なソレを足がかりに。
v->pc = PC_TO_RETURN;
ええと、PC_TO_RETURN の定義は以下。
/* A stub VM code to make VM return immediately */
static ScmWord return_code[] = { SCM_VM_INSN(SCM_VM_RET) };
#define PC_TO_RETURN return_codeどこかに_PC ってリスト_という表現があったはずなんですが、このバージョンを見る限りは命令列は配列で表現されているように見えます。次のインストラクションは
#define FETCH_INSN(var) ((var) = *PC++)
みたいなソレで取り出されてるし。ええと以下なマクロもよく使われてますが
#define FETCH_LOCATION(var) ((var) = (ScmWord*)*PC)
FETCH_INSN マクロな取り出し方がデフォルトなので次の命令、は上記なマクロで取り出せる、という事かと。
体調微妙なんで
続きは明日で (を