diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-01-28 22:24:15 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-01-28 22:24:15 +0000 |
commit | e8a3530e6f07275cb1a176a6bba2eca42d258e40 (patch) | |
tree | 3f79844358261b45612ef20e03e5cd2cce551f37 | |
parent | 3ff5b944cd03878ea0ddfc3a345ea090bda37f1c (diff) |
[lazy] added closed-over local tail clearing, for once-only fns, used in delay
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 0b57c389..50921f7f 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -2817,6 +2817,7 @@ static public class FnExpr implements Expr{ int line; PersistentVector constants; int constantsID; + boolean onceOnly = false; public final IPersistentCollection methods(){ return methods; @@ -2898,6 +2899,7 @@ static public class FnExpr implements Expr{ static Expr parse(C context, ISeq form, String name) throws Exception{ FnExpr fn = new FnExpr(tagOf(form)); FnMethod enclosingMethod = (FnMethod) METHOD.get(); + fn.onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), Keyword.intern(null, "once"))); //fn.thisName = name; String basename = enclosingMethod != null ? (enclosingMethod.fn.name + "$") @@ -3211,6 +3213,21 @@ static public class FnExpr implements Expr{ } } + void emitClearCloses(GeneratorAdapter gen){ + int a = 1; + for(ISeq s = RT.keys(closes); s != null; s = s.rest(), ++a) + { + LocalBinding lb = (LocalBinding) s.first(); + Class primc = lb.getPrimitiveType(); + if(primc == null) + { + gen.loadThis(); + gen.visitInsn(Opcodes.ACONST_NULL); + gen.putField(fntype, lb.name, OBJECT_TYPE); + } + } + } + synchronized Class getCompiledClass(){ if(compiledClass == null) try @@ -3537,6 +3554,10 @@ public static class FnMethod{ } } } + if(fn.onceOnly) + { + fn.emitClearCloses(gen); + } } } |