例示できるナニ
短かくて理解し易げなソレが何かないものか、と試行錯誤。
gosh> (define (add (x y) (+ x y))) add gosh> (disasm (lambda (x) (+ (add x 1) 2))) main_code (name=#f, code=0x80f6ea0, size=8, const=1, stack=11): args: #f 0 PRE-CALL(2) 6 2 LREF0-PUSH ; x 3 CONSTI-PUSH(1) 4 GREF-CALL(2) #<identifier user#add>; (add x 1) 6 NUMADDI(2) ; (+ (add x 1) 2) 7 RET #<undef> gosh> (disasm (lambda (x y) (+ (add x 1) y))) main_code (name=#f, code=0x80f8e60, size=10, const=1, stack=11): args: #f 0 PRE-CALL(2) 6 2 LREF1-PUSH ; x 3 CONSTI-PUSH(1) 4 GREF-CALL(2) #<identifier user#add>; (add x 1) 6 PUSH 7 LREF0 ; y 8 NUMADD2 ; (+ (add x 1) y) 9 RET #<undef> gosh>
即値は最適化されてしまう。ある意味凄い。ちなみに add という関数を使わない場合にはこうなる。
gosh> (disasm (lambda (x y) (+ (+ x 1) y))) main_code (name=#f, code=0x80d73a8, size=6, const=0, stack=1): args: #f 0 LREF1 ; x 1 NUMADDI(1) ; (+ x 1) 2 PUSH 3 LREF0 ; y 4 NUMADD2 ; (+ (+ x 1) y) 5 RET #<undef> gosh>
あげ。こっちの方が分かりやすいじゃん (駄目
推測ベースで書くと
- lexical address の (0 1) から値を取り出して val0 にセット
- val0 と 1 を加えて val0 に
- val0 を push
- lexical address の (0 0) から値を取り出して val0 にセット
- pop した値と val0 を加えて val0 にセット
ってカンジなのだろうか。試した所では上記な形だと x と y な引数でないと PUSH が最適化されてしまうみたい。とりあえず PUSH の説明としては
val0 レジスタの値をスタックに push する。
で良いのでしょうか。とりあえず書いてみる。