diff options
Diffstat (limited to 'src/jvm')
-rw-r--r-- | src/jvm/clojure/lang/AFn.java | 47 | ||||
-rw-r--r-- | src/jvm/clojure/lang/AFunction.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 3264 | ||||
-rw-r--r-- | src/jvm/clojure/lang/DynamicClassLoader.java | 45 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IDynamicType.java | 22 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IKeywordLookup.java | 17 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ILookupHost.java | 19 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ILookupSite.java | 19 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ILookupThunk.java | 19 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Keyword.java | 16 | ||||
-rw-r--r-- | src/jvm/clojure/lang/KeywordLookupSite.java | 65 | ||||
-rw-r--r-- | src/jvm/clojure/lang/MethodImplCache.java | 52 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentList.java | 8 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentStructMap.java | 20 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Reflector.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RestFn.java | 187 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Util.java | 18 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Var.java | 6 |
18 files changed, 2856 insertions, 974 deletions
diff --git a/src/jvm/clojure/lang/AFn.java b/src/jvm/clojure/lang/AFn.java index e2646ade..9a86cd2a 100644 --- a/src/jvm/clojure/lang/AFn.java +++ b/src/jvm/clojure/lang/AFn.java @@ -161,37 +161,40 @@ public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object } public Object applyTo(ISeq arglist) throws Exception{ - return applyToHelper(this, arglist); + return applyToHelper(this, Util.ret1(arglist,arglist = null)); } static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ switch(RT.boundedLength(arglist, 20)) { case 0: + arglist = null; return ifn.invoke(); case 1: - return ifn.invoke(arglist.first()); + Object a1 = arglist.first(); + arglist = null; + return ifn.invoke(a1); case 2: return ifn.invoke(arglist.first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 3: return ifn.invoke(arglist.first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 4: return ifn.invoke(arglist.first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 5: return ifn.invoke(arglist.first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 6: return ifn.invoke(arglist.first() @@ -199,7 +202,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 7: return ifn.invoke(arglist.first() @@ -208,7 +211,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 8: return ifn.invoke(arglist.first() @@ -218,7 +221,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 9: return ifn.invoke(arglist.first() @@ -229,7 +232,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 10: return ifn.invoke(arglist.first() @@ -241,7 +244,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 11: return ifn.invoke(arglist.first() @@ -254,7 +257,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 12: return ifn.invoke(arglist.first() @@ -268,7 +271,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 13: return ifn.invoke(arglist.first() @@ -283,7 +286,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 14: return ifn.invoke(arglist.first() @@ -299,7 +302,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 15: return ifn.invoke(arglist.first() @@ -316,7 +319,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 16: return ifn.invoke(arglist.first() @@ -334,7 +337,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 17: return ifn.invoke(arglist.first() @@ -353,7 +356,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 18: return ifn.invoke(arglist.first() @@ -373,7 +376,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 19: return ifn.invoke(arglist.first() @@ -394,7 +397,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); case 20: return ifn.invoke(arglist.first() @@ -416,7 +419,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , (arglist = arglist.next()).first() + , Util.ret1((arglist = arglist.next()).first(),arglist = null) ); default: return ifn.invoke(arglist.first() @@ -439,7 +442,7 @@ static public Object applyToHelper(IFn ifn, ISeq arglist) throws Exception{ , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() , (arglist = arglist.next()).first() - , RT.seqToArray(arglist.next())); + , RT.seqToArray(Util.ret1(arglist.next(),arglist = null))); } } diff --git a/src/jvm/clojure/lang/AFunction.java b/src/jvm/clojure/lang/AFunction.java index 82a79070..d89e88e6 100644 --- a/src/jvm/clojure/lang/AFunction.java +++ b/src/jvm/clojure/lang/AFunction.java @@ -16,6 +16,9 @@ import java.util.Comparator; public abstract class AFunction extends AFn implements Comparator, Fn{ +//note - this is not even volatile by design +public MethodImplCache __methodImplCache; + public AFunction(IPersistentMap meta){ super(meta); } diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index d70380d9..46d167d8 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -55,10 +55,14 @@ static final Symbol MONITOR_ENTER = Symbol.create("monitor-enter"); static final Symbol MONITOR_EXIT = Symbol.create("monitor-exit"); static final Symbol IMPORT = Symbol.create("clojure.core", "import*"); //static final Symbol INSTANCE = Symbol.create("instance?"); +static final Symbol DEFTYPE = Symbol.create("deftype*"); +static final Symbol CASE = Symbol.create("case*"); //static final Symbol THISFN = Symbol.create("thisfn"); static final Symbol CLASS = Symbol.create("Class"); static final Symbol NEW = Symbol.create("new"); +static final Symbol THIS = Symbol.create("this"); +static final Symbol REIFY = Symbol.create("reify*"); //static final Symbol UNQUOTE = Symbol.create("unquote"); //static final Symbol UNQUOTE_SPLICING = Symbol.create("unquote-splicing"); //static final Symbol SYNTAX_QUOTE = Symbol.create("clojure.core", "syntax-quote"); @@ -73,6 +77,13 @@ 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 Keyword implementsKey = Keyword.intern(null, "implements"); +static final String COMPILE_STUB_PREFIX = "compile__stub"; + +static final Keyword protocolKey = Keyword.intern(null, "protocol"); +static final Keyword onKey = Keyword.intern(null, "on"); + static final Symbol NS = Symbol.create("ns"); static final Symbol IN_NS = Symbol.create("in-ns"); @@ -86,6 +97,7 @@ static final public IPersistentMap specials = PersistentHashMap.create( LOOP, new LetExpr.Parser(), RECUR, new RecurExpr.Parser(), IF, new IfExpr.Parser(), + CASE, new CaseExpr.Parser(), LET, new LetExpr.Parser(), LETFN, new LetFnExpr.Parser(), DO, new BodyExpr.Parser(), @@ -95,6 +107,8 @@ static final public IPersistentMap specials = PersistentHashMap.create( IMPORT, new ImportExpr.Parser(), DOT, new HostExpr.Parser(), ASSIGN, new AssignExpr.Parser(), + DEFTYPE, new NewInstanceExpr.DeftypeParser(), + REIFY, new NewInstanceExpr.ReifyParser(), // TRY_FINALLY, new TryFinallyExpr.Parser(), TRY, new TryExpr.Parser(), THROW, new ThrowExpr.Parser(), @@ -120,9 +134,11 @@ private static final Type VAR_TYPE = Type.getType(Var.class); private static final Type SYMBOL_TYPE = Type.getType(Symbol.class); //private static final Type NUM_TYPE = Type.getType(Num.class); private static final Type IFN_TYPE = Type.getType(IFn.class); +private static final Type AFUNCTION_TYPE = Type.getType(AFunction.class); private static final Type RT_TYPE = Type.getType(RT.class); final static Type CLASS_TYPE = Type.getType(Class.class); final static Type NS_TYPE = Type.getType(Namespace.class); +final static Type UTIL_TYPE = Type.getType(Util.class); final static Type REFLECTOR_TYPE = Type.getType(Reflector.class); final static Type THROWABLE_TYPE = Type.getType(Throwable.class); final static Type BOOLEAN_OBJECT_TYPE = Type.getType(Boolean.class); @@ -165,6 +181,15 @@ static final public Var LOOP_LABEL = Var.create(); //vector<object> static final public Var CONSTANTS = Var.create(); +//vector<keyword> +static final public Var KEYWORD_CALLSITES = Var.create(); + +//vector<var> +static final public Var PROTOCOL_CALLSITES = Var.create(); + +//vector<var> +static final public Var VAR_CALLSITES = Var.create(); + //keyword->constid static final public Var KEYWORDS = Var.create(); @@ -195,6 +220,9 @@ static final public Var COMPILE_PATH = Var.intern(Namespace.findOrCreate(Symbol. static final public Var COMPILE_FILES = Var.intern(Namespace.findOrCreate(Symbol.create("clojure.core")), Symbol.create("*compile-files*"), Boolean.FALSE); +static final public Var INSTANCE = Var.intern(Namespace.findOrCreate(Symbol.create("clojure.core")), + Symbol.create("instance?")); + //Integer static final public Var LINE = Var.create(0); @@ -209,7 +237,20 @@ static final public Var NEXT_LOCAL_NUM = Var.create(0); static final public Var RET_LOCAL_NUM = Var.create(); -public enum C{ +static final public Var COMPILE_STUB_SYM = Var.create(null); +static final public Var COMPILE_STUB_CLASS = Var.create(null); + + +//PathNode chain +static final public Var CLEAR_PATH = Var.create(null); + +//tail of PathNode chain +static final public Var CLEAR_ROOT = Var.create(null); + +//LocalBinding -> Set<LocalBindingExpr> +static final public Var CLEAR_SITES = Var.create(null); + + public enum C{ STATEMENT, //value ignored EXPRESSION, //value required RETURN, //tail position relative to enclosing recur frame @@ -219,7 +260,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 +357,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 +431,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 +471,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 +492,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 +513,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 +549,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 +581,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 +618,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 +660,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 +678,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 +708,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) @@ -784,18 +777,18 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ { Symbol sym = (Symbol) RT.third(form); if(c != null) - maybeField = Reflector.getMethods(c, 0, sym.name, true).size() == 0; + maybeField = Reflector.getMethods(c, 0, munge(sym.name), true).size() == 0; else if(instance != null && instance.hasJavaClass() && instance.getJavaClass() != null) - maybeField = Reflector.getMethods(instance.getJavaClass(), 0, sym.name, false).size() == 0; + maybeField = Reflector.getMethods(instance.getJavaClass(), 0, munge(sym.name), false).size() == 0; } if(maybeField) //field { Symbol sym = (Symbol) RT.third(form); Symbol tag = tagOf(form); if(c != null) { - return new StaticFieldExpr(line, c, sym.name, tag); + return new StaticFieldExpr(line, c, munge(sym.name), tag); } else - return new InstanceFieldExpr(line, instance, sym.name, tag); + return new InstanceFieldExpr(line, instance, munge(sym.name), tag); } else { @@ -808,9 +801,9 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ for(ISeq s = RT.next(call); s != null; s = s.next()) args = args.cons(analyze(context == C.EVAL ? context : C.EXPRESSION, s.first())); if(c != null) - return new StaticMethodExpr(source, line, tag, c, sym.name, args); + return new StaticMethodExpr(source, line, tag, c, munge(sym.name), args); else - return new InstanceMethodExpr(source, line, tag, instance, sym.name, args); + return new InstanceMethodExpr(source, line, tag, instance, munge(sym.name), args); } } } @@ -824,6 +817,8 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ Symbol sym = (Symbol) form; if(sym.ns == null) //if ns-qualified can't be classname { + if(Util.equals(sym,COMPILE_STUB_SYM.get())) + return (Class) COMPILE_STUB_CLASS.get(); if(sym.name.indexOf('.') > 0 || sym.name.charAt(0) == '[') c = RT.classForName(sym.name); else @@ -927,27 +922,32 @@ 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); - gen.checkCast(Type.getType(targetClass)); - gen.getField(Type.getType(targetClass), fieldName, Type.getType(field.getType())); + target.emit(C.EXPRESSION, objx, gen); + gen.checkCast(getType(targetClass)); + gen.getField(getType(targetClass), fieldName, Type.getType(field.getType())); } else 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); - gen.checkCast(Type.getType(targetClass)); - gen.getField(Type.getType(targetClass), fieldName, Type.getType(field.getType())); + target.emit(C.EXPRESSION, objx, gen); + gen.checkCast(getType(targetClass)); + gen.getField(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(); @@ -955,7 +955,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) @@ -975,23 +975,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) @@ -1023,17 +1023,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(); @@ -1057,12 +1061,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(); @@ -1074,7 +1078,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)) @@ -1089,19 +1093,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); @@ -1109,12 +1113,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) @@ -1214,18 +1218,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)); @@ -1238,18 +1246,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)); @@ -1258,16 +1266,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); @@ -1358,15 +1366,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); @@ -1377,32 +1389,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.getParameter |