Skip to content

Commit

Permalink
fixed intrinsic predicates, closes #36
Browse files Browse the repository at this point in the history
  • Loading branch information
Bronsa committed Sep 29, 2013
1 parent f2e84d5 commit b3e9b43
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
35 changes: 21 additions & 14 deletions src/cinc/compiler/jvm/bytecode/emit.clj
Expand Up @@ -4,7 +4,7 @@
[cinc.analyzer.jvm.utils :refer [primitive? numeric? box] :as j.u]
[clojure.string :as s]
[cinc.compiler.jvm.bytecode.transform :as t]
[cinc.compiler.jvm.bytecode.intrinsics :refer [intrinsic]]))
[cinc.compiler.jvm.bytecode.intrinsics :refer [intrinsic intrinsic-predicate]]))

(defmulti -emit (fn [{:keys [op]} _] op))
(defmulti -emit-set! (fn [{:keys [op]} _] op))
Expand Down Expand Up @@ -373,19 +373,23 @@
~@(emit-as-array args frame)
[:invoke-static [:clojure.lang.Reflector/invokeCostructor :java.lang.Class :objects] :java.lang.Object]]))

(defn emit-intrinsic [^Class class method args]
(defn emit-intrinsic [{:keys [args method ^Class class false-label]}]
(let [args (mapv (fn [{:keys [cast tag]}] (or cast tag)) args)
m (str (.getMethod class (name method) (into-array Class args)))]
(when-let [ops (intrinsic m)]
(mapv (fn [op] [:insn op]) ops))))
(if false-label
(when-let [ops (intrinsic-predicate m)]
(conj (mapv (fn [op] [:insn op]) (butlast ops))
[:jump-insn (last ops) false-label]))
(when-let [ops (intrinsic m)]
(mapv (fn [op] [:insn op]) ops)))))

(defmethod -emit :static-call
[{:keys [env ret-tag validated? args method ^Class class]} frame]
[{:keys [env ret-tag validated? args method ^Class class false-label] :as ast} frame]
(if validated?
`[~@(emit-line-number env)
~@(mapcat #(emit % frame) args)
~@(or
(emit-intrinsic class method args)
(emit-intrinsic ast)
`[[:invoke-static [~(keyword (.getName class) (str method))
~@(mapv :tag args)] ~ret-tag]])]
`[[:push ~(.getName class)]
Expand Down Expand Up @@ -434,16 +438,19 @@

(defmethod -emit :if
[{:keys [test then else env]} frame]
(let [[null-label false-label end-label] (repeatedly label)]
(let [[null-label false-label end-label] (repeatedly label)
test-expr (emit (assoc test :false-label false-label) frame)]
`^:container
[~@(emit-line-number env)
~@(emit test frame)
~@(if (not= (:tag test) Boolean/TYPE)
[[:dup]
[:if-null null-label]
[:get-static :java.lang.Boolean/FALSE :java.lang.Boolean]
[:jump-insn :IF_ACMPEQ false-label]]
[[:if-z-cmp :EQ false-label]])
~@test-expr
~@(when (not (and (= :static-call (:op test))
(= :jump-insn (first (last test-expr)))))
(if (not= (:tag test) Boolean/TYPE)
[[:dup]
[:if-null null-label]
[:get-static :java.lang.Boolean/FALSE :java.lang.Boolean]
[:jump-insn :IF_ACMPEQ false-label]]
[[:if-z-cmp :EQ false-label]]))
~@(emit then frame)
[:go-to ~end-label]
[:mark ~null-label]
Expand Down
42 changes: 21 additions & 21 deletions src/cinc/compiler/jvm/bytecode/intrinsics.clj
Expand Up @@ -86,26 +86,26 @@
"public static long clojure.lang.RT.uncheckedLongCast(double)" [Opcodes/D2L]
"public static long clojure.lang.RT.uncheckedLongCast(byte)" [Opcodes/I2L]
"public static long clojure.lang.RT.uncheckedLongCast(long)" [Opcodes/NOP]
"public static long clojure.lang.RT.uncheckedLongCast(int)" [Opcodes/I2L]
"public static long clojure.lang.RT.uncheckedLongCast(int)" [Opcodes/I2L]})

;; "public static boolean clojure.lang.Numbers.lt(double,double)" [Opcodes/DCMPG Opcodes/IFGE]
;; "public static boolean clojure.lang.Numbers.lt(long,long)" [Opcodes/LCMP Opcodes/IFGE]
;; "public static boolean clojure.lang.Numbers.equiv(double,double)" [Opcodes/DCMPL Opcodes/IFNE]
;; "public static boolean clojure.lang.Numbers.equiv(long,long)" [Opcodes/LCMP Opcodes/IFNE]
;; "public static boolean clojure.lang.Numbers.lte(double,double)" [Opcodes/DCMPG Opcodes/IFGT]
;; "public static boolean clojure.lang.Numbers.lte(long,long)" [Opcodes/LCMP Opcodes/IFGT]
;; "public static boolean clojure.lang.Numbers.gt(long,long)" [Opcodes/LCMP Opcodes/IFLE]
;; "public static boolean clojure.lang.Numbers.gt(double,double)" [Opcodes/DCMPL Opcodes/IFLE]
;; "public static boolean clojure.lang.Numbers.gte(long,long)" [Opcodes/LCMP Opcodes/IFLT]
;; "public static boolean clojure.lang.Numbers.gte(double,double)" [Opcodes/DCMPL Opcodes/IFLT]
;; "public static boolean clojure.lang.Util.equiv(long,long)" [Opcodes/LCMP Opcodes/IFNE]
;; "public static boolean clojure.lang.Util.equiv(boolean,boolean)" [Opcodes/IF_ICMPNE]
;; "public static boolean clojure.lang.Util.equiv(double,double)" [Opcodes/DCMPL Opcodes/IFNE]
(def intrinsic-predicate
{"public static boolean clojure.lang.Numbers.lt(double,double)" [Opcodes/DCMPG Opcodes/IFGE]
"public static boolean clojure.lang.Numbers.lt(long,long)" [Opcodes/LCMP Opcodes/IFGE]
"public static boolean clojure.lang.Numbers.equiv(double,double)" [Opcodes/DCMPL Opcodes/IFNE]
"public static boolean clojure.lang.Numbers.equiv(long,long)" [Opcodes/LCMP Opcodes/IFNE]
"public static boolean clojure.lang.Numbers.lte(double,double)" [Opcodes/DCMPG Opcodes/IFGT]
"public static boolean clojure.lang.Numbers.lte(long,long)" [Opcodes/LCMP Opcodes/IFGT]
"public static boolean clojure.lang.Numbers.gt(long,long)" [Opcodes/LCMP Opcodes/IFLE]
"public static boolean clojure.lang.Numbers.gt(double,double)" [Opcodes/DCMPL Opcodes/IFLE]
"public static boolean clojure.lang.Numbers.gte(long,long)" [Opcodes/LCMP Opcodes/IFLT]
"public static boolean clojure.lang.Numbers.gte(double,double)" [Opcodes/DCMPL Opcodes/IFLT]
"public static boolean clojure.lang.Util.equiv(long,long)" [Opcodes/LCMP Opcodes/IFNE]
"public static boolean clojure.lang.Util.equiv(boolean,boolean)" [Opcodes/IF_ICMPNE]
"public static boolean clojure.lang.Util.equiv(double,double)" [Opcodes/DCMPL Opcodes/IFNE]

;; "public static boolean clojure.lang.Numbers.isZero(double)" [Opcodes/DCONST_0 Opcodes/DCMPL Opcodes/IFNE]
;; "public static boolean clojure.lang.Numbers.isZero(long)" [Opcodes/LCONST_0 Opcodes/LCMP Opcodes/IFNE]
;; "public static boolean clojure.lang.Numbers.isPos(long)" [Opcodes/LCONST_0 Opcodes/LCMP Opcodes/IFLE]
;; "public static boolean clojure.lang.Numbers.isPos(double)" [Opcodes/DCONST_0 Opcodes/DCMPL Opcodes/IFLE]
;; "public static boolean clojure.lang.Numbers.isNeg(long)" [Opcodes/LCONST_0 Opcodes/LCMP Opcodes/IFGE]
;; "public static boolean clojure.lang.Numbers.isNeg(double)" [Opcodes/DCONST_0 Opcodes/DCMPG Opcodes/IFGE]
})
"public static boolean clojure.lang.Numbers.isZero(double)" [Opcodes/DCONST_0 Opcodes/DCMPL Opcodes/IFNE]
"public static boolean clojure.lang.Numbers.isZero(long)" [Opcodes/LCONST_0 Opcodes/LCMP Opcodes/IFNE]
"public static boolean clojure.lang.Numbers.isPos(long)" [Opcodes/LCONST_0 Opcodes/LCMP Opcodes/IFLE]
"public static boolean clojure.lang.Numbers.isPos(double)" [Opcodes/DCONST_0 Opcodes/DCMPL Opcodes/IFLE]
"public static boolean clojure.lang.Numbers.isNeg(long)" [Opcodes/LCONST_0 Opcodes/LCMP Opcodes/IFGE]
"public static boolean clojure.lang.Numbers.isNeg(double)" [Opcodes/DCONST_0 Opcodes/DCMPG Opcodes/IFGE]})

0 comments on commit b3e9b43

Please sign in to comment.