summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-06-10 13:54:35 -0400
committerRich Hickey <richhickey@gmail.com>2010-06-10 13:54:35 -0400
commitc7af275d4ee33cdc1794c8df8fa1e6d39039ac84 (patch)
tree33c0dd940f364341c737c40a8c7e6e42309b65df
parent826c815fbd912c79fdd501d5fe0d8678f0a3450b (diff)
simplified keyword callsites, made compatible with static fns
-rw-r--r--src/clj/clojure/core.clj6
-rw-r--r--src/jvm/clojure/lang/Compiler.java118
-rw-r--r--src/jvm/clojure/lang/ILookupHost.java19
-rw-r--r--src/jvm/clojure/lang/ILookupSite.java2
-rw-r--r--src/jvm/clojure/lang/KeywordLookupSite.java24
5 files changed, 31 insertions, 138 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index faa8fac0..d0aa27c7 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -1644,7 +1644,7 @@
default if no error-handler is given) -- see set-error-mode! for
details."
{:added "1.0"
- ;:static true ;can't due to keyword callsite
+ :static true
}
([state & options]
(let [a (new clojure.lang.Agent state)
@@ -1735,7 +1735,7 @@
any, will NOT be notified of the new state. Throws an exception if
the agent is not failed."
{:added "1.2"
- ;:static true ;can't due to keyword callsite
+ :static true
}
[^clojure.lang.Agent a, new-state & options]
(let [opts (apply hash-map options)]
@@ -1833,7 +1833,7 @@
of after a read fault). History is limited, and the limit can be set
with :max-history."
{:added "1.0"
- ;:static true ;can't due to keyword callsite
+ :static true
}
([x] (new clojure.lang.Ref x))
([x & options]
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 79c373b0..abcccd01 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -2706,100 +2706,33 @@ static class KeywordInvokeExpr implements Expr{
gen.visitLineNumber(line, gen.mark());
gen.getStatic(objx.objtype, objx.thunkNameStatic(siteIndex),ObjExpr.ILOOKUP_THUNK_TYPE);
- gen.dup();
- target.emit(C.EXPRESSION, objx, gen);
- gen.dupX2();
- gen.invokeInterface(ObjExpr.ILOOKUP_THUNK_TYPE, Method.getMethod("Object get(Object)"));
- gen.dupX2();
- gen.visitJumpInsn(IF_ACMPEQ, faultLabel);
- gen.pop();
+ gen.dup(); //thunk, thunk
+ target.emit(C.EXPRESSION, objx, gen); //thunk,thunk,target
+ gen.dupX2(); //target,thunk,thunk,target
+ gen.invokeInterface(ObjExpr.ILOOKUP_THUNK_TYPE, Method.getMethod("Object get(Object)")); //target,thunk,result
+ gen.dupX2(); //result,target,thunk,result
+ gen.visitJumpInsn(IF_ACMPEQ, faultLabel); //result,target
+ gen.pop(); //result
gen.goTo(endLabel);
- gen.mark(faultLabel);
- gen.swap();
- gen.pop();
- gen.getStatic(objx.objtype, objx.siteNameStatic(siteIndex),ObjExpr.KEYWORD_LOOKUPSITE_TYPE);
- gen.swap();
- gen.loadThis();
+ gen.mark(faultLabel); //result,target
+ gen.swap(); //target,result
+ gen.pop(); //target
+ gen.dup(); //target,target
+ gen.getStatic(objx.objtype, objx.siteNameStatic(siteIndex),ObjExpr.KEYWORD_LOOKUPSITE_TYPE); //target,target,site
+ gen.swap(); //target,site,target
gen.invokeInterface(ObjExpr.ILOOKUP_SITE_TYPE,
- Method.getMethod("Object fault(Object, clojure.lang.ILookupHost)"));
+ Method.getMethod("clojure.lang.ILookupThunk fault(Object)")); //target,new-thunk
+ gen.dup(); //target,new-thunk,new-thunk
+ gen.putStatic(objx.objtype, objx.thunkNameStatic(siteIndex),ObjExpr.ILOOKUP_THUNK_TYPE); //target,new-thunk
+ gen.swap(); //new-thunk,target
+ gen.invokeInterface(ObjExpr.ILOOKUP_THUNK_TYPE, Method.getMethod("Object get(Object)")); //result
gen.mark(endLabel);
if(context == C.STATEMENT)
gen.pop();
}
- public void emit2(C context, ObjExpr objx, GeneratorAdapter gen){
- Label endLabel = gen.newLabel();
- Label faultLabel = gen.newLabel();
-
- gen.visitLineNumber(line, gen.mark());
- target.emit(C.EXPRESSION, objx, gen);
- gen.dup();
- gen.getStatic(objx.objtype, objx.thunkNameStatic(siteIndex),ObjExpr.ILOOKUP_THUNK_TYPE);
- gen.swap();
- gen.getStatic(objx.objtype, objx.siteNameStatic(siteIndex),ObjExpr.KEYWORD_LOOKUPSITE_TYPE);
-/// gen.loadThis();
- gen.invokeInterface(ObjExpr.ILOOKUP_THUNK_TYPE,
- Method.getMethod("Object get(Object,clojure.lang.ILookupSite)"));
-// gen.invokeInterface(ObjExpr.ILOOKUP_THUNK_TYPE,
-// Method.getMethod("Object get(Object,clojure.lang.ILookupSite,clojure.lang.ILookupHost)"));
- gen.dup();
- gen.getStatic(objx.objtype, objx.siteNameStatic(siteIndex),ObjExpr.KEYWORD_LOOKUPSITE_TYPE);
- gen.visitJumpInsn(IF_ACMPEQ, faultLabel);
- gen.swap();
- gen.pop();
- gen.goTo(endLabel);
-
- gen.mark(faultLabel);
- gen.swap();
- gen.loadThis();
- gen.invokeInterface(ObjExpr.ILOOKUP_SITE_TYPE,
- Method.getMethod("Object fault(Object, clojure.lang.ILookupHost)"));
-
- gen.mark(endLabel);
- if(context == C.STATEMENT)
- gen.pop();
- }
-
- public void emitInstance(C context, ObjExpr objx, GeneratorAdapter gen){
- gen.visitLineNumber(line, gen.mark());
- gen.loadThis();
- gen.getField(objx.objtype, objx.thunkName(siteIndex),ObjExpr.ILOOKUP_THUNK_TYPE);
- target.emit(C.EXPRESSION, objx, gen);
- gen.loadThis();
- gen.getField(objx.objtype, objx.siteName(siteIndex),ObjExpr.ILOOKUP_SITE_TYPE);
- gen.loadThis();
- gen.checkCast(Type.getType(ILookupHost.class));
- gen.invokeInterface(ObjExpr.ILOOKUP_THUNK_TYPE,
- Method.getMethod("Object get(Object,clojure.lang.ILookupSite,clojure.lang.ILookupHost)"));
- if(context == C.STATEMENT)
- gen.pop();
- }
-
- public void emitNormal(C context, ObjExpr objx, GeneratorAdapter gen){
- Label slowLabel = gen.newLabel();
- Label endLabel = gen.newLabel();
-
- gen.visitLineNumber(line, gen.mark());
- target.emit(C.EXPRESSION, objx, gen);
- gen.dup();
- gen.instanceOf(ILOOKUP_TYPE);
- gen.ifZCmp(GeneratorAdapter.EQ, slowLabel);
- kw.emit(C.EXPRESSION, objx, gen);
- gen.invokeInterface(ILOOKUP_TYPE, new Method("valAt", OBJECT_TYPE, ARG_TYPES[1]));
- gen.goTo(endLabel);
-
- gen.mark(slowLabel);
- kw.emit(C.EXPRESSION, objx, gen);
- gen.invokeStatic(RT_TYPE, new Method("get", OBJECT_TYPE, ARG_TYPES[2]));
-
- gen.mark(endLabel);
-
- if(context == C.STATEMENT)
- gen.pop();
- }
-
public boolean hasJavaClass() throws Exception{
return tag != null;
}
@@ -3613,18 +3546,6 @@ static public class ObjExpr implements Expr{
//with name current_ns.defname[$letname]+
//anonymous fns get names fn__id
//derived from AFn/RestFn
- if(keywordCallsites.count() > 0)
- {
- if(interfaceNames == null)
- interfaceNames = new String[]{"clojure/lang/ILookupHost"};
- else
- {
- String[] inames = new String[interfaceNames.length + 1];
- System.arraycopy(interfaceNames,0,inames,0,interfaceNames.length);
- inames[interfaceNames.length] = "clojure/lang/ILookupHost";
- interfaceNames = inames;
- }
- }
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
// ClassWriter cw = new ClassWriter(0);
ClassVisitor cv = cw;
@@ -3977,10 +3898,9 @@ static public class ObjExpr implements Expr{
Keyword k = (Keyword) keywordCallsites.nth(i);
clinitgen.newInstance(KEYWORD_LOOKUPSITE_TYPE);
clinitgen.dup();
- clinitgen.push(i);
emitValue(k,clinitgen);
clinitgen.invokeConstructor(KEYWORD_LOOKUPSITE_TYPE,
- Method.getMethod("void <init>(int,clojure.lang.Keyword)"));
+ Method.getMethod("void <init>(clojure.lang.Keyword)"));
clinitgen.dup();
clinitgen.putStatic(objtype, siteNameStatic(i), KEYWORD_LOOKUPSITE_TYPE);
clinitgen.putStatic(objtype, thunkNameStatic(i), ILOOKUP_THUNK_TYPE);
diff --git a/src/jvm/clojure/lang/ILookupHost.java b/src/jvm/clojure/lang/ILookupHost.java
deleted file mode 100644
index ede82876..00000000
--- a/src/jvm/clojure/lang/ILookupHost.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) Rich Hickey. All rights reserved.
- * The use and distribution terms for this software are covered by the
- * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
- * which can be found in the file epl-v10.html at the root of this distribution.
- * By using this software in any fashion, you are agreeing to be bound by
- * the terms of this license.
- * You must not remove this notice, or any other, from this software.
- **/
-
-/* rich Nov 2, 2009 */
-
-package clojure.lang;
-
-public interface ILookupHost{
-
-void swapThunk(int n, ILookupThunk thunk);
-
-}
diff --git a/src/jvm/clojure/lang/ILookupSite.java b/src/jvm/clojure/lang/ILookupSite.java
index 0609974e..0ae6e19b 100644
--- a/src/jvm/clojure/lang/ILookupSite.java
+++ b/src/jvm/clojure/lang/ILookupSite.java
@@ -14,6 +14,6 @@ package clojure.lang;
public interface ILookupSite{
-Object fault(Object target, ILookupHost host);
+ILookupThunk fault(Object target);
}
diff --git a/src/jvm/clojure/lang/KeywordLookupSite.java b/src/jvm/clojure/lang/KeywordLookupSite.java
index 02ddfffa..5c2f14f7 100644
--- a/src/jvm/clojure/lang/KeywordLookupSite.java
+++ b/src/jvm/clojure/lang/KeywordLookupSite.java
@@ -14,26 +14,22 @@ package clojure.lang;
public final class KeywordLookupSite implements ILookupSite, ILookupThunk{
-final int n;
final Keyword k;
-public KeywordLookupSite(int n, Keyword k){
- this.n = n;
+public KeywordLookupSite(Keyword k){
this.k = k;
}
-public Object fault(Object target, ILookupHost host){
+public ILookupThunk fault(Object target){
if(target instanceof IKeywordLookup)
{
- return install(target, host);
+ return install(target);
}
else if(target instanceof ILookup)
{
- host.swapThunk(n,ilookupThunk(target.getClass()));
- return ((ILookup) target).valAt(k);
+ return ilookupThunk(target.getClass());
}
- host.swapThunk(n,this);
- return RT.get(target, k);
+ return this;
}
public Object get(Object target){
@@ -52,14 +48,10 @@ private ILookupThunk ilookupThunk(final Class c){
};
}
-private Object install(Object target, ILookupHost host){
+private ILookupThunk install(Object target){
ILookupThunk t = ((IKeywordLookup)target).getLookupThunk(k);
if(t != null)
- {
- host.swapThunk(n,t);
- return t.get(target);
- }
- host.swapThunk(n,ilookupThunk(target.getClass()));
- return ((ILookup) target).valAt(k);
+ return t;
+ return ilookupThunk(target.getClass());
}
}