boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

067-fnptr-call.scm (1588B)


      1 ;; tests/cc-cg/67-fnptr-call.scm — function-pointer call (§K.2).
      2 ;; Models:
      3 ;;   int triple(int x) { return x + x + x; }
      4 ;;   int main(void) {
      5 ;;       int (*fp)(int) = triple;
      6 ;;       return fp(7);  /* 21 */
      7 ;;   }
      8 ;; Exercises cg-call's %callr(t0) branch when the fn opnd is a
      9 ;; non-fn-typed (frame) operand: the address is loaded into t0.
     10 
     11 (let* ((cg          (cg-init))
     12        (triple-fnty (%ctype 'fn 8 8 (cons %t-i32 (cons (list %t-i32) #f))))
     13        (triple-sym  (%sym "triple" 'fn 'extern triple-fnty #f)))
     14   ;; int triple(int x) { return x + x + x; }
     15   (let* ((params (cg-fn-begin cg "triple"
     16                               (list (cons "x" %t-i32))
     17                               %t-i32))
     18          (x*     (cdr (car params))))
     19     (cg-push-sym cg x*) (cg-load cg)
     20     (cg-push-sym cg x*) (cg-load cg) (cg-binop cg 'add)
     21     (cg-push-sym cg x*) (cg-load cg) (cg-binop cg 'add)
     22     (cg-return cg)
     23     (cg-fn-end cg))
     24   ;; int main(void) { int (*fp)(int) = triple; return fp(7); }
     25   (let* ((params (cg-fn-begin cg "main" '() %t-i32))
     26          (fp-ty  (%ctype 'ptr 8 8 triple-fnty))
     27          (fp-sl  (cg-alloc-slot cg 8 8))
     28          (fp-sym (%sym "fp" 'var 'auto fp-ty fp-sl)))
     29     ;; fp = triple   (address of fn into the slot)
     30     (cg-push-sym cg fp-sym)
     31     (cg-push-sym cg triple-sym)
     32     (cg-cast cg fp-ty)
     33     (cg-assign cg) (cg-pop cg)
     34     ;; fp(7) — cg-call expects fn opnd at vstack-bottom of the args.
     35     (cg-push-sym cg fp-sym) (cg-load cg)
     36     (cg-push-imm cg %t-i32 7)
     37     (cg-call cg 1 #t)
     38     (cg-return cg)
     39     (cg-fn-end cg))
     40   (write-bv-fd 1 (cg-finish cg)))