CALL なインストラクション
確認中。なかなか面白いです。昨晩どこまで見たか、というと subr な場合の分岐な模様。もの凄く不思議なのは組込みな subr はここではどう扱われているのかな、という事。
で
- とかどうよと言いつつ disasm
gosh> (disasm (lambda (x y) (+ x y) 0)) main_code (name=#f, code=0x80d7b40, size=5, const=0, stack=1): args: #f 0 LREF1-PUSH ; x 1 LREF0 ; y 2 NUMADD2 ; (+ x y) 3 CONSTI(0) 4 RET #<undef> gosh> (disasm (lambda (x) (+ 1 2 x))) main_code (name=#f, code=0x81f1d10, size=3, const=0, stack=0): args: #f 0 LREF0 ; x 1 NUMADDI(3) ; (+ 1 2 x) 2 RET #<undef> gosh>
ひええ。builtin な subr は基本的にインストラクションな範疇でナニされるのか。よく考えれば当たり前か。
まだまだ脱線
昨晩も微妙だったナニ
VAL0 = SCM_SUBR(VAL0)->func(ARGP, argc, SCM_SUBR(VAL0)->data);
ScmSubr な型なんですが gauche.h にて以下の定義。
/* Subr - C defined procedure */ struct ScmSubrRec { ScmProcedure common; ScmSubrProc *func; void *data; };
で、上記の func 属性の型がまた微妙。定義は gauche.h にて以下。
typedef ScmObj ScmSubrProc(ScmObj *, int, void*);
これによれば func 属性は関数ポインタなんですか。置き換えると以下なカンジ?
ScmObj (*func)(ScmObj*, int, void*);
これはインターフェースを属性として持つという結構アレなテクですな。
どうも
脱線してしまうな。とりあえず一連の命令
SP = ARGP; PC = PC_TO_RETURN; SCM_PROF_COUNT_CALL(vm, VAL0); VAL0 = SCM_SUBR(VAL0)->func(ARGP, argc, SCM_SUBR(VAL0)->data); /* the subr may substituted pc, so we need to check if we can pop the continuation immediately. */ if (TAIL_POS()) RETURN_OP(); NEXT;
は
- SP と ARGP の値が同じという事は継続フレームを push した直後の状態?
- PC が RET を指してる状態に
- SCM_PROF_COUNT_CALL は略 (後で色々確認したい
- ScmSubr 型の func 属性呼びだし
- 上記の手続きで PC が書き換えられてるかもしれんので一応 PC が RET を指したままかをチェックしてそうだったら継続フレームを pop する
- 次のインストラクションをナニ
という流れなのか。しかしこの調子だとこのインストラクションを、に凄い時間がかかりそうなんですが (とほほほ