diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-11-27 15:04:03 -0500 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-11-27 15:04:03 -0500 |
commit | aa7d26336faff6ccc65e4405e28e471221f35fc4 (patch) | |
tree | 97f829df1d3528a57c298406003684eddd48e492 | |
parent | 3e644c768b1f769217ecd484c019580384c7a670 (diff) |
added *unchecked-math* support, temporarily disabled name propagation to fns
-rw-r--r-- | src/clj/clojure/core.clj | 29 | ||||
-rw-r--r-- | src/clj/clojure/main.clj | 1 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 53 |
3 files changed, 59 insertions, 24 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 6c603b48..d55d5bf4 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -303,7 +303,9 @@ m)) m (conj (if (meta name) (meta name) {}) m)] (list 'def (with-meta name m) - (cons `fn (cons name fdecl)) )))) + ;;todo - restore propagation of fn name + ;;must figure out how to convey primitive hints to self calls first + (cons `fn fdecl) )))) (. (var defn) (setMacro)) @@ -814,7 +816,7 @@ (defn int "Coerce to int" { - :inline (fn [x] `(. clojure.lang.RT (intCast ~x))) + :inline (fn [x] `(. clojure.lang.RT (~(if *unchecked-math* 'uncheckedIntCast 'intCast) ~x))) :added "1.0"} [x] (. clojure.lang.RT (intCast x))) @@ -854,7 +856,7 @@ (defn inc "Returns a number one greater than num. Does not auto-promote longs, will throw on overflow. See also: inc'" - {:inline (fn [x] `(. clojure.lang.Numbers (inc ~x))) + {:inline (fn [x] `(. clojure.lang.Numbers (~(if *unchecked-math* 'unchecked_inc 'inc) ~x))) :added "1.2"} [x] (. clojure.lang.Numbers (inc x))) @@ -899,7 +901,7 @@ (defn + "Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'" - {:inline (fn [x y] `(. clojure.lang.Numbers (add ~x ~y))) + {:inline (fn [x y] `(. clojure.lang.Numbers (~(if *unchecked-math* 'unchecked_add 'add) ~x ~y))) :inline-arities #{2} :added "1.2"} ([] 0) @@ -923,7 +925,7 @@ (defn * "Returns the product of nums. (*) returns 1. Does not auto-promote longs, will throw on overflow. See also: *'" - {:inline (fn [x y] `(. clojure.lang.Numbers (multiply ~x ~y))) + {:inline (fn [x y] `(. clojure.lang.Numbers (~(if *unchecked-math* 'unchecked_multiply 'multiply) ~x ~y))) :inline-arities #{2} :added "1.2"} ([] 1) @@ -959,7 +961,7 @@ "If no ys are supplied, returns the negation of x, else subtracts the ys from x and returns the result. Does not auto-promote longs, will throw on overflow. See also: -'" - {:inline (fn [& args] `(. clojure.lang.Numbers (minus ~@args))) + {:inline (fn [& args] `(. clojure.lang.Numbers (~(if *unchecked-math* 'unchecked_minus 'minus) ~@args))) :inline-arities #{1 2} :added "1.2"} ([x] (. clojure.lang.Numbers (minus x))) @@ -1055,7 +1057,7 @@ (defn dec "Returns a number one less than num. Does not auto-promote longs, will throw on overflow. See also: dec'" - {:inline (fn [x] `(. clojure.lang.Numbers (dec ~x))) + {:inline (fn [x] `(. clojure.lang.Numbers (~(if *unchecked-math* 'unchecked_dec 'dec) ~x))) :added "1.2"} [x] (. clojure.lang.Numbers (dec x))) @@ -2984,7 +2986,7 @@ (defn float "Coerce to float" - {:inline (fn [x] `(. clojure.lang.RT (floatCast ~x))) + {:inline (fn [x] `(. clojure.lang.RT (~(if *unchecked-math* 'uncheckedFloatCast 'floatCast) ~x))) :added "1.0"} [^Number x] (clojure.lang.RT/floatCast x)) @@ -2996,19 +2998,19 @@ (defn short "Coerce to short" - {:inline (fn [x] `(. clojure.lang.RT (shortCast ~x))) + {:inline (fn [x] `(. clojure.lang.RT (~(if *unchecked-math* 'uncheckedShortCast 'shortCast) ~x))) :added "1.0"} [^Number x] (clojure.lang.RT/shortCast x)) (defn byte "Coerce to byte" - {:inline (fn [x] `(. clojure.lang.RT (byteCast ~x))) + {:inline (fn [x] `(. clojure.lang.RT (~(if *unchecked-math* 'uncheckedByteCast 'byteCast) ~x))) :added "1.0"} [^Number x] (clojure.lang.RT/byteCast x)) (defn char "Coerce to char" - {:inline (fn [x] `(. clojure.lang.RT (charCast ~x))) + {:inline (fn [x] `(. clojure.lang.RT (~(if *unchecked-math* 'uncheckedCharCast 'charCast) ~x))) :added "1.1"} [x] (. clojure.lang.RT (charCast x))) @@ -5658,6 +5660,11 @@ "Set to true when compiling files, false otherwise." {:added "1.0"}) +(add-doc-and-meta *unchecked-math* + "While bound to true, compilations of +, -, *, inc, dec and the + coercions will be done without overflow checks. Default: false." + {:added "1.3"}) + (add-doc-and-meta *ns* "A clojure.lang.Namespace object representing the current namespace." {:added "1.0"}) diff --git a/src/clj/clojure/main.clj b/src/clj/clojure/main.clj index 7aa74ab8..96fa25b3 100644 --- a/src/clj/clojure/main.clj +++ b/src/clj/clojure/main.clj @@ -32,6 +32,7 @@ *print-level* *print-level* *compile-path* (System/getProperty "clojure.compile.path" "classes") *command-line-args* *command-line-args* + *unchecked-math* *unchecked-math* *assert* *assert* *1 nil *2 nil diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 16022b95..9794d648 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -234,6 +234,10 @@ static final public Var INSTANCE = Var.intern(Namespace.findOrCreate(Symbol.inte static final public Var ADD_ANNOTATIONS = Var.intern(Namespace.findOrCreate(Symbol.intern("clojure.core")), Symbol.intern("add-annotations")); +//boolean +static final public Var UNCHECKED_MATH = Var.intern(Namespace.findOrCreate(Symbol.intern("clojure.core")), + Symbol.intern("*unchecked-math*"), Boolean.FALSE).setDynamic(); + //Integer static final public Var LINE = Var.create(0).setDynamic(); @@ -797,18 +801,36 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ { Method m = null; gen.checkCast(NUMBER_TYPE); - if(paramType == int.class) - m = Method.getMethod("int intCast(Object)"); - else if(paramType == float.class) - m = Method.getMethod("float floatCast(Object)"); - else if(paramType == double.class) - m = Method.getMethod("double doubleCast(Object)"); - else if(paramType == long.class) - m = Method.getMethod("long longCast(Object)"); - else if(paramType == byte.class) - m = Method.getMethod("byte byteCast(Object)"); - else if(paramType == short.class) - m = Method.getMethod("short shortCast(Object)"); + if(RT.booleanCast(UNCHECKED_MATH.deref())) + { + if(paramType == int.class) + m = Method.getMethod("int uncheckedIntCast(Object)"); + else if(paramType == float.class) + m = Method.getMethod("float uncheckedFloatCast(Object)"); + else if(paramType == double.class) + m = Method.getMethod("double uncheckedDoubleCast(Object)"); + else if(paramType == long.class) + m = Method.getMethod("long uncheckedLongCast(Object)"); + else if(paramType == byte.class) + m = Method.getMethod("byte uncheckedByteCast(Object)"); + else if(paramType == short.class) + m = Method.getMethod("short uncheckedShortCast(Object)"); + } + else + { + if(paramType == int.class) + m = Method.getMethod("int intCast(Object)"); + else if(paramType == float.class) + m = Method.getMethod("float floatCast(Object)"); + else if(paramType == double.class) + m = Method.getMethod("double doubleCast(Object)"); + else if(paramType == long.class) + m = Method.getMethod("long longCast(Object)"); + else if(paramType == byte.class) + m = Method.getMethod("byte byteCast(Object)"); + else if(paramType == short.class) + m = Method.getMethod("short shortCast(Object)"); + } gen.invokeStatic(RT_TYPE, m); } } @@ -1204,7 +1226,10 @@ static abstract class MethodExpr extends HostExpr{ { final MaybePrimitiveExpr pe = (MaybePrimitiveExpr) e; pe.emitUnboxed(C.EXPRESSION, objx, gen); - gen.invokeStatic(RT_TYPE, Method.getMethod("int intCast(long)")); + if(RT.booleanCast(UNCHECKED_MATH.deref())) + gen.invokeStatic(RT_TYPE, Method.getMethod("int uncheckedIntCast(long)")); + else + gen.invokeStatic(RT_TYPE, Method.getMethod("int intCast(long)")); } else if(primc == float.class && parameterTypes[i] == double.class) { @@ -6598,6 +6623,7 @@ public static Object load(Reader rdr, String sourcePath, String sourceName) thro RT.CURRENT_NS, RT.CURRENT_NS.deref(), LINE_BEFORE, pushbackReader.getLineNumber(), LINE_AFTER, pushbackReader.getLineNumber() + ,UNCHECKED_MATH, UNCHECKED_MATH.deref() )); try @@ -6714,6 +6740,7 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t CONSTANT_IDS, new IdentityHashMap(), KEYWORDS, PersistentHashMap.EMPTY, VARS, PersistentHashMap.EMPTY + ,UNCHECKED_MATH, UNCHECKED_MATH.deref() // ,LOADER, RT.makeClassLoader() )); |