summaryrefslogtreecommitdiff
path: root/src/jvm
diff options
context:
space:
mode:
Diffstat (limited to 'src/jvm')
-rw-r--r--src/jvm/clojure/lang/AFn.java47
-rw-r--r--src/jvm/clojure/lang/AFunction.java3
-rw-r--r--src/jvm/clojure/lang/Compiler.java3264
-rw-r--r--src/jvm/clojure/lang/DynamicClassLoader.java45
-rw-r--r--src/jvm/clojure/lang/IDynamicType.java22
-rw-r--r--src/jvm/clojure/lang/IKeywordLookup.java17
-rw-r--r--src/jvm/clojure/lang/ILookupHost.java19
-rw-r--r--src/jvm/clojure/lang/ILookupSite.java19
-rw-r--r--src/jvm/clojure/lang/ILookupThunk.java19
-rw-r--r--src/jvm/clojure/lang/Keyword.java16
-rw-r--r--src/jvm/clojure/lang/KeywordLookupSite.java65
-rw-r--r--src/jvm/clojure/lang/MethodImplCache.java52
-rw-r--r--src/jvm/clojure/lang/PersistentList.java8
-rw-r--r--src/jvm/clojure/lang/PersistentStructMap.java20
-rw-r--r--src/jvm/clojure/lang/Reflector.java3
-rw-r--r--src/jvm/clojure/lang/RestFn.java187
-rw-r--r--src/jvm/clojure/lang/Util.java18
-rw-r--r--src/jvm/clojure/lang/Var.java6
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