boot2

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

058-fnptr-tab.scm (1755B)


      1 ;; tests/cc-cg/58-fnptr-tab.scm — array of function pointers initialized
      2 ;; with named functions. §L.3.
      3 ;;
      4 ;; Models:
      5 ;;   int f1(void) { return 1; }
      6 ;;   int f2(void) { return 2; }
      7 ;;   int (*tab[])(void) = { f1, f2 };
      8 ;;   int main(void) { return tab[0]() + tab[1]() * 10; }   (== 21)
      9 ;;
     10 ;; tab[i] is read via &tab + i (in fn-ptr units == 8 bytes), then a
     11 ;; %callr indirect call.
     12 
     13 (let* ((cg (cg-init))
     14        (fnty (%ctype 'fn -1 -1 (list %t-i32 '() #f)))
     15        (fnptr (%ctype 'ptr 8 8 fnty)))
     16   ;; int f1(void) { return 1; }
     17   (cg-fn-begin cg "f1" '() %t-i32)
     18   (cg-push-imm cg %t-i32 1)
     19   (cg-return cg)
     20   (cg-fn-end cg)
     21   ;; int f2(void) { return 2; }
     22   (cg-fn-begin cg "f2" '() %t-i32)
     23   (cg-push-imm cg %t-i32 2)
     24   (cg-return cg)
     25   (cg-fn-end cg)
     26   ;; tab[2] = { &f1, &f2 } — two label-ref pieces.
     27   (let* ((aty (%ctype 'arr 16 8 (cons fnptr 2)))
     28          (tab (%sym "tab" 'var 'static aty #f)))
     29     (cg-emit-global cg tab (list (cons 'label-ref "f1")
     30                                  (cons 'label-ref "f2")))
     31     ;; int main(void) { return tab[0]() + tab[1]() * 10; }
     32     (cg-fn-begin cg "main" '() %t-i32)
     33     (let ((pp (%ctype 'ptr 8 8 fnptr))   ; ptr to fnptr = pointee size 8
     34           (emit-call
     35            (lambda (idx ppt)
     36              (cg-push-sym cg tab) (cg-take-addr cg)
     37              (cg-cast cg ppt)             ; relabel to ptr-to-fnptr
     38              (cg-push-imm cg %t-i32 idx)
     39              (cg-binop cg 'add)           ; ptr arith scales by 8
     40              (cg-push-deref cg) (cg-load cg)
     41              (cg-call cg 0 #t))))
     42       (emit-call 0 pp)
     43       (emit-call 1 pp)
     44       (cg-push-imm cg %t-i32 10)
     45       (cg-binop cg 'mul)
     46       (cg-binop cg 'add))
     47     (cg-return cg)
     48     (cg-fn-end cg))
     49   (write-bv-fd 1 (cg-finish cg)))