git » blacktide.git » master » tree

[master] / test / com / tailrecursion / blacktide / source_values_test.clj

(ns com.tailrecursion.blacktide.source-values-test
  "Primitive source reads box at each Object use; mutable locations and saved
  Object references retain their identity across normalization and transfers."
  (:require [clojure.test :refer [deftest is]]
            [com.tailrecursion.blacktide.backend-fixture :as backend]))

(def initializers
  '[1000 1.5 (int 1000) (short 1000) (byte 4) (float 1.5) (char 256) (boolean true)
    (identity 1000) (identity 1.5) (Integer. 1000) (Double. 1.5)])

(deftest source-reads-preserve-width-and-identity
  (doseq [init initializers
          body '[(identical? x x)
                 (let [[a b] [x x]] (identical? a b))
                 (let [snapshot (identity x)] (identical? snapshot snapshot))
                 (let [x (identity x)] (identical? x x))]
          :let [form (list 'let ['x init] body) reference (backend/compile-program form :default)]
          mode [:default :dispatcher]]
    (is (= (reference nil) ((backend/compile-program (list 'loophole [] form) mode) nil)) (pr-str [init body mode])))
  (doseq [init initializers :let [form (list 'let ['x init] 'x) reference (backend/compile-program form :default)]
          mode [:default :dispatcher] :let [compiled (backend/compile-program (list 'loophole [] form) mode)]]
    (is (= (reference nil) (compiled nil)) (pr-str [init mode]))
    (is (= (class (reference nil)) (class (compiled nil))) (pr-str [init mode]))
    (is (= (identical? (reference nil) (reference nil)) (identical? (compiled nil) (compiled nil)))
        (pr-str [init mode]))))

(deftest mutable-snapshots-remain-references
  (doseq [mode [:default :dispatcher] init initializers
          form [(list 'loophole ['x init 'y nil] '(psetq y x x x) '(identical? x y))
                (list 'loophole ['x nil 'y nil] (list 'psetq 'y (list 'setq 'x init)) '(identical? x y))
                (list 'loophole ['x init]
                      '(let [saved x] (setq x nil) (identical? saved saved)))]]
    (is (true? ((backend/compile-program form mode) nil)) (pr-str [mode form])))
  (doseq [mode [:default :dispatcher]]
    (is (= [1000 true false]
           ((backend/compile-program
              '(loophole [x 1000 y nil count 0 saved x]
                   (label again)
                   (psetq y x x (long 1001))
                   (setq count (inc count))
                   (when (< count 2) (setq x saved) (goto again))
                   [saved (identical? saved y) (identical? saved x)]) mode) nil)))))