summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2009-11-03 17:06:36 -0500
committerRich Hickey <richhickey@gmail.com>2009-11-03 17:06:36 -0500
commitd8ae62ddb57de78e1f35b86dc179a1faf1717055 (patch)
tree61040338ede20c5e146d8f4f64aba343309dde00 /src
parenta88ce1882218c83e410d430fab63fbc9331aaba0 (diff)
tweaks to keyword call sites, enable in defclass/type by default
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core_deftype.clj14
-rw-r--r--src/jvm/clojure/lang/Compiler.java41
-rw-r--r--src/jvm/clojure/lang/ILookupThunk.java2
-rw-r--r--src/jvm/clojure/lang/KeywordLookupSite.java19
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);
}
}