diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-04-05 17:52:55 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-04-05 17:52:55 -0400 |
commit | 54ab7bd6b6b2894923cc0a9333a5ea39738ae4f6 (patch) | |
tree | 104648a9f77038a96b4622181e7694e7988aa3ac | |
parent | c733148ba0fb3ff7bbab133f5375422972e62d08 (diff) |
use reify for ILookupThunk impls in deftype
-rw-r--r-- | src/clj/clojure/core_deftype.clj | 16 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 67 |
2 files changed, 9 insertions, 74 deletions
diff --git a/src/clj/clojure/core_deftype.clj b/src/clj/clojure/core_deftype.clj index d8027302..8e13902a 100644 --- a/src/clj/clojure/core_deftype.clj +++ b/src/clj/clojure/core_deftype.clj @@ -149,13 +149,15 @@ (get ~'__extmap k# else#))) `(getLookupThunk [~'this 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)))] + ~@(let [gtarget (gensym) + hinted-target (with-meta gtarget {:tag tagname})] + (mapcat + (fn [fld] + [(keyword fld) + `(reify clojure.lang.ILookupThunk + (get [_ ~gtarget] (. ~hinted-target ~fld)))]) + base-fields)) + nil)))] [i m])) (idynamictype [[i m]] [(conj i 'clojure.lang.IDynamicType) diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 080fc060..f4091281 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -6049,8 +6049,6 @@ static public class NewInstanceExpr extends ObjExpr{ fmap = fmap.assoc(sym, lb); closesvec[i*2] = lb; closesvec[i*2 + 1] = lb; - if(!sym.name.startsWith("__")) - compileLookupThunk(ret, sym); } //todo - inject __meta et al into closes - when? @@ -6208,71 +6206,6 @@ static public class NewInstanceExpr extends ObjExpr{ return loader.defineClass(COMPILE_STUB_PREFIX + "." + ret.name, bytecode); } - static Class compileLookupThunk(NewInstanceExpr ret, Symbol fld) throws Exception{ - //String superName, NewInstanceExpr ret, String[] interfaceNames){ - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - ClassVisitor cv = cw; - String iname = ret.internalName + "$__lookup__" + fld.name; - String cname = ret.name + "$__lookup__" + fld.name; - Class fclass = tagClass(tagOf(fld)); - - //workaround until full support for type-hinted non-primitive fields - if(!fclass.isPrimitive()) - fclass = Object.class; - - Type ftype = Type.getType(fclass); - cv.visit(V1_5, ACC_PUBLIC + ACC_SUPER + ACC_FINAL, iname, - null,"java/lang/Object",new String[]{"clojure/lang/ILookupThunk"}); - - GeneratorAdapter ctorgen = new GeneratorAdapter(ACC_PUBLIC, - voidctor, - null, - null, - cv); - ctorgen.visitCode(); - ctorgen.loadThis(); - ctorgen.invokeConstructor(OBJECT_TYPE, voidctor); - ctorgen.returnValue(); - ctorgen.endMethod(); - - Method meth = Method.getMethod("Object get(Object)"); - - GeneratorAdapter gen = new GeneratorAdapter(ACC_PUBLIC, - meth, - null, - null, - cv); - gen.visitCode(); - Label faultLabel = gen.newLabel(); - Label endLabel = gen.newLabel(); - - gen.loadArg(0); - gen.dup(); - gen.instanceOf(ret.objtype); - gen.ifZCmp(GeneratorAdapter.EQ, faultLabel); - gen.checkCast(ret.objtype); - gen.getField(ret.objtype, munge(fld.name), ftype); - HostExpr.emitBoxReturn(ret,gen,fclass); - gen.goTo(endLabel); - - gen.mark(faultLabel); - gen.pop(); - gen.loadThis(); - - gen.mark(endLabel); - gen.returnValue(); - gen.endMethod(); - - //end of class - cv.visitEnd(); - - byte[] bytecode = cw.toByteArray(); - if(RT.booleanCast(COMPILE_FILES.deref())) - writeClassFile(iname, bytecode); - DynamicClassLoader loader = (DynamicClassLoader) LOADER.deref(); - return loader.defineClass(cname, bytecode); - } - static String[] interfaceNames(IPersistentVector interfaces){ int icnt = interfaces.count(); String[] inames = icnt > 0 ? new String[icnt] : null; |