diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/clj/clojure/core.clj | 8 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 1825 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentList.java | 8 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Reflector.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RestFn.java | 55 |
5 files changed, 1066 insertions, 833 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 90e3f76f..c4ab4785 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -4380,10 +4380,10 @@ not yet finished, calls to deref/@ will block." [#^Callable f] (let [fut (.submit clojure.lang.Agent/soloExecutor f)] - (proxy [clojure.lang.IDeref java.util.concurrent.Future] [] + (new [clojure.lang.IDeref java.util.concurrent.Future] (deref [] (.get fut)) - (get ([] (.get fut)) - ([timeout unit] (.get fut timeout unit))) + (get [] (.get fut)) + (get [timeout unit] (.get fut timeout unit)) (isCancelled [] (.isCancelled fut)) (isDone [] (.isDone fut)) (cancel [interrupt?] (.cancel fut interrupt?))))) @@ -4493,7 +4493,7 @@ [] (let [d (java.util.concurrent.CountDownLatch. 1) v (atom nil)] - (proxy [clojure.lang.AFn clojure.lang.IDeref] [] + (new [clojure.lang.AFn clojure.lang.IDeref] this (deref [] (.await d) @v) (invoke [x] (locking d diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index e9ba4335..c5c9f922 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -73,6 +73,8 @@ static final Symbol ISEQ = Symbol.create("clojure.lang.ISeq"); static final Keyword inlineKey = Keyword.intern(null, "inline"); static final Keyword inlineAritiesKey = Keyword.intern(null, "inline-arities"); +static final Keyword volatileKey = Keyword.intern(null, "volatile"); + static final Symbol NS = Symbol.create("ns"); static final Symbol IN_NS = Symbol.create("in-ns"); @@ -219,7 +221,7 @@ public enum C{ interface Expr{ Object eval() throws Exception; - void emit(C context, FnExpr fn, GeneratorAdapter gen); + void emit(C context, ObjExpr objx, GeneratorAdapter gen); boolean hasJavaClass() throws Exception; @@ -316,18 +318,18 @@ static class DefExpr implements Expr{ } } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - fn.emitVar(gen, var); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + objx.emitVar(gen, var); if(initProvided) { gen.dup(); - init.emit(C.EXPRESSION, fn, gen); + init.emit(C.EXPRESSION, objx, gen); gen.invokeVirtual(VAR_TYPE, bindRootMethod); } if(meta != null) { gen.dup(); - meta.emit(C.EXPRESSION, fn, gen); + meta.emit(C.EXPRESSION, objx, gen); gen.checkCast(IPERSISTENTMAP_TYPE); gen.invokeVirtual(VAR_TYPE, setMetaMethod); } @@ -390,8 +392,8 @@ public static class AssignExpr implements Expr{ return target.evalAssign(val); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - target.emitAssign(context, fn, gen, val); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + target.emitAssign(context, objx, gen, val); } public boolean hasJavaClass() throws Exception{ @@ -430,8 +432,8 @@ public static class VarExpr implements Expr, AssignableExpr{ return var.deref(); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - fn.emitVar(gen, var); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + objx.emitVar(gen, var); gen.invokeVirtual(VAR_TYPE, getMethod); if(context == C.STATEMENT) { @@ -451,10 +453,10 @@ public static class VarExpr implements Expr, AssignableExpr{ return var.set(val.eval()); } - public void emitAssign(C context, FnExpr fn, GeneratorAdapter gen, + public void emitAssign(C context, ObjExpr objx, GeneratorAdapter gen, Expr val){ - fn.emitVar(gen, var); - val.emit(C.EXPRESSION, fn, gen); + objx.emitVar(gen, var); + val.emit(C.EXPRESSION, objx, gen); gen.invokeVirtual(VAR_TYPE, setMethod); if(context == C.STATEMENT) gen.pop(); @@ -472,8 +474,8 @@ public static class TheVarExpr implements Expr{ return var; } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - fn.emitVar(gen, var); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + objx.emitVar(gen, var); if(context == C.STATEMENT) gen.pop(); } @@ -508,8 +510,8 @@ public static class KeywordExpr implements Expr{ return k; } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - fn.emitKeyword(gen, k); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + objx.emitKeyword(gen, k); if(context == C.STATEMENT) gen.pop(); @@ -540,7 +542,7 @@ public static class ImportExpr implements Expr{ return null; } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ gen.getStatic(RT_TYPE,"CURRENT_NS",VAR_TYPE); gen.invokeVirtual(VAR_TYPE, derefMethod); gen.checkCast(NS_TYPE); @@ -577,11 +579,12 @@ public static abstract class LiteralExpr implements Expr{ static interface AssignableExpr{ Object evalAssign(Expr val) throws Exception; - void emitAssign(C context, FnExpr fn, GeneratorAdapter gen, Expr val); + void emitAssign(C context, ObjExpr objx, GeneratorAdapter gen, Expr val); } -static public interface MaybePrimitiveExpr{ - public void emitUnboxed(C context, FnExpr fn, GeneratorAdapter gen); +static public interface MaybePrimitiveExpr extends Expr{ + public boolean canEmitPrimitive(); + public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen); } static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ @@ -618,57 +621,8 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ final static Method fromDoubleMethod = Method.getMethod("clojure.lang.Num from(double)"); - /* - public static void emitBoxReturn(FnExpr fn, GeneratorAdapter gen, Class returnType){ - if(returnType.isPrimitive()) - { - if(returnType == boolean.class) - { - Label falseLabel = gen.newLabel(); - Label endLabel = gen.newLabel(); - gen.ifZCmp(GeneratorAdapter.EQ, falseLabel); - gen.getStatic(RT_TYPE, "T", KEYWORD_TYPE); - gen.goTo(endLabel); - gen.mark(falseLabel); - NIL_EXPR.emit(C.EXPRESSION, fn, gen); - gen.mark(endLabel); - } - else if(returnType == void.class) - { - NIL_EXPR.emit(C.EXPRESSION, fn, gen); - } - else if(returnType == char.class) - { - gen.invokeStatic(CHAR_TYPE, charValueOfMethod); - } - else if(returnType == int.class) - gen.invokeStatic(INTEGER_TYPE, intValueOfMethod); - //m = fromIntMethod; - else - { - Method m = fromIntMethod; - if(returnType == int.class) - m = fromIntMethod; - else if(returnType == float.class) - { - gen.visitInsn(F2D); - m = fromDoubleMethod; - } - else if(returnType == double.class) - m = fromDoubleMethod; - else if(returnType == long.class) - m = fromLongMethod; - else if(returnType == byte.class) - m = fromIntMethod; - else if(returnType == short.class) - m = fromIntMethod; - gen.invokeStatic(NUM_TYPE, m); - } - } - } - */ //* - public static void emitBoxReturn(FnExpr fn, GeneratorAdapter gen, Class returnType){ + public static void emitBoxReturn(ObjExpr objx, GeneratorAdapter gen, Class returnType){ if(returnType.isPrimitive()) { if(returnType == boolean.class) @@ -685,7 +639,7 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ } else if(returnType == void.class) { - NIL_EXPR.emit(C.EXPRESSION, fn, gen); + NIL_EXPR.emit(C.EXPRESSION, objx, gen); } else if(returnType == char.class) { @@ -715,7 +669,7 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ } //*/ - public static void emitUnboxArg(FnExpr fn, GeneratorAdapter gen, Class paramType){ + public static void emitUnboxArg(ObjExpr objx, GeneratorAdapter gen, Class paramType){ if(paramType.isPrimitive()) { if(paramType == boolean.class) @@ -923,11 +877,16 @@ static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ return Reflector.invokeNoArgInstanceMember(target.eval(), fieldName); } - public void emitUnboxed(C context, FnExpr fn, GeneratorAdapter gen){ + public boolean canEmitPrimitive(){ + return targetClass != null && field != null && + Util.isPrimitive(field.getType()); + } + + public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitLineNumber(line, gen.mark()); if(targetClass != null && field != null) { - target.emit(C.EXPRESSION, fn, gen); + target.emit(C.EXPRESSION, objx, gen); gen.checkCast(Type.getType(targetClass)); gen.getField(Type.getType(targetClass), fieldName, Type.getType(field.getType())); } @@ -935,15 +894,15 @@ static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ throw new UnsupportedOperationException("Unboxed emit of unknown member"); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitLineNumber(line, gen.mark()); if(targetClass != null && field != null) { - target.emit(C.EXPRESSION, fn, gen); + target.emit(C.EXPRESSION, objx, gen); gen.checkCast(Type.getType(targetClass)); gen.getField(Type.getType(targetClass), fieldName, Type.getType(field.getType())); //if(context != C.STATEMENT) - HostExpr.emitBoxReturn(fn, gen, field.getType()); + HostExpr.emitBoxReturn(objx, gen, field.getType()); if(context == C.STATEMENT) { gen.pop(); @@ -951,7 +910,7 @@ static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ } else { - target.emit(C.EXPRESSION, fn, gen); + target.emit(C.EXPRESSION, objx, gen); gen.push(fieldName); gen.invokeStatic(REFLECTOR_TYPE, invokeNoArgInstanceMember); if(context == C.STATEMENT) @@ -971,23 +930,23 @@ static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ return Reflector.setInstanceField(target.eval(), fieldName, val.eval()); } - public void emitAssign(C context, FnExpr fn, GeneratorAdapter gen, + public void emitAssign(C context, ObjExpr objx, GeneratorAdapter gen, Expr val){ gen.visitLineNumber(line, gen.mark()); if(targetClass != null && field != null) { - target.emit(C.EXPRESSION, fn, gen); + target.emit(C.EXPRESSION, objx, gen); gen.checkCast(Type.getType(targetClass)); - val.emit(C.EXPRESSION, fn, gen); + val.emit(C.EXPRESSION, objx, gen); gen.dupX1(); - HostExpr.emitUnboxArg(fn, gen, field.getType()); + HostExpr.emitUnboxArg(objx, gen, field.getType()); gen.putField(Type.getType(targetClass), fieldName, Type.getType(field.getType())); } else { - target.emit(C.EXPRESSION, fn, gen); + target.emit(C.EXPRESSION, objx, gen); gen.push(fieldName); - val.emit(C.EXPRESSION, fn, gen); + val.emit(C.EXPRESSION, objx, gen); gen.invokeStatic(REFLECTOR_TYPE, setInstanceFieldMethod); } if(context == C.STATEMENT) @@ -1017,17 +976,21 @@ static class StaticFieldExpr extends FieldExpr implements AssignableExpr{ return Reflector.getStaticField(c, fieldName); } - public void emitUnboxed(C context, FnExpr fn, GeneratorAdapter gen){ + public boolean canEmitPrimitive(){ + return Util.isPrimitive(field.getType()); + } + + public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitLineNumber(line, gen.mark()); gen.getStatic(Type.getType(c), fieldName, Type.getType(field.getType())); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitLineNumber(line, gen.mark()); gen.getStatic(Type.getType(c), fieldName, Type.getType(field.getType())); //if(context != C.STATEMENT) - HostExpr.emitBoxReturn(fn, gen, field.getType()); + HostExpr.emitBoxReturn(objx, gen, field.getType()); if(context == C.STATEMENT) { gen.pop(); @@ -1051,12 +1014,12 @@ static class StaticFieldExpr extends FieldExpr implements AssignableExpr{ return Reflector.setStaticField(c, fieldName, val.eval()); } - public void emitAssign(C context, FnExpr fn, GeneratorAdapter gen, + public void emitAssign(C context, ObjExpr objx, GeneratorAdapter gen, Expr val){ gen.visitLineNumber(line, gen.mark()); - val.emit(C.EXPRESSION, fn, gen); + val.emit(C.EXPRESSION, objx, gen); gen.dup(); - HostExpr.emitUnboxArg(fn, gen, field.getType()); + HostExpr.emitUnboxArg(objx, gen, field.getType()); gen.putStatic(Type.getType(c), fieldName, Type.getType(field.getType())); if(context == C.STATEMENT) gen.pop(); @@ -1068,7 +1031,7 @@ static class StaticFieldExpr extends FieldExpr implements AssignableExpr{ static Class maybePrimitiveType(Expr e){ try { - if(e instanceof MaybePrimitiveExpr && e.hasJavaClass()) + if(e instanceof MaybePrimitiveExpr && e.hasJavaClass() && ((MaybePrimitiveExpr)e).canEmitPrimitive()) { Class c = e.getJavaClass(); if(Util.isPrimitive(c)) @@ -1083,19 +1046,19 @@ static Class maybePrimitiveType(Expr e){ } static abstract class MethodExpr extends HostExpr{ - static void emitArgsAsArray(IPersistentVector args, FnExpr fn, GeneratorAdapter gen){ + static void emitArgsAsArray(IPersistentVector args, ObjExpr objx, GeneratorAdapter gen){ gen.push(args.count()); gen.newArray(OBJECT_TYPE); for(int i = 0; i < args.count(); i++) { gen.dup(); gen.push(i); - ((Expr) args.nth(i)).emit(C.EXPRESSION, fn, gen); + ((Expr) args.nth(i)).emit(C.EXPRESSION, objx, gen); gen.arrayStore(OBJECT_TYPE); } } - public static void emitTypedArgs(FnExpr fn, GeneratorAdapter gen, Class[] parameterTypes, IPersistentVector args){ + public static void emitTypedArgs(ObjExpr objx, GeneratorAdapter gen, Class[] parameterTypes, IPersistentVector args){ for(int i = 0; i < parameterTypes.length; i++) { Expr e = (Expr) args.nth(i); @@ -1103,12 +1066,12 @@ static abstract class MethodExpr extends HostExpr{ { if(maybePrimitiveType(e) == parameterTypes[i]) { - ((MaybePrimitiveExpr) e).emitUnboxed(C.EXPRESSION, fn, gen); + ((MaybePrimitiveExpr) e).emitUnboxed(C.EXPRESSION, objx, gen); } else { - e.emit(C.EXPRESSION, fn, gen); - HostExpr.emitUnboxArg(fn, gen, parameterTypes[i]); + e.emit(C.EXPRESSION, objx, gen); + HostExpr.emitUnboxArg(objx, gen, parameterTypes[i]); } } catch(Exception e1) @@ -1206,18 +1169,22 @@ static class InstanceMethodExpr extends MethodExpr{ } } - public void emitUnboxed(C context, FnExpr fn, GeneratorAdapter gen){ + public boolean canEmitPrimitive(){ + return method != null && Util.isPrimitive(method.getReturnType()); + } + + public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitLineNumber(line, gen.mark()); if(method != null) { Type type = Type.getType(method.getDeclaringClass()); - target.emit(C.EXPRESSION, fn, gen); + target.emit(C.EXPRESSION, objx, gen); //if(!method.getDeclaringClass().isInterface()) gen.checkCast(type); - MethodExpr.emitTypedArgs(fn, gen, method.getParameterTypes(), args); + MethodExpr.emitTypedArgs(objx, gen, method.getParameterTypes(), args); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.deref(); + ObjMethod method = (ObjMethod) METHOD.deref(); method.emitClearLocals(gen); } Method m = new Method(methodName, Type.getReturnType(method), Type.getArgumentTypes(method)); @@ -1230,18 +1197,18 @@ static class InstanceMethodExpr extends MethodExpr{ throw new UnsupportedOperationException("Unboxed emit of unknown member"); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitLineNumber(line, gen.mark()); if(method != null) { Type type = Type.getType(method.getDeclaringClass()); - target.emit(C.EXPRESSION, fn, gen); + target.emit(C.EXPRESSION, objx, gen); //if(!method.getDeclaringClass().isInterface()) gen.checkCast(type); - MethodExpr.emitTypedArgs(fn, gen, method.getParameterTypes(), args); + MethodExpr.emitTypedArgs(objx, gen, method.getParameterTypes(), args); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.deref(); + ObjMethod method = (ObjMethod) METHOD.deref(); method.emitClearLocals(gen); } Method m = new Method(methodName, Type.getReturnType(method), Type.getArgumentTypes(method)); @@ -1250,16 +1217,16 @@ static class InstanceMethodExpr extends MethodExpr{ else gen.invokeVirtual(type, m); //if(context != C.STATEMENT || method.getReturnType() == Void.TYPE) - HostExpr.emitBoxReturn(fn, gen, method.getReturnType()); + HostExpr.emitBoxReturn(objx, gen, method.getReturnType()); } else { - target.emit(C.EXPRESSION, fn, gen); + target.emit(C.EXPRESSION, objx, gen); gen.push(methodName); - emitArgsAsArray(args, fn, gen); + emitArgsAsArray(args, objx, gen); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.deref(); + ObjMethod method = (ObjMethod) METHOD.deref(); method.emitClearLocals(gen); } gen.invokeStatic(REFLECTOR_TYPE, invokeInstanceMethodMethod); @@ -1348,15 +1315,19 @@ static class StaticMethodExpr extends MethodExpr{ } } - public void emitUnboxed(C context, FnExpr fn, GeneratorAdapter gen){ + public boolean canEmitPrimitive(){ + return method != null && Util.isPrimitive(method.getReturnType()); + } + + public void emitUnboxed(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitLineNumber(line, gen.mark()); if(method != null) { - MethodExpr.emitTypedArgs(fn, gen, method.getParameterTypes(), args); + MethodExpr.emitTypedArgs(objx, gen, method.getParameterTypes(), args); //Type type = Type.getObjectType(className.replace('.', '/')); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.deref(); + ObjMethod method = (ObjMethod) METHOD.deref(); method.emitClearLocals(gen); } Type type = Type.getType(c); @@ -1367,32 +1338,32 @@ static class StaticMethodExpr extends MethodExpr{ throw new UnsupportedOperationException("Unboxed emit of unknown member"); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitLineNumber(line, gen.mark()); if(method != null) { - MethodExpr.emitTypedArgs(fn, gen, method.getParameterTypes(), args); + MethodExpr.emitTypedArgs(objx, gen, method.getParameterTypes(), args); //Type type = Type.getObjectType(className.replace('.', '/')); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.deref(); + ObjMethod method = (ObjMethod) METHOD.deref(); method.emitClearLocals(gen); } Type type = Type.getType(c); Method m = new Method(methodName, Type.getReturnType(method), Type.getArgumentTypes(method)); gen.invokeStatic(type, m); //if(context != C.STATEMENT || method.getReturnType() == Void.TYPE) - HostExpr.emitBoxReturn(fn, gen, method.getReturnType()); + HostExpr.emitBoxReturn(objx, gen, method.getReturnType()); } else { gen.push(c.getName()); gen.invokeStatic(CLASS_TYPE, forNameMethod); gen.push(methodName); - emitArgsAsArray(args, fn, gen); + emitArgsAsArray(args, objx, gen); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.deref(); + ObjMethod method = (ObjMethod) METHOD.deref(); method.emitClearLocals(gen); } gen.invokeStatic(REFLECTOR_TYPE, invokeStaticMethodMethod); @@ -1426,7 +1397,7 @@ static class UnresolvedVarExpr implements Expr{ "UnresolvedVarExpr has no Java class"); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ } public Object eval() throws Exception{ @@ -1453,8 +1424,8 @@ static class ConstantExpr extends LiteralExpr{ return v; } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - fn.emitConstant(gen, id); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + objx.emitConstant(gen, id); if(context == C.STATEMENT) { gen.pop(); @@ -1505,7 +1476,7 @@ static class NilExpr extends LiteralExpr{ return null; } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ gen.visitInsn(Opcodes.ACONST_NULL); if(context == C.STATEMENT) gen.pop(); @@ -1534,7 +1505,7 @@ static class BooleanExpr extends LiteralExpr{ return val ? RT.T : RT.F; } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ if(val) gen.getStatic(BOOLEAN_OBJECT_TYPE, "TRUE", BOOLEAN_OBJECT_TYPE); else @@ -1568,7 +1539,7 @@ static class StringExpr extends LiteralExpr{ return str; } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ if(context != C.STATEMENT) gen.push(str); } @@ -1582,104 +1553,7 @@ static class StringExpr extends LiteralExpr{ } } -/* -static class NumExpr extends LiteralExpr{ - final Num num; - final static Method numFromIntMethod = Method.getMethod("clojure.lang.Num from(int)"); - final static Method numFromDoubleMethod = Method.getMethod("clojure.lang.Num from(double)"); - final static Method numFromBigIntMethod = Method.getMethod("clojure.lang.Num from(java.math.BigInteger)"); - final static Method numDivideMethod = - Method.getMethod("clojure.lang.Num divide(java.math.BigInteger,java.math.BigInteger)"); - final static Type BIGINT_TYPE = Type.getType(BigInteger.class); - final static Method bigintFromStringCtor = Method.getMethod("void <init>(String)"); - - public NumExpr(Num num){ - this.num = num; - } - - Object val(){ - return num; - } - - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - if(context != C.STATEMENT) - { - Class nclass = num.getClass(); - if(nclass == FixNum.class) - { - gen.push(num.intValue()); - gen.invokeStatic(NUM_TYPE, numFromIntMethod); - } - else if(nclass == DoubleNum.class) - { - gen.push(num.doubleValue()); - gen.invokeStatic(NUM_TYPE, numFromDoubleMethod); - } - else if(nclass == BigNum.class) - { - emitBigInteger(gen, num); - gen.invokeStatic(NUM_TYPE, numFromBigIntMethod); - } - else if(nclass == RatioNum.class) - { - RatioNum r = (RatioNum) num; - emitBigInteger(gen, r.numerator); - emitBigInteger(gen, r.denominator); - gen.invokeStatic(NUM_TYPE, numDivideMethod); - } - else - throw new UnsupportedOperationException("Unknown Num type"); - } - } - - public boolean hasJavaClass(){ - return true; - } - - public Class getJavaClass() throws Exception{ - return Num.class; - } - - static void emitBigInteger(GeneratorAdapter gen, Num num){ - gen.newInstance(BIGINT_TYPE); - gen.dup(); - gen.push(num.toString()); - gen.invokeConstructor(BIGINT_TYPE, bigintFromStringCtor); - } -} - - - -static class CharExpr extends LiteralExpr{ - final Character ch; - final static Type CHARACTER_TYPE = Type.getObjectType("java/lang/Character"); - final static Method charValueOfMethod = Method.getMethod("Character valueOf(char)"); - - public CharExpr(Character ch){ - this.ch = ch; - } - Object val(){ - return ch; - } - - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - if(context != C.STATEMENT) - { - gen.push(ch.charValue()); - gen.invokeStatic(CHARACTER_TYPE, charValueOfMethod); - } - } - - public boolean hasJavaClass(){ - return true; - } - - public Class getJavaClass() throws Exception{ - return Character.class; - } -} - */ static class MonitorEnterExpr extends UntypedExpr{ final Expr target; @@ -1691,10 +1565,10 @@ static class MonitorEnterExpr extends UntypedExpr{ throw new UnsupportedOperationException("Can't eval monitor-enter"); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - target.emit(C.EXPRESSION, fn, gen); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + target.emit(C.EXPRESSION, objx, gen); gen.monitorEnter(); - NIL_EXPR.emit(context, fn, gen); + NIL_EXPR.emit(context, objx, gen); } static class Parser implements IParser{ @@ -1715,10 +1589,10 @@ static class MonitorExitExpr extends UntypedExpr{ throw new UnsupportedOperationException("Can't eval monitor-exit"); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - target.emit(C.EXPRESSION, fn, gen); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + target.emit(C.EXPRESSION, objx, gen); gen.monitorExit(); - NIL_EXPR.emit(context, fn, gen); + NIL_EXPR.emit(context, objx, gen); } static class Parser implements IParser{ @@ -1764,7 +1638,7 @@ public static class TryExpr implements Expr{ throw new UnsupportedOperationException("Can't eval try"); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ Label startTry = gen.newLabel(); Label endTry = gen.newLabel(); Label endTryCatch = gen.newLabel(); @@ -1779,12 +1653,12 @@ public static class TryExpr implements Expr{ } gen.mark(startTry); - tryExpr.emit(context, fn, gen); + tryExpr.emit(context, objx, gen); if(context != C.STATEMENT) gen.visitVarInsn(OBJECT_TYPE.getOpcode(Opcodes.ISTORE), retLocal); gen.mark(endTry); if(finallyExpr != null) - finallyExpr.emit(C.STATEMENT, fn, gen); + finallyExpr.emit(C.STATEMENT, objx, gen); gen.goTo(ret); for(int i = 0; i < catchExprs.count(); i++) @@ -1794,13 +1668,13 @@ public static class TryExpr implements Expr{ //exception should be on stack //put in clause local gen.visitVarInsn(OBJECT_TYPE.getOpcode(Opcodes.ISTORE), clause.lb.idx); - clause.handler.emit(context, fn, gen); + clause.handler.emit(context, objx, gen); if(context != C.STATEMENT) gen.visitVarInsn(OBJECT_TYPE.getOpcode(Opcodes.ISTORE), retLocal); gen.mark(clause.endLabel); if(finallyExpr != null) - finallyExpr.emit(C.STATEMENT, fn, gen); + finallyExpr.emit(C.STATEMENT, objx, gen); gen.goTo(ret); } gen.mark(endTryCatch); @@ -1809,7 +1683,7 @@ public static class TryExpr implements Expr{ gen.mark(finallyLabel); //exception should be on stack gen.visitVarInsn(OBJECT_TYPE.getOpcode(Opcodes.ISTORE), finallyLocal); - finallyExpr.emit(C.STATEMENT, fn, gen); + finallyExpr.emit(C.STATEMENT, objx, gen); gen.visitVarInsn(OBJECT_TYPE.getOpcode(Opcodes.ILOAD), finallyLocal); gen.throwException(); } @@ -1891,7 +1765,8 @@ public static class TryExpr implements Expr{ Var.pushThreadBindings(dynamicBindings); LocalBinding lb = registerLocal(sym, (Symbol) (RT.second(f) instanceof Symbol ? RT.second(f) - : null), null); + : null), + null,false); Expr handler = (new BodyExpr.Parser()).parse(context, RT.next(RT.next(RT.next(f)))); catches = catches.cons(new CatchClause(c, lb, handler)); } @@ -1993,8 +1868,8 @@ static class ThrowExpr extends UntypedExpr{ throw new Exception("Can't eval throw"); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - excExpr.emit(C.EXPRESSION, fn, gen); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + excExpr.emit(C.EXPRESSION, objx, gen); gen.checkCast(THROWABLE_TYPE); gen.throwException(); } @@ -2008,50 +1883,6 @@ static class ThrowExpr extends UntypedExpr{ } } -/* -static class ClassExpr implements Expr{ - final Class c; - final static Method forNameMethod = Method.getMethod("Class forName(String)"); - - - public ClassExpr(Class c){ - this.c = c; - } - - public Object eval() throws Exception{ - return c; - } - - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - if(context != C.STATEMENT) - { - gen.push(c.getName()); - gen.invokeStatic(CLASS_TYPE, forNameMethod); - } - } - - public boolean hasJavaClass(){ - return true; - } - - public Class getJavaClass() throws Exception{ - return Class.class; - } - - static class Parser implements IParser{ - public Expr parse(C context, Object frm) throws Exception{ - ISeq form = (ISeq) frm; - //(class Classname) - if(form.count() != 2) - throw new Exception("wrong number of arguments, expecting: (class Classname)"); - Class c = HostExpr.maybeClass(RT.second(form), true); - if(c == null) - throw new IllegalArgumentException("Unable to resolve classname: " + RT.second(form)); - return new ClassExpr(c); - } - } -} -*/ static public boolean subsumes(Class[] c1, Class[] c2){ //presumes matching lengths @@ -2183,16 +2014,16 @@ public static class NewExpr implements Expr{ return Reflector.invokeConstructor(c, argvals); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ if(this.ctor != null) { Type type = Type.getType(c); gen.newInstance(type); gen.dup(); - MethodExpr.emitTypedArgs(fn, gen, ctor.getParameterTypes(), args); + MethodExpr.emitTypedArgs(objx, gen, ctor.getParameterTypes(), args); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.deref(); + ObjMethod method = (ObjMethod) METHOD.deref(); method.emitClearLocals(gen); } gen.invokeConstructor(type, new Method("<init>", Type.getConstructorDescriptor(ctor))); @@ -2201,10 +2032,10 @@ public static class NewExpr implements Expr{ { gen.push(c.getName()); gen.invokeStatic(CLASS_TYPE, forNameMethod); - MethodExpr.emitArgsAsArray(args, fn, gen); + MethodExpr.emitArgsAsArray(args, objx, gen); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.deref(); + ObjMethod method = (ObjMethod) METHOD.deref(); method.emitClearLocals(gen); } gen.invokeStatic(REFLECTOR_TYPE, invokeConstructorMethod); @@ -2225,6 +2056,8 @@ public static class NewExpr implements Expr{ public Expr parse(C context, Object frm) throws Exception{ int line = (Integer) LINE.deref(); ISeq form = (ISeq) frm; + if(RT.second(form) instanceof IPersistentVector) + return NewInstanceExpr.parse(context, form); //(new Classname args...) if(form.count() < 2) throw new Exception("wrong number of arguments, expecting: (new Classname args...)"); @@ -2240,113 +2073,6 @@ public static class NewExpr implements Expr{ } -//static class IdenticalExpr implements Expr{ -// final Expr expr1; -// final Expr expr2; -// -// -// public IdenticalExpr(Expr expr1, Expr expr2){ -// this.expr1 = expr1; -// this.expr2 = expr2; -// } -// -// public boolean hasJavaClass(){ -// return true; -// } -// -// public Class getJavaClass(){ -// return Boolean.class; -// } -// -// public Object eval() throws Exception{ -// return expr1.eval() == expr2.eval() ? -// RT.T : RT.F; -// } -// -// public void emit(C context, FnExpr fn, GeneratorAdapter gen){ -// if(context != C.STATEMENT) -// { -// Label not = gen.newLabel(); -// Label end = gen.newLabel(); -// expr1.emit(C.EXPRESSION, fn, gen); -// expr2.emit(C.EXPRESSION, fn, gen); -// gen.visitJumpInsn(IF_ACMPNE, not); -// gen.getStatic(BOOLEAN_OBJECT_TYPE, "TRUE", BOOLEAN_OBJECT_TYPE); -//// gen.getStatic(RT_TYPE, "T", KEYWORD_TYPE); -// gen.goTo(end); -// gen.mark(not); -// gen.getStatic(BOOLEAN_OBJECT_TYPE, "FALSE", BOOLEAN_OBJECT_TYPE); -//// NIL_EXPR.emit(C.EXPRESSION, fn, gen); -// gen.mark(end); -// } -// } -// -// static class Parser implements IParser{ -// public Expr parse(C context, Object frm) throws Exception{ -// ISeq form = (ISeq) frm; -// if(form.count() != 3) -// throw new Exception("wrong number of arguments, expecting: (identical? x y)"); -// -// return new IdenticalExpr(analyze(C.EXPRESSION, RT.second(form)), analyze(C.EXPRESSION, RT.third(form))); -// } -// } -//} - -//static class InstanceExpr implements Expr{ -// final Expr expr; -// final Class c; -// -// -// public InstanceExpr(Expr expr, Class c){ -// this.expr = expr; -// this.c = c; -// } -// -// public Object eval() throws Exception{ -// return c.isInstance(expr.eval()) ? -// RT.T : RT.F; -// } -// -// public boolean hasJavaClass(){ -// return true; -// } -// -// public Class getJavaClass(){ -// return Boolean.class; -// } -// -// public void emit(C context, FnExpr fn, GeneratorAdapter gen){ -// if(context != C.STATEMENT) -// { -// Label not = gen.newLabel(); -// Label end = gen.newLabel(); -// expr.emit(C.EXPRESSION, fn, gen); -// gen.instanceOf(Type.getType(c)); -// gen.ifZCmp(GeneratorAdapter.EQ, not); -// gen.getStatic(BOOLEAN_OBJECT_TYPE, "TRUE", BOOLEAN_OBJECT_TYPE); -//// gen.getStatic(RT_TYPE, "T", KEYWORD_TYPE); -// gen.goTo(end); -// gen.mark(not); -// gen.getStatic(BOOLEAN_OBJECT_TYPE, "FALSE", BOOLEAN_OBJECT_TYPE); -//// NIL_EXPR.emit(C.EXPRESSION, fn, gen); -// gen.mark(end); -// } -// } -// -// static class Parser implements IParser{ -// public Expr parse(C context, Object frm) throws Exception{ -// ISeq form = (ISeq) frm; -// //(instance? x Classname) -// if(form.count() != 3) -// throw new Exception("wrong number of arguments, expecting: (instance? x Classname)"); -// Class c = HostExpr.maybeClass(RT.third(form), true); -// if(c == null) -// throw new IllegalArgumentException("Unable to resolve classname: " + RT.third(form)); -// return new InstanceExpr(analyze(C.EXPRESSION, RT.second(form)), c); -// } -// } -//} - public static class MetaExpr implements Expr{ public final Expr expr; public final MapExpr meta; @@ -2363,10 +2089,10 @@ public static class MetaExpr implements Expr{ return ((IObj) expr.eval()).withMeta((IPersistentMap) meta.eval()); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - expr.emit(C.EXPRESSION, fn, gen); + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + expr.emit(C.EXPRESSION, objx, gen); gen.checkCast(IOBJ_TYPE); - meta.emit(C.EXPRESSION, fn, gen); + meta.emit(C.EXPRESSION, objx, gen); gen.checkCast(IPERSISTENTMAP_TYPE); gen.invokeInterface(IOBJ_TYPE, withMetaMethod); if(context == C.STATEMENT) @@ -2405,7 +2131,7 @@ public static class IfExpr implements Expr{ return elseExpr.eval(); } - public void emit(C context, FnExpr fn, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ Label nullLabel = gen.newLabel(); Label falseLabel = gen.newLabel |