diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-08-01 17:43:24 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-08-01 17:43:24 -0400 |
commit | cff83ebc8e8f81f11ec7e76cc055cff693bd1b28 (patch) | |
tree | f9a228b51bb96379e38654e92f7a32d1cfb30fde | |
parent | 0bd86ba81d15584b0e12ce6d783e41bcd916b95f (diff) |
added support for volatiles in new new
(let [a 42 b 21] (new [supers] this {:volatile [a]} (foo [] ... (set! a 13) ...)))
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 6f1e88f4..c39026d9 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -73,6 +73,8 @@ static final Symbol ISEQ = Symbol.create("clojure.lang.ISeq"); static final Keyword inlineKey = Keyword.intern(null, "inline"); static final Keyword inlineAritiesKey = Keyword.intern(null, "inline-arities"); +static final Keyword volatileKey = Keyword.intern(null, "volatile"); + static final Symbol NS = Symbol.create("ns"); static final Symbol IN_NS = Symbol.create("in-ns"); @@ -2707,6 +2709,10 @@ static public class ObjExpr implements Expr{ public final Object tag; //localbinding->itself IPersistentMap closes = PersistentHashMap.EMPTY; + + //symbols + IPersistentSet volatiles = PersistentHashSet.EMPTY; + //Keyword->KeywordExpr IPersistentMap keywords = PersistentHashMap.EMPTY; IPersistentMap vars = PersistentHashMap.EMPTY; @@ -2874,8 +2880,9 @@ static public class ObjExpr implements Expr{ for(ISeq s = RT.keys(closes); s != null; s = s.next()) { LocalBinding lb = (LocalBinding) s.first(); + if(lb.getPrimitiveType() != null) - cv.visitField(ACC_PUBLIC + ACC_FINAL + cv.visitField(ACC_PUBLIC + (isVolatile(lb) ? ACC_VOLATILE : ACC_FINAL) , lb.name, Type.getType(lb.getPrimitiveType()).getDescriptor(), null, null); else @@ -3090,6 +3097,9 @@ static public class ObjExpr implements Expr{ } } + boolean isVolatile(LocalBinding lb){ + return closes.containsKey(lb) && volatiles.contains(lb.sym); + } void emitClearCloses(GeneratorAdapter gen){ int a = 1; @@ -3185,6 +3195,26 @@ static public class ObjExpr implements Expr{ return (tag != null) ? HostExpr.tagToClass(tag) : IFn.class; } + public void emitAssignLocal(GeneratorAdapter gen, LocalBinding lb,Expr val){ + if(!isVolatile(lb)) + throw new IllegalArgumentException("Cannot assign to non-volatile: " + lb.name); + Class primc = lb.getPrimitiveType(); + gen.loadThis(); + if(primc != null) + { + MaybePrimitiveExpr me = (MaybePrimitiveExpr) val; + if(!me.canEmitPrimitive()) + throw new IllegalArgumentException("Must assign primitive to primitive volatile: " + lb.name); + me.emitUnboxed(C.EXPRESSION, this, gen); + gen.putField(objtype, lb.name, Type.getType(primc)); + } + else + { + val.emit(C.EXPRESSION, this, gen); + gen.putField(objtype, lb.name, OBJECT_TYPE); + } + } + private void emitLocal(GeneratorAdapter gen, LocalBinding lb){ if(closes.containsKey(lb)) { @@ -3570,7 +3600,7 @@ public static class LocalBinding{ } } -public static class LocalBindingExpr implements Expr, MaybePrimitiveExpr{ +public static class LocalBindingExpr implements Expr, MaybePrimitiveExpr, AssignableExpr{ public final LocalBinding b; public final Symbol tag; @@ -3598,6 +3628,16 @@ public static class LocalBindingExpr implements Expr, MaybePrimitiveExpr{ objx.emitLocal(gen, b); } + public Object evalAssign(Expr val) throws Exception{ + throw new UnsupportedOperationException("Can't eval locals"); + } + + public void emitAssign(C context, ObjExpr objx, GeneratorAdapter gen, Expr val){ + objx.emitAssignLocal(gen, b,val); + if(context != C.STATEMENT) + objx.emitLocal(gen, b); + } + public boolean hasJavaClass() throws Exception{ return tag != null || b.hasJavaClass(); } @@ -4914,7 +4954,12 @@ static public class NewInstanceExpr extends ObjExpr{ ret.optionsMap = ((IPersistentMap) RT.first(rform)); rform = RT.next(rform); } - + + if(RT.get(ret.optionsMap, volatileKey) != null) + { + ret.volatiles = PersistentHashSet.create(RT.seq(RT.get(ret.optionsMap, volatileKey))); + } + try { Var.pushThreadBindings( @@ -4931,6 +4976,7 @@ static public class NewInstanceExpr extends ObjExpr{ methods = RT.conj(methods, m); } + ret.methods = methods; ret.keywords = (IPersistentMap) KEYWORDS.deref(); ret.vars = (IPersistentMap) VARS.deref(); |