boot2

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

066-vararg-call.scm (2538B)


      1 ;; tests/cc-cg/66-vararg-call.scm — variadic call with default-promoted args (§G.1).
      2 ;; Models a variadic callee that just sums two int args after the named one.
      3 ;;   int sum_var(int n, ...) {
      4 ;;       int *ap = ((int*)(&n)) + 1;   /* hand-rolled vararg access */
      5 ;;       return n + ap[0] + ap[1];
      6 ;;   }
      7 ;;   int main(void) {
      8 ;;       signed char c = 5;
      9 ;;       short      s = 10;
     10 ;;       /* C semantics: c and s are promoted to int at the call site. */
     11 ;;       return sum_var(1, c, s);   /* 1 + 5 + 10 = 16 */
     12 ;;   }
     13 ;;
     14 ;; What the cc-cg fixture exercises is the *caller* side: cg-promote on
     15 ;; each variadic arg before cg-call. The callee uses fixed-arg ABI here
     16 ;; for simplicity; va_arg/va_start/va_end are §G.2.
     17 
     18 (let* ((cg          (cg-init))
     19        (sumv-fnty   (%ctype 'fn 8 8 (cons %t-i32 (cons (list %t-i32) #t))))
     20        (sumv-sym    (%sym "sum_var" 'fn 'extern sumv-fnty #f)))
     21   ;; int sum_var(int n, int a, int b) { return n + a + b; }
     22   ;; (Modeling 3 fixed params; the callee doesn't care about variadic
     23   ;; ABI in this fixture — see §G.2 for that.)
     24   (let* ((params (cg-fn-begin cg "sum_var"
     25                               (list (cons "n" %t-i32)
     26                                     (cons "a" %t-i32)
     27                                     (cons "b" %t-i32))
     28                               %t-i32))
     29          (n* (cdr (car params)))
     30          (a* (cdr (car (cdr params))))
     31          (b* (cdr (car (cdr (cdr params))))))
     32     (cg-push-sym cg n*) (cg-load cg)
     33     (cg-push-sym cg a*) (cg-load cg) (cg-binop cg 'add)
     34     (cg-push-sym cg b*) (cg-load cg) (cg-binop cg 'add)
     35     (cg-return cg)
     36     (cg-fn-end cg))
     37   ;; int main(void) { signed char c=5; short s=10; return sum_var(1, c, s); }
     38   (let* ((params (cg-fn-begin cg "main" '() %t-i32))
     39          (c-sl   (cg-alloc-slot cg 1 1))
     40          (s-sl   (cg-alloc-slot cg 2 2))
     41          (c-sym  (%sym "c" 'var 'auto %t-i8  c-sl))
     42          (s-sym  (%sym "s" 'var 'auto %t-i16 s-sl)))
     43     ;; c = 5;
     44     (cg-push-sym cg c-sym) (cg-push-imm cg %t-i32 5)
     45     (cg-assign cg) (cg-pop cg)
     46     ;; s = 10;
     47     (cg-push-sym cg s-sym) (cg-push-imm cg %t-i32 10)
     48     (cg-assign cg) (cg-pop cg)
     49     ;; sum_var(1, c, s) — promote c and s to int at the call site
     50     (cg-push-sym cg sumv-sym)
     51     (cg-push-imm cg %t-i32 1)               ; named-arg n
     52     (cg-push-sym cg c-sym) (cg-load cg) (cg-promote cg)   ; variadic c
     53     (cg-push-sym cg s-sym) (cg-load cg) (cg-promote cg)   ; variadic s
     54     (cg-call cg 3 #t)
     55     (cg-return cg)
     56     (cg-fn-end cg))
     57   (write-bv-fd 1 (cg-finish cg)))