ref とか
直前エントリで lambda な式を ref に渡しても slot が戻る事を知った。
そりゃそうか、と言いつつ以下。
gosh> (d (lambda (obj selector) (ref obj selector))) #<closure #f> is an instance of class <procedure> slots: required : 2 optional : #f locked : #f info : #f setter : #f gosh>
引数二つ。あるいは以下だと
gosh> (d (lambda (obj selector . more) (apply @ (ref obj selector) more))) #<closure #f> is an instance of class <procedure> slots: required : 2 optional : #t locked : #f info : #f setter : #f gosh>
optional が #t になってます。今度は disasm してみる。
gosh> (disasm (lambda () (ref (lambda (obj selector) (ref obj selector)) 'required)))
main_code (name=#f, code=0x80f6de0, size=8, const=3, stack=5):
args: #f
0 CLOSURE #<lambda 0> ; (lambda (obj selector) (ref obj selector ...
2 PUSH
3 CONST-PUSH required
5 GREF-TAIL-CALL(2) #<identifier user#ref>; (ref (lambda (obj selector) (ref obj sel ...
7 RET
internal_closure_0 (name=#f, code=0x80d6770, size=4, const=1 stack=5):
args: #f
0 LREF1-PUSH ; obj
1 LREF0-PUSH-GREF-TAIL-CALL(2) #<identifier user#ref>; (ref obj selector)
3 RET
#<undef>
gosh>CLOSURE な instruction にて手続きオブジェクトになっているんでしょうか。
CASE(SCM_VM_CLOSURE) {
ScmObj body;
FETCH_OPERAND(body);
INCR_PC;
/* preserve environment */
VAL0 = Scm_MakeClosure(body, get_env(vm));
NEXT1;
}1 に何があるのか、凄く気になる。compile してみれば良いのか。
gosh> (with-module gauche.internal (compile-p2 (compile-p1 '(lambda (obj selector) (ref obj selector)))))
($lambda[#f;0] (obj[1;0] selector[1;0])
($call ($gref ref)
($lref obj[1;0])
($lref selector[1;0])))
($const #<undef>)
#<undef>
gosh>うーん ...
gosh> (with-module gauche.internal (compile-p2 (compile-p1 '(ref (lambda (obj selector) (ref obj selector)) 'optional))))
($call ($gref ref)
($lambda[#f;0] (obj[1;0] selector[1;0])
($call ($gref ref)
($lref obj[1;0])
($lref selector[1;0])))
($const optional))
($const #<undef>)
#<undef>
gosh> むむむ。だんだん何がしたいのかワケワカらんぞ。
とりあえず
vm.c な実装を見るに、手続きオブジェクトが生成されるのは compile 時ではなくて VM instruction の評価時?
なんか割り込み多くて gdgd 気味。
とは言え、
gosh> (disasm (lambda () (ref (lambda (obj selector) (ref obj selector)) 'required)))
main_code (name=#f, code=0x80f6de0, size=8, const=3, stack=5):
args: #f
0 CLOSURE #<lambda 0> ; (lambda (obj selector) (ref obj selector ...
2 PUSH の 1 なナニがとても気になる。とりあえず gencomp 方面に戻ります。