057-block-static.scm (1895B)
1 ;; tests/cc-cg/57-block-static.scm — block-scope `static int n;` should 2 ;; live in .bss/.data, not on the stack. §I. 3 ;; 4 ;; Models: 5 ;; int incr(void) { static int n = 0; n = n + 1; return n; } 6 ;; int main(void) { incr(); incr(); return incr(); } (== 3) 7 ;; 8 ;; Two functions could declare `static int n;` independently; mangling 9 ;; with the function name avoids collisions. Here we lay down a 10 ;; pre-mangled cc__incr__n directly via the cg API. 11 12 (let* ((cg (cg-init)) 13 (n (%sym "n" 'var 'static %t-i32 (string->symbol "cc__incr__n")))) 14 ;; cg-emit-global expects the slot to be a bv (the emitted label name). 15 ;; Build n with a string slot directly. 16 (let* ((nsym (%sym "n" 'var 'static %t-i32 #f)) 17 (zero (make-bytevector 4 0))) 18 ;; n is sym-named "n"; cg-mangle-global prefixes with "cc__" → "cc__n". 19 ;; That collides if multiple fns name `n`; the parser side adds the 20 ;; fn-name segment via handle-decl. For the cg fixture we just use 21 ;; the unprefixed sym-name. 22 (cg-emit-global cg nsym (list zero)) 23 24 ;; int incr(void) { n = n + 1; return n; } 25 (cg-fn-begin cg "incr" '() %t-i32) 26 (cg-push-sym cg nsym) ; lhs lval n 27 (cg-push-sym cg nsym) (cg-load cg) ; rhs n 28 (cg-push-imm cg %t-i32 1) 29 (cg-binop cg 'add) 30 (cg-assign cg) (cg-pop cg) 31 (cg-push-sym cg nsym) (cg-load cg) 32 (cg-return cg) 33 (cg-fn-end cg) 34 35 ;; int main(void) { incr(); incr(); return incr(); } 36 (cg-fn-begin cg "main" '() %t-i32) 37 (let ((incr-sym (%sym "incr" 'fn 'extern 38 (%ctype 'fn -1 -1 (list %t-i32 '() #f)) 39 "cc__incr"))) 40 (cg-push-sym cg incr-sym) (cg-call cg 0 #t) (cg-pop cg) 41 (cg-push-sym cg incr-sym) (cg-call cg 0 #t) (cg-pop cg) 42 (cg-push-sym cg incr-sym) (cg-call cg 0 #t) 43 (cg-return cg)) 44 (cg-fn-end cg)) 45 (write-bv-fd 1 (cg-finish cg)))