diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-06-10 13:54:35 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-06-10 13:54:35 -0400 |
commit | c7af275d4ee33cdc1794c8df8fa1e6d39039ac84 (patch) | |
tree | 33c0dd940f364341c737c40a8c7e6e42309b65df | |
parent | 826c815fbd912c79fdd501d5fe0d8678f0a3450b (diff) |
simplified keyword callsites, made compatible with static fns
-rw-r--r-- | src/clj/clojure/core.clj | 6 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 118 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ILookupHost.java | 19 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ILookupSite.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/KeywordLookupSite.java | 24 |
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()); } } |