diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-11-03 17:06:36 -0500 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-11-03 17:06:36 -0500 |
commit | d8ae62ddb57de78e1f35b86dc179a1faf1717055 (patch) | |
tree | 61040338ede20c5e146d8f4f64aba343309dde00 /src | |
parent | a88ce1882218c83e410d430fab63fbc9331aaba0 (diff) |
tweaks to keyword call sites, enable in defclass/type by default
Diffstat (limited to 'src')
-rw-r--r-- | src/clj/clojure/core_deftype.clj | 14 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 41 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ILookupThunk.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/KeywordLookupSite.java | 19 |
4 files changed, 54 insertions, 22 deletions
diff --git a/src/clj/clojure/core_deftype.clj b/src/clj/clojure/core_deftype.clj index c778906e..3149e954 100644 --- a/src/clj/clojure/core_deftype.clj +++ b/src/clj/clojure/core_deftype.clj @@ -55,6 +55,18 @@ base-fields) (get ~'__extmap k# else#))))] [i m])) + (ikeywordlookup [[i m]] + [(conj i 'clojure.lang.IKeywordLookup) + (conj m + `(.getLookupThunk [k#] + (case k# + ~@(mapcat + (fn [fld] + (let [cstr (str (clojure.core/name classname) "$__lookup__" (clojure.core/name fld))] + [(keyword fld) + `(-> ~cstr (Class/forName) (.newInstance))])) + base-fields) + nil)))]) (imap [[i m]] (if (and (interface-set clojure.lang.IPersistentMap) (not (methodname-set '.assoc))) [i @@ -81,7 +93,7 @@ (new ~name ~@(remove #{'__extmap} fields) (not-empty (dissoc ~'__extmap k#))))))] [i m]))] - (let [[i m] (-> [interfaces methods] eqhash iobj ilookup imap)] + (let [[i m] (-> [interfaces methods] eqhash iobj ilookup imap ikeywordlookup)] `(defclass* ~classname ~(conj hinted-fields '__meta '__extmap) :implements ~(vec i) ~@m))))) diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index c734723e..bcfa3337 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -2515,7 +2515,36 @@ static class KeywordInvokeExpr implements Expr{ } } - public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + public void emit(C context, ObjExpr objx, GeneratorAdapter gen){ + Label endLabel = gen.newLabel(); + Label faultLabel = gen.newLabel(); + + 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.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.invokeInterface(ObjExpr.ILOOKUP_SITE_TYPE, + Method.getMethod("Object fault(Object, clojure.lang.ILookupHost)")); + + 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(); @@ -5546,8 +5575,7 @@ static public class NewInstanceExpr extends ObjExpr{ ctorgen.returnValue(); ctorgen.endMethod(); - Method meth = Method.getMethod("Object get(Object, clojure.lang.ILookupSite)"); -// Method meth = Method.getMethod("Object get(Object, clojure.lang.ILookupSite, clojure.lang.ILookupHost)"); + Method meth = Method.getMethod("Object get(Object)"); GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC, meth, @@ -5564,17 +5592,12 @@ static public class NewInstanceExpr extends ObjExpr{ gen.ifZCmp(GeneratorAdapter.EQ, faultLabel); gen.checkCast(ret.objtype); gen.getField(ret.objtype, fld.name, ftype); -// gen.getField(ret.objtype, fld.name, ftype); HostExpr.emitBoxReturn(ret,gen,fclass); gen.goTo(endLabel); gen.mark(faultLabel); gen.pop(); - gen.loadArg(1); -// gen.swap(); -// gen.loadArg(2); -// gen.invokeInterface(ObjExpr.ILOOKUP_SITE_TYPE, -// Method.getMethod("Object fault(Object, clojure.lang.ILookupHost)")); + gen.loadThis(); gen.mark(endLabel); gen.returnValue(); diff --git a/src/jvm/clojure/lang/ILookupThunk.java b/src/jvm/clojure/lang/ILookupThunk.java index 49f68aa7..66bbc4ce 100644 --- a/src/jvm/clojure/lang/ILookupThunk.java +++ b/src/jvm/clojure/lang/ILookupThunk.java @@ -14,6 +14,6 @@ package clojure.lang; public interface ILookupThunk{ -Object get(Object target, ILookupSite site); +Object get(Object target); } diff --git a/src/jvm/clojure/lang/KeywordLookupSite.java b/src/jvm/clojure/lang/KeywordLookupSite.java index de762a46..813f754f 100644 --- a/src/jvm/clojure/lang/KeywordLookupSite.java +++ b/src/jvm/clojure/lang/KeywordLookupSite.java @@ -29,16 +29,13 @@ public Object fault(Object target, ILookupHost host){ } else if(target instanceof ILookup) { -// final Class c = target.getClass(); + final Class c = target.getClass(); host.swapThunk(n,new ILookupThunk(){ - public Object get(Object target, ILookupSite site){ - if(target instanceof ILookup) - return ((ILookup)target).valAt(k); - return RT.get(target, k); -// if(target != null && target.getClass() == c) -// return ((ILookup) target).valAt(k); -// return site; + public Object get(Object target){ + if(target != null && target.getClass() == c) + return ((ILookup) target).valAt(k); + return this; } }); return ((ILookup) target).valAt(k); @@ -47,15 +44,15 @@ public Object fault(Object target, ILookupHost host){ return RT.get(target, k); } -public Object get(Object target, ILookupSite site){ +public Object get(Object target){ if(target instanceof IKeywordLookup || target instanceof ILookup) - return site; + return this; return RT.get(target,k); } private Object install(Object target, ILookupHost host){ ILookupThunk t = ((IKeywordLookup)target).getLookupThunk(k); host.swapThunk(n,t); - return t.get(target, this); + return t.get(target); } } |