boot2

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

072-cg-snapshot-rewind.scm (1838B)


      1 ;; tests/cc-cg/72-cg-snapshot-rewind.scm — cg-snapshot / cg-rewind
      2 ;; primitives. The pair underpins parse-side `sizeof EXPR` (no-eval):
      3 ;; the parser learns the expression's type without retaining the code
      4 ;; emission or vstack push the operand parse produced.
      5 ;;
      6 ;; Models, in C terms:
      7 ;;     int x = 5;
      8 ;;     /* "speculative" load+inc+store sequence, then rewound */
      9 ;;     /* speculative pushes onto vstack, then rewound */
     10 ;;     return x;          /* must still be 5 */
     11 ;;
     12 ;; Concretely:
     13 ;;   1. x = 5 (committed).
     14 ;;   2. cg-snapshot — capture vstack/fn-buf/frame-hi state.
     15 ;;   3. Emit a postinc on x (loads, stores x+1) AND push extra opnds
     16 ;;      onto the vstack.
     17 ;;   4. cg-rewind — discard the emitted bytes and the vstack pushes.
     18 ;;   5. return x — must observe pre-snapshot value, exit 5.
     19 ;;
     20 ;; If snapshot/rewind fail to undo the fn-buf bytes, x is incremented
     21 ;; to 6 and we'd exit 6 instead of 5. If the vstack rewind fails, the
     22 ;; final cg-return sees the wrong opnd on top.
     23 
     24 (let ((cg (cg-init)))
     25   (cg-fn-begin cg "main" '() %t-i32)
     26   (let* ((off-x (cg-alloc-slot cg 4 4))
     27          (sym-x (%sym "x" 'var 'auto %t-i32 off-x)))
     28     ;; x = 5 (committed)
     29     (cg-push-sym cg sym-x)
     30     (cg-push-imm cg %t-i32 5)
     31     (cg-assign cg) (cg-pop cg)
     32     ;; snapshot: capture state before the speculative work
     33     (let ((tag (cg-snapshot cg)))
     34       ;; speculative emission: postinc on x — would make x = 6
     35       (cg-push-sym cg sym-x)
     36       (cg-postinc cg)
     37       (cg-pop cg)
     38       ;; speculative vstack push, never assigned: an extra imm
     39       (cg-push-imm cg %t-i32 999)
     40       ;; rewind: discard the postinc bytes AND the speculative pushes
     41       (cg-rewind cg tag))
     42     ;; return x — should still be 5
     43     (cg-push-sym cg sym-x) (cg-load cg)
     44     (cg-return cg))
     45   (cg-fn-end cg)
     46   (write-bv-fd 1 (cg-finish cg)))