;;;; Two rendered numbers, held at once. ;;;; ;;;; i64->bytes and its two siblings render into a buffer and answer a slice ;;;; over it. That buffer used to be one file-static in the runtime, shared by ;;;; every call in the process, so the program below printed "22 22": the ;;;; second conversion overwrote the first, and the first slice — still a ;;;; perfectly valid pointer into a perfectly live buffer — was read after it. ;;;; No crash, no diagnostic, and nothing for a sanitizer to catch, because ;;;; every byte read was inside an object that was alive. The wrong bytes. ;;;; ;;;; The conversion's bytes are now copied into the temp allocator, so a ;;;; result outlives the frame that made it: the last two cases return one from ;;;; a function and push them into a Vec that outlives the loop that made them. (defn numstr [n i64] string (string (i64->bytes n))) (defn main [] i32 ;; Two i64 conversions alive at the same time. (let [a (string (i64->bytes 11)) b (string (i64->bytes 22))] (print a) (print " ") (println b)) ; 11 22 ;; Three, and read in the order they were made rather than in reverse, so a ;; version that rotated among two buffers would still be caught. (let [a (string (i64->bytes 1)) b (string (i64->bytes 2)) c (string (i64->bytes 3))] (print a) (print b) (println c)) ; 123 ;; Across the two shims: the f64's text is made first and read last. (let [x (string (f64->bytes 2.5)) n (string (i64->bytes 7))] (print x) (print " ") (println n)) ; 2.5 7 ;; Inside a loop, one conversion per turn. Printed on one line so the ;; loop's shape is visible in the output. (dotimes [i 4] (let [s (string (i64->bytes (i64 (* i 11))))] (print s) (print " "))) (println "") ; 0 11 22 33 ;; Returned from the function that made it. With the text in that ;; function's frame, the second call wrote over the first. (let [a (numstr 11) b (numstr 22)] (print a) (print " ") (println b)) ; 11 22 ;; Pushed, and read after the loop. (let [v (vec-new [u8])] (dotimes [i 3] (push v (f64->bytes (+ (f64 i) 0.5)))) (dotimes [i 3] (print (string (at v i))) (print " ")) (println "")) ; 0.5 1.5 2.5 0)