summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-11-27 15:04:03 -0500
committerRich Hickey <richhickey@gmail.com>2010-11-27 15:04:03 -0500
commitaa7d26336faff6ccc65e4405e28e471221f35fc4 (patch)
tree97f829df1d3528a57c298406003684eddd48e492
parent3e644c768b1f769217ecd484c019580384c7a670 (diff)
added *unchecked-math* support, temporarily disabled name propagation to fns
-rw-r--r--src/clj/clojure/core.clj29
-rw-r--r--src/clj/clojure/main.clj1
-rw-r--r--src/jvm/clojure/lang/Compiler.java53
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()
));