From f514ad60efe36befa659f19ea5f3bf17b247aaed Mon Sep 17 00:00:00 2001 From: Rich Hickey Date: Wed, 26 Mar 2008 18:10:53 +0000 Subject: re-enabled clearing locals on tail calls, but track locals used in catch/finally clauses and avoid clearing them --- src/jvm/clojure/lang/Compiler.java | 50 ++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index b6adac6b..39263396 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -163,6 +163,9 @@ static public Var VARS = Var.create(); //FnFrame static public Var METHOD = Var.create(null); +//null or not +static public Var IN_CATCH_FINALLY = Var.create(null); + //String static public Var SOURCE = Var.create("NO_SOURCE_FILE"); @@ -1554,7 +1557,8 @@ static class TryExpr implements Expr{ throw new Exception("Can't bind qualified name"); IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.get(), - NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.get()); + NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.get(), + IN_CATCH_FINALLY, RT.T); try { Var.pushThreadBindings(dynamicBindings); @@ -1572,7 +1576,15 @@ static class TryExpr implements Expr{ { if(fs.rest() != null) throw new Exception("finally clause must be last in try expression"); - finallyExpr = (new BodyExpr.Parser()).parse(C.STATEMENT, RT.rest(f)); + try + { + Var.pushThreadBindings(RT.map(IN_CATCH_FINALLY, RT.T)); + finallyExpr = (new BodyExpr.Parser()).parse(C.STATEMENT, RT.rest(f)); + } + finally + { + Var.popThreadBindings(); + } } } } @@ -2793,6 +2805,7 @@ static class FnMethod{ PersistentVector argLocals; int maxLocal = 0; int line; + PersistentHashSet localsUsedInCatchFinally = PersistentHashSet.EMPTY; public FnMethod(FnExpr fn, FnMethod parent){ this.parent = parent; @@ -2911,16 +2924,22 @@ static class FnMethod{ } void emitClearLocals(GeneratorAdapter gen){ -// for(int i = 0; i < numParams(); i++) -// { -// gen.visitInsn(Opcodes.ACONST_NULL); -// gen.storeArg(i); -// } -// for(int i=numParams()+1;i