Skip to content

Commit

Permalink
added support for volatiles in new new
Browse files Browse the repository at this point in the history
(let [a 42 b 21] (new [supers] this {:volatile [a]} (foo [] ... (set! a 13) ...)))
  • Loading branch information
richhickey committed Aug 1, 2009
1 parent 0bd86ba commit cff83eb
Showing 1 changed file with 49 additions and 3 deletions.
52 changes: 49 additions & 3 deletions src/jvm/clojure/lang/Compiler.java
Expand Up @@ -73,6 +73,8 @@ public class Compiler implements Opcodes{
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");

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2874,8 +2880,9 @@ void compile(String superName, String[] interfaceNames, boolean oneTimeUse) thro
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
Expand Down Expand Up @@ -3090,6 +3097,9 @@ void emitConstants(GeneratorAdapter clinitgen){
}
}

boolean isVolatile(LocalBinding lb){
return closes.containsKey(lb) && volatiles.contains(lb.sym);
}

void emitClearCloses(GeneratorAdapter gen){
int a = 1;
Expand Down Expand Up @@ -3185,6 +3195,26 @@ public Class getJavaClass() throws Exception{
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))
{
Expand Down Expand Up @@ -3570,7 +3600,7 @@ public Class getPrimitiveType(){
}
}

public static class LocalBindingExpr implements Expr, MaybePrimitiveExpr{
public static class LocalBindingExpr implements Expr, MaybePrimitiveExpr, AssignableExpr{
public final LocalBinding b;
public final Symbol tag;

Expand Down Expand Up @@ -3598,6 +3628,16 @@ public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
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();
}
Expand Down Expand Up @@ -4914,7 +4954,12 @@ static Expr parse(C context, ISeq form) throws Exception{
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(
Expand All @@ -4931,6 +4976,7 @@ static Expr parse(C context, ISeq form) throws Exception{
methods = RT.conj(methods, m);
}


ret.methods = methods;
ret.keywords = (IPersistentMap) KEYWORDS.deref();
ret.vars = (IPersistentMap) VARS.deref();
Expand Down

0 comments on commit cff83eb

Please sign in to comment.