;;;; M2 queue item 5: typed = and != grow strings. Bytewise, with a ;;;; length-mismatch fast path and a same-pointer fast path ahead of the byte ;;;; loop (runtime/flan_rt.c, flan_str_eq). Ordering stays refused on a ;;;; string -- that half is tested in test_flan.ml, because a program that ;;;; wrote (< "a" "b") would not compile and so cannot be a row here. (defn main [] i32 ;; Same pointer: one local read twice is the same two words, ptr and len ;; both, and the fast path answers before a single byte is looked at. (let [s "same"] (println (= s s)) ; true (println (!= s s))) ; false ;; Differing lengths: the length check alone settles it, and never reaches ;; the byte loop -- a common prefix would be no evidence otherwise. (println (= "abc" "ab")) ; false (println (!= "abc" "ab")) ; true ;; Equal contents, distinct pointers. "abc" the literal lives in the ;; read-only data section; to-lower of "ABC" is a fresh heap allocation, ;; so this pair shares no address and the same-pointer fast path cannot ;; fire -- what answers here is the byte loop, or the length check first ;; ruling nothing out since both are three bytes. (let [heap (to-lower (bytes "ABC"))] (let [h (string (as-slice heap))] (println (= "abc" h)) ; true (println (!= "abc" h))) (free heap)) ;; A one-byte difference at the end, so the length check cannot rule it ;; out and the byte loop has to run to the last byte before it can answer. (println (= "abd" "abc")) ; false (println (!= "abd" "abc")) ; true ;; Empty strings: the length check's zero case, which the runtime helper ;; also uses to skip a memcmp that would otherwise read through a null ;; pointer -- two empty string literals, and empty against non-empty. (println (= "" "")) ; true (println (= "" "a")) ; false (println (= "a" "")) ; false ;; A slice and the prefix it was cut from: same base pointer, different ;; lengths -- the one pair the same-pointer fast path would answer wrong on ;; if it ran before the length check instead of after. (let [s "abcd"] (println (= s (string (slice (bytes s) 0 2))))) ; false 0)