CALL なインストラクション

確認中。なかなか面白いです。昨晩どこまで見たか、というと subr な場合の分岐な模様。もの凄く不思議なのは組込みな subr はここではどう扱われているのかな、という事。

  1. とかどうよと言いつつ 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 する
  • 次のインストラクションをナニ

という流れなのか。しかしこの調子だとこのインストラクションを、に凄い時間がかかりそうなんですが (とほほほ