summaryrefslogtreecommitdiff
path: root/src/jvm
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-06-02 12:05:36 -0400
committerRich Hickey <richhickey@gmail.com>2010-06-02 12:05:36 -0400
commitc37c15c81a299c617779bff738480b1a2fb45524 (patch)
treed9218214341b31791a9b720c3705d9494bf7c777 /src/jvm
parentf47b3d6f028e0370c495383731a449092d0ae451 (diff)
flow primitives through if and let
Diffstat (limited to 'src/jvm')
-rw-r--r--src/jvm/clojure/lang/Compiler.java67
-rw-r--r--src/jvm/clojure/lang/RT.java4
2 files changed, 63 insertions, 8 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 40acd58d..3aae49f8 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -2191,7 +2191,7 @@ public static class MetaExpr implements Expr{
}
}
-public static class IfExpr implements Expr{
+public static class IfExpr implements Expr, MaybePrimitiveExpr{
public final Expr testExpr;
public final Expr thenExpr;
public final Expr elseExpr;
@@ -2213,6 +2213,14 @@ public static class IfExpr implements Expr{
}
public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
+ doEmit(context, objx, gen,false);
+ }
+
+ public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){
+ doEmit(context, objx, gen, true);
+ }
+
+ public void doEmit(C context, ObjExpr objx, GeneratorAdapter gen, boolean emitUnboxed){
Label nullLabel = gen.newLabel();
Label falseLabel = gen.newLabel();
Label endLabel = gen.newLabel();
@@ -2239,12 +2247,18 @@ public static class IfExpr implements Expr{
{
throw new RuntimeException(e);
}
- thenExpr.emit(context, objx, gen);
+ if(emitUnboxed)
+ ((MaybePrimitiveExpr)thenExpr).emitUnboxed(context, objx, gen);
+ else
+ thenExpr.emit(context, objx, gen);
gen.goTo(endLabel);
gen.mark(nullLabel);
gen.pop();
gen.mark(falseLabel);
- elseExpr.emit(context, objx, gen);
+ if(emitUnboxed)
+ ((MaybePrimitiveExpr)elseExpr).emitUnboxed(context, objx, gen);
+ else
+ elseExpr.emit(context, objx, gen);
gen.mark(endLabel);
}
@@ -2253,8 +2267,23 @@ public static class IfExpr implements Expr{
&& elseExpr.hasJavaClass()
&&
(thenExpr.getJavaClass() == elseExpr.getJavaClass()
- || thenExpr.getJavaClass() == null
- || elseExpr.getJavaClass() == null);
+ || (thenExpr.getJavaClass() == null && !elseExpr.getJavaClass().isPrimitive())
+ || (elseExpr.getJavaClass() == null && !thenExpr.getJavaClass().isPrimitive()));
+ }
+
+ public boolean canEmitPrimitive(){
+ try
+ {
+ return thenExpr instanceof MaybePrimitiveExpr
+ && elseExpr instanceof MaybePrimitiveExpr
+ && thenExpr.getJavaClass() == elseExpr.getJavaClass()
+ && ((MaybePrimitiveExpr)thenExpr).canEmitPrimitive()
+ && ((MaybePrimitiveExpr)elseExpr).canEmitPrimitive();
+ }
+ catch(Exception e)
+ {
+ return false;
+ }
}
public Class getJavaClass() throws Exception{
@@ -4838,7 +4867,7 @@ public static class LetFnExpr implements Expr{
}
}
-public static class LetExpr implements Expr{
+public static class LetExpr implements Expr, MaybePrimitiveExpr{
public final PersistentVector bindingInits;
public final Expr body;
public final boolean isLoop;
@@ -4927,6 +4956,15 @@ public static class LetExpr implements Expr{
}
public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
+ doEmit(context, objx, gen, false);
+ }
+
+ public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){
+ doEmit(context, objx, gen, true);
+ }
+
+
+ public void doEmit(C context, ObjExpr objx, GeneratorAdapter gen, boolean emitUnboxed){
for(int i = 0; i < bindingInits.count(); i++)
{
BindingInit bi = (BindingInit) bindingInits.nth(i);
@@ -4948,7 +4986,10 @@ public static class LetExpr implements Expr{
try
{
Var.pushThreadBindings(RT.map(LOOP_LABEL, loopLabel));
- body.emit(context, objx, gen);
+ if(emitUnboxed)
+ ((MaybePrimitiveExpr)body).emitUnboxed(context, objx, gen);
+ else
+ body.emit(context, objx, gen);
}
finally
{
@@ -4956,7 +4997,12 @@ public static class LetExpr implements Expr{
}
}
else
- body.emit(context, objx, gen);
+ {
+ if(emitUnboxed)
+ ((MaybePrimitiveExpr)body).emitUnboxed(context, objx, gen);
+ else
+ body.emit(context, objx, gen);
+ }
Label end = gen.mark();
// gen.visitLocalVariable("this", "Ljava/lang/Object;", null, loopLabel, end, 0);
for(ISeq bis = bindingInits.seq(); bis != null; bis = bis.next())
@@ -4981,6 +5027,11 @@ public static class LetExpr implements Expr{
public Class getJavaClass() throws Exception{
return body.getJavaClass();
}
+
+ public boolean canEmitPrimitive(){
+ return body instanceof MaybePrimitiveExpr && ((MaybePrimitiveExpr)body).canEmitPrimitive();
+ }
+
}
public static class RecurExpr implements Expr{
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index e1016f57..1f78443e 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -894,6 +894,10 @@ static public boolean booleanCast(Object x){
return x != null;
}
+static public boolean booleanCast(boolean x){
+ return x;
+}
+
static public byte byteCast(Object x){
long n = ((Number) x).longValue();
if(n < Byte.MIN_VALUE || n > Byte.MAX_VALUE)