summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj8
-rw-r--r--src/jvm/clojure/lang/Compiler.java1825
-rw-r--r--src/jvm/clojure/lang/PersistentList.java8
-rw-r--r--src/jvm/clojure/lang/Reflector.java3
-rw-r--r--src/jvm/clojure/lang/RestFn.java55
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