diff options
-rw-r--r-- | src/clj/clojure/core.clj | 98 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ARef.java | 52 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Agent.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Atom.java | 10 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compile.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 146 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Delay.java | 6 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IDeref.java | 17 | ||||
-rw-r--r-- | src/jvm/clojure/lang/IRef.java | 6 | ||||
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 17 | ||||
-rw-r--r-- | src/jvm/clojure/lang/MultiFn.java | 6 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Numbers.java | 22 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 22 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Ref.java | 7 | ||||
-rw-r--r-- | src/jvm/clojure/lang/TransactionalHashMap.java | 16 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Var.java | 8 |
16 files changed, 232 insertions, 207 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 04b11d25..37a063aa 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -1214,11 +1214,13 @@ ([x & options] (setup-reference (ref x) options))) (defn deref - "Also reader macro: @ref/@agent/@var/@atom Within a transaction, + "Also reader macro: @ref/@agent/@var/@atom/@delay/@future. Within a transaction, returns the in-transaction-value of ref, else returns the most-recently-committed value of ref. When applied to a var, agent - or atom, returns its current state." - [#^clojure.lang.IRef ref] (. ref (get))) + or atom, returns its current state. When applied to a delay, forces + it if not already forced. When applied to a future, will block if + computation not complete" + [#^clojure.lang.IDeref ref] (.deref ref)) (defn atom "Creates and returns an Atom with an initial value of x and zero or @@ -3704,43 +3706,6 @@ "Returns true if coll implements Reversible" [coll] (instance? clojure.lang.Reversible coll)) -(defn pcalls - "Executes the no-arg fns in parallel, returning a lazy sequence of - their values" - [& fns] - (let [futs (.invokeAll clojure.lang.Agent/pooledExecutor fns)] - (map #(.get %) futs))) - -(defmacro pvalues - "Returns a lazy sequence of the values of the exprs, which are - evaluated in parallel" - [& exprs] - `(pcalls ~@(map #(list `fn [] %) exprs))) - -(defn pmap - "Like map, except f is applied in parallel. Semi-lazy in that the - parallel computation stays ahead of the consumption, but doesn't - realize the entire result unless required. Only useful for - computationally intensive functions where the time of f dominates - the coordination overhead." - ([f coll] - (let [n (inc (.. Runtime getRuntime availableProcessors)) - agents (doall (map #(send (agent %) f) (take n coll))) - wget (fn [a] (await1 a) @a) - step (fn step [[x & xs :as s] - [a & as :as acycle]] - (if s - (let [v (wget a)] - (send a (fn [_] (f x))) - (lazy-cons v (step xs as))) - (map wget (take (count agents) acycle))))] - (step (drop n coll) (cycle agents)))) - ([f coll & colls] - (let [step (fn step [cs] - (when (every? seq cs) - (lazy-cons (map first cs) (step (map rest cs)))))] - (pmap #(apply f %) (step (cons coll colls)))))) - (def #^{:doc "bound in a repl thread to the most recent value printed"} *1) @@ -3933,3 +3898,56 @@ (load "genclass") +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; futures (needs proxy);;;;;;;;;;;;;;;;;; +(defn future-call + "Takes a function of no args and yields a future object that will + invoke the function in another thread, and will cache the result and + return it on all subsequent calls to deref/@. If the computation has + not yet finished, calls to deref/@ will block." + [#^Callable f] + (let [fut (.submit clojure.lang.Agent/pooledExecutor f)] + (proxy [clojure.lang.IDeref java.util.concurrent.Future] [] + (deref [] (.get fut)) + (get [] (.get fut)) + (get [timeout unit] (.get fut timeout unit)) + (isCancelled [] (.isCancelled fut)) + (isDone [] (.isDone fut)) + (cancel [interrupt?] (.cancel fut interrupt?))))) + +(defmacro future + "Takes a body of expressions and yields a future object that will + invoke the body in another thread, and will cache the result and + return it on all subsequent calls to deref/@. If the computation has + not yet finished, calls to deref/@ will block." + [& body] `(future-call (fn [] ~@body))) + +(defn pmap + "Like map, except f is applied in parallel. Semi-lazy in that the + parallel computation stays ahead of the consumption, but doesn't + realize the entire result unless required. Only useful for + computationally intensive functions where the time of f dominates + the coordination overhead." + ([f coll] + (let [n (+ 2 (.. Runtime getRuntime availableProcessors)) + rets (map #(future (f %)) coll) + step (fn step [[x & xs :as vs] fs] + (if fs + (lazy-cons (deref x) (step xs (rest fs))) + (map deref vs)))] + (step rets (drop n rets)))) + ([f coll & colls] + (let [step (fn step [cs] + (when (every? seq cs) + (lazy-cons (map first cs) (step (map rest cs)))))] + (pmap #(apply f %) (step (cons coll colls)))))) + +(defn pcalls + "Executes the no-arg fns in parallel, returning a lazy sequence of + their values" + [& fns] (pmap #(%) fns)) + +(defmacro pvalues + "Returns a lazy sequence of the values of the exprs, which are + evaluated in parallel" + [& exprs] + `(pcalls ~@(map #(list `fn [] %) exprs))) diff --git a/src/jvm/clojure/lang/ARef.java b/src/jvm/clojure/lang/ARef.java index c165db9f..8b88de76 100644 --- a/src/jvm/clojure/lang/ARef.java +++ b/src/jvm/clojure/lang/ARef.java @@ -12,12 +12,11 @@ package clojure.lang; -import java.util.concurrent.atomic.AtomicReference; import java.util.Map; public abstract class ARef extends AReference implements IRef { protected volatile IFn validator = null; - private AtomicReference<IPersistentMap> watchers = new AtomicReference(PersistentHashMap.EMPTY); + private volatile IPersistentMap watchers = PersistentHashMap.EMPTY; public ARef() { super(); @@ -49,7 +48,7 @@ public abstract class ARef extends AReference implements IRef { public void setValidator(IFn vf){ try { - validate(vf,get()); + validate(vf, deref()); } catch (Exception e) { @@ -63,43 +62,30 @@ public abstract class ARef extends AReference implements IRef { } public IPersistentMap getWatches(){ - return watchers.get(); + return watchers; } - public IRef addWatch(Agent watcher, IFn action, boolean sendOff){ - boolean added = false; - IPersistentMap prior = null; - while(!added) - { - prior = watchers.get(); - added = watchers.compareAndSet(prior, prior.assoc(watcher,new Object[]{action,sendOff})); - } - - return this; + synchronized public IRef addWatch(Agent watcher, IFn action, boolean sendOff){ + watchers = watchers.assoc(watcher, new Object[]{action, sendOff}); + return this; } - public IRef removeWatch(Agent watcher){ - boolean removed = false; - IPersistentMap prior = null; - while(!removed) - { - prior = watchers.get(); - try - { - removed = watchers.compareAndSet(prior, prior.without(watcher)); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } + synchronized public IRef removeWatch(Agent watcher){ + try + { + watchers = watchers.without(watcher); + } + catch(Exception e) + { + throw new RuntimeException(e); + } - return this; - } + return this; + } public void notifyWatches() { - IPersistentMap ws = watchers.get(); - if (ws != null) + IPersistentMap ws = watchers; + if (ws.count() > 0) { ISeq args = new Cons(this, null); for (ISeq s = RT.seq(ws); s != null; s = s.rest()) diff --git a/src/jvm/clojure/lang/Agent.java b/src/jvm/clojure/lang/Agent.java index 95c10216..277307e7 100644 --- a/src/jvm/clojure/lang/Agent.java +++ b/src/jvm/clojure/lang/Agent.java @@ -123,7 +123,7 @@ boolean setState(Object newState) throws Exception{ return ret; } -public Object get() throws Exception{ +public Object deref() throws Exception{ if(errors != null) { throw new Exception("Agent has errors", (Exception) RT.first(errors)); diff --git a/src/jvm/clojure/lang/Atom.java b/src/jvm/clojure/lang/Atom.java index 3d02f6e4..050b5ffb 100644 --- a/src/jvm/clojure/lang/Atom.java +++ b/src/jvm/clojure/lang/Atom.java @@ -26,14 +26,14 @@ public class Atom extends ARef{ this.state = new AtomicReference(state); } - public Object get() { + public Object deref() { return state.get(); } public Object swap(IFn f) throws Exception { for(;;) { - Object v = get(); + Object v = deref(); Object newv = f.invoke(v); validate(newv); if(state.compareAndSet(v,newv)) @@ -48,7 +48,7 @@ public class Atom extends ARef{ public Object swap(IFn f, Object arg) throws Exception { for(;;) { - Object v = get(); + Object v = deref(); Object newv = f.invoke(v,arg); validate(newv); if(state.compareAndSet(v,newv)) @@ -63,7 +63,7 @@ public class Atom extends ARef{ public Object swap(IFn f, Object arg1, Object arg2) throws Exception { for(;;) { - Object v = get(); + Object v = deref(); Object newv = f.invoke(v, arg1, arg2); validate(newv); if(state.compareAndSet(v,newv)) @@ -78,7 +78,7 @@ public class Atom extends ARef{ public Object swap(IFn f, Object x, Object y, ISeq args) throws Exception { for(;;) { - Object v = get(); + Object v = deref(); Object newv = f.applyTo(RT.listStar(v, x, y, args)); validate(newv); if(state.compareAndSet(v,newv)) diff --git a/src/jvm/clojure/lang/Compile.java b/src/jvm/clojure/lang/Compile.java index 0f3948b1..86120deb 100644 --- a/src/jvm/clojure/lang/Compile.java +++ b/src/jvm/clojure/lang/Compile.java @@ -28,8 +28,8 @@ private static final Var compile = RT.var("clojure.core", "compile"); public static void main(String[] args) throws Exception{ - OutputStreamWriter out = (OutputStreamWriter) RT.OUT.get(); - PrintWriter err = (PrintWriter) RT.ERR.get(); + OutputStreamWriter out = (OutputStreamWriter) RT.OUT.deref(); + PrintWriter err = (PrintWriter) RT.ERR.deref(); String path = System.getProperty(PATH_PROP); int count = args.length; diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 4c707f64..4ba30b5e 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -361,9 +361,9 @@ static class DefExpr implements Expr{ throw new Exception("Can't create defs outside of current ns"); } IPersistentMap mm = sym.meta(); - mm = (IPersistentMap) RT.assoc(mm, RT.LINE_KEY, LINE.get()).assoc(RT.FILE_KEY, SOURCE.get()); + mm = (IPersistentMap) RT.assoc(mm, RT.LINE_KEY, LINE.deref()).assoc(RT.FILE_KEY, SOURCE.deref()); Expr meta = analyze(context == C.EVAL ? context : C.EXPRESSION, mm); - return new DefExpr((String) SOURCE.get(), (Integer) LINE.get(), + return new DefExpr((String) SOURCE.deref(), (Integer) LINE.deref(), v, analyze(context == C.EVAL ? context : C.EXPRESSION, RT.third(form), v.sym.name), meta, RT.count(form) == 3); } @@ -420,7 +420,7 @@ public static class VarExpr implements Expr, AssignableExpr{ } public Object eval() throws Exception{ - return var.get(); + return var.deref(); } public void emit(C context, FnExpr fn, GeneratorAdapter gen){ @@ -723,8 +723,8 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ throw new IllegalArgumentException("Malformed member expression, expecting (. target member ...)"); //determine static or instance //static target must be symbol, either fully.qualified.Classname or Classname that has been imported - int line = (Integer) LINE.get(); - String source = (String) SOURCE.get(); + int line = (Integer) LINE.deref(); + String source = (String) SOURCE.deref(); Class c = maybeClass(RT.second(form), false); //at this point c will be non-null if static Expr instance = null; @@ -860,9 +860,9 @@ static class InstanceFieldExpr extends FieldExpr implements AssignableExpr{ this.field = targetClass != null ? Reflector.getField(targetClass, fieldName, false) : null; this.fieldName = fieldName; this.line = line; - if(field == null && RT.booleanCast(RT.WARN_ON_REFLECTION.get())) + if(field == null && RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) { - ((PrintWriter) RT.ERR.get()) + ((PrintWriter) RT.ERR.deref()) .format("Reflection warning, line: %d - reference to field %s can't be resolved.\n", line, fieldName); } @@ -1063,7 +1063,7 @@ static abstract class MethodExpr extends HostExpr{ catch(Exception e1) { e1.printStackTrace((PrintWriter) RT.ERR - .get()); //To change body of catch statement use File | Settings | File Templates. + .deref()); //To change body of catch statement use File | Settings | File Templates. } } @@ -1123,9 +1123,9 @@ static class InstanceMethodExpr extends MethodExpr{ else method = null; - if(method == null && RT.booleanCast(RT.WARN_ON_REFLECTION.get())) + if(method == null && RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) { - ((PrintWriter) RT.ERR.get()) + ((PrintWriter) RT.ERR.deref()) .format("Reflection warning, line: %d - call to %s can't be resolved.\n", line, methodName); } } @@ -1165,7 +1165,7 @@ static class InstanceMethodExpr extends MethodExpr{ MethodExpr.emitTypedArgs(fn, gen, method.getParameterTypes(), args); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } Method m = new Method(methodName, Type.getReturnType(method), Type.getArgumentTypes(method)); @@ -1189,7 +1189,7 @@ static class InstanceMethodExpr extends MethodExpr{ MethodExpr.emitTypedArgs(fn, gen, method.getParameterTypes(), args); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } Method m = new Method(methodName, Type.getReturnType(method), Type.getArgumentTypes(method)); @@ -1207,7 +1207,7 @@ static class InstanceMethodExpr extends MethodExpr{ emitArgsAsArray(args, fn, gen); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } gen.invokeStatic(REFLECTOR_TYPE, invokeInstanceMethodMethod); @@ -1264,9 +1264,9 @@ static class StaticMethodExpr extends MethodExpr{ methodidx = getMatchingParams(methodName, params, args,rets); } method = (java.lang.reflect.Method) (methodidx >= 0 ? methods.get(methodidx) : null); - if(method == null && RT.booleanCast(RT.WARN_ON_REFLECTION.get())) + if(method == null && RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) { - ((PrintWriter) RT.ERR.get()) + ((PrintWriter) RT.ERR.deref()) .format("Reflection warning, line: %d - call to %s can't be resolved.\n", line, methodName); } } @@ -1302,7 +1302,7 @@ static class StaticMethodExpr extends MethodExpr{ //Type type = Type.getObjectType(className.replace('.', '/')); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } Type type = Type.getType(c); @@ -1321,7 +1321,7 @@ static class StaticMethodExpr extends MethodExpr{ //Type type = Type.getObjectType(className.replace('.', '/')); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } Type type = Type.getType(c); @@ -1337,7 +1337,7 @@ static class StaticMethodExpr extends MethodExpr{ emitArgsAsArray(args, fn, gen); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } gen.invokeStatic(REFLECTOR_TYPE, invokeStaticMethodMethod); @@ -1828,8 +1828,8 @@ public static class TryExpr implements Expr{ if(sym.getNamespace() != null) throw new Exception("Can't bind qualified name:" + sym); - IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.get(), - NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.get(), + IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.deref(), + NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.deref(), IN_CATCH_FINALLY, RT.T); try { @@ -2095,9 +2095,9 @@ public static class NewExpr implements Expr{ } this.ctor = ctoridx >= 0 ? (Constructor) ctors.get(ctoridx) : null; - if(ctor == null && RT.booleanCast(RT.WARN_ON_REFLECTION.get())) + if(ctor == null && RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) { - ((PrintWriter) RT.ERR.get()) + ((PrintWriter) RT.ERR.deref()) .format("Reflection warning, line: %d - call to %s ctor can't be resolved.\n", line, c.getName()); } } @@ -2122,7 +2122,7 @@ public static class NewExpr implements Expr{ MethodExpr.emitTypedArgs(fn, gen, ctor.getParameterTypes(), args); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } gen.invokeConstructor(type, new Method("<init>", Type.getConstructorDescriptor(ctor))); @@ -2134,7 +2134,7 @@ public static class NewExpr implements Expr{ MethodExpr.emitArgsAsArray(args, fn, gen); if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } gen.invokeStatic(REFLECTOR_TYPE, invokeConstructorMethod); @@ -2153,7 +2153,7 @@ public static class NewExpr implements Expr{ static class Parser implements IParser{ public Expr parse(C context, Object frm) throws Exception{ - int line = (Integer) LINE.get(); + int line = (Integer) LINE.deref(); ISeq form = (ISeq) frm; //(new Classname args...) if(form.count() < 2) @@ -2396,7 +2396,7 @@ public static class IfExpr implements Expr{ throw new Exception("Too many arguments to if"); else if(form.count() < 3) throw new Exception("Too few arguments to if"); - return new IfExpr((Integer) LINE.get(), + return new IfExpr((Integer) LINE.deref(), analyze(context == C.EVAL ? context : C.EXPRESSION, RT.second(form)), analyze(context, RT.third(form)), analyze(context, RT.fourth(form))); @@ -2724,7 +2724,7 @@ static class InvokeExpr implements Expr{ if(context == C.RETURN) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.emitClearLocals(gen); } @@ -2755,7 +2755,7 @@ static class InvokeExpr implements Expr{ // throw new IllegalArgumentException( // String.format("No more than %d args supported", MAX_POSITIONAL_ARITY)); - return new InvokeExpr((String) SOURCE.get(), (Integer) LINE.get(), tagOf(form), fexpr, args); + return new InvokeExpr((String) SOURCE.deref(), (Integer) LINE.deref(), tagOf(form), fexpr, args); } } @@ -2897,7 +2897,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(); + FnMethod enclosingMethod = (FnMethod) METHOD.deref(); //fn.thisName = name; String basename = enclosingMethod != null ? (enclosingMethod.fn.name + "$") @@ -2929,7 +2929,7 @@ static public class FnExpr implements Expr{ //turn former into latter if(RT.second(form) instanceof IPersistentVector) form = RT.list(FN, RT.rest(form)); - fn.line = (Integer) LINE.get(); + fn.line = (Integer) LINE.deref(); FnMethod[] methodArray = new FnMethod[MAX_POSITIONAL_ARITY + 1]; FnMethod variadicMethod = null; for(ISeq s = RT.rest(form); s != null; s = RT.rest(s)) @@ -2964,9 +2964,9 @@ static public class FnExpr implements Expr{ fn.methods = methods; fn.variadicMethod = variadicMethod; - fn.keywords = (IPersistentMap) KEYWORDS.get(); - fn.vars = (IPersistentMap) VARS.get(); - fn.constants = (PersistentVector) CONSTANTS.get(); + fn.keywords = (IPersistentMap) KEYWORDS.deref(); + fn.vars = (IPersistentMap) VARS.deref(); + fn.constants = (PersistentVector) CONSTANTS.deref(); fn.constantsID = RT.nextID(); // DynamicClassLoader loader = (DynamicClassLoader) LOADER.get(); // loader.registerConstants(fn.constantsID, fn.constants.toArray()); @@ -3013,11 +3013,11 @@ static public class FnExpr implements Expr{ //ClassVisitor cv = new TraceClassVisitor(cw, new PrintWriter(System.out)); cv.visit(V1_5, ACC_PUBLIC + ACC_SUPER, internalName, null, isVariadic() ? "clojure/lang/RestFn" : "clojure/lang/AFunction", null); - String source = (String) SOURCE.get(); - int lineBefore = (Integer) LINE_BEFORE.get(); - int lineAfter = (Integer) LINE_AFTER.get() + 1; + String source = (String) SOURCE.deref(); + int lineBefore = (Integer) LINE_BEFORE.deref(); + int lineAfter = (Integer) LINE_AFTER.deref() + 1; - if(source != null && SOURCE_PATH.get() != null) + if(source != null && SOURCE_PATH.deref() != null) { //cv.visitSource(source, null); String smap = "SMAP\n" + @@ -3029,7 +3029,7 @@ static public class FnExpr implements Expr{ "*S Clojure\n" + "*F\n" + "+ 1 " + source + "\n" + - (String) SOURCE_PATH.get() + "\n" + + (String) SOURCE_PATH.deref() + "\n" + "*L\n" + String.format("%d#1,%d:%d\n", lineBefore, lineAfter - lineBefore, lineBefore) + "*E"; @@ -3160,7 +3160,7 @@ static public class FnExpr implements Expr{ cv.visitEnd(); bytecode = cw.toByteArray(); - if(RT.booleanCast(COMPILE_FILES.get())) + if(RT.booleanCast(COMPILE_FILES.deref())) writeClassFile(internalName,bytecode); // else // getCompiledClass(); @@ -3215,11 +3215,11 @@ static public class FnExpr implements Expr{ if(compiledClass == null) try { - if(RT.booleanCast(COMPILE_FILES.get())) + if(RT.booleanCast(COMPILE_FILES.deref())) compiledClass = RT.classForName(name);//loader.defineClass(name, bytecode); else { - loader = (DynamicClassLoader) LOADER.get(); + loader = (DynamicClassLoader) LOADER.deref(); compiledClass = loader.defineClass(name, bytecode); } } @@ -3417,13 +3417,13 @@ public static class FnMethod{ ISeq body = RT.rest(form); try { - FnMethod method = new FnMethod(fn, (FnMethod) METHOD.get()); - method.line = (Integer) LINE.get(); + FnMethod method = new FnMethod(fn, (FnMethod) METHOD.deref()); + method.line = (Integer) LINE.deref(); //register as the current method and set up a new env frame Var.pushThreadBindings( RT.map( METHOD, method, - LOCAL_ENV, LOCAL_ENV.get(), + LOCAL_ENV, LOCAL_ENV.deref(), LOOP_LOCALS, null, NEXT_LOCAL_NUM, 0)); @@ -3725,8 +3725,8 @@ public static class LetExpr implements Expr{ || (context == C.EXPRESSION && isLoop)) return analyze(context, RT.list(RT.list(FN, PersistentVector.EMPTY, form))); - IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.get(), - NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.get()); + IPersistentMap dynamicBindings = RT.map(LOCAL_ENV, LOCAL_ENV.deref(), + NEXT_LOCAL_NUM, NEXT_LOCAL_NUM.deref()); if(isLoop) dynamicBindings = dynamicBindings.assoc(LOOP_LOCALS, null); @@ -3840,7 +3840,7 @@ public static class RecurExpr implements Expr{ } public void emit(C context, FnExpr fn, GeneratorAdapter gen){ - Label loopLabel = (Label) LOOP_LABEL.get(); + Label loopLabel = (Label) LOOP_LABEL.deref(); if(loopLabel == null) throw new IllegalStateException(); for(int i = 0; i < loopLocals.count(); i++) @@ -3892,10 +3892,10 @@ public static class RecurExpr implements Expr{ static class Parser implements IParser{ public Expr parse(C context, Object frm) throws Exception{ ISeq form = (ISeq) frm; - IPersistentVector loopLocals = (IPersistentVector) LOOP_LOCALS.get(); + IPersistentVector loopLocals = (IPersistentVector) LOOP_LOCALS.deref(); if(context != C.RETURN || loopLocals == null) throw new UnsupportedOperationException("Can only recur from tail position"); - if(IN_CATCH_FINALLY.get() != null) + if(IN_CATCH_FINALLY.deref() != null) throw new UnsupportedOperationException("Cannot recur from catch/finally"); PersistentVector args = PersistentVector.EMPTY; for(ISeq s = RT.seq(form.rest()); s != null; s = s.rest()) @@ -3914,17 +3914,17 @@ public static class RecurExpr implements Expr{ private static LocalBinding registerLocal(Symbol sym, Symbol tag, Expr init) throws Exception{ int num = getAndIncLocalNum(); LocalBinding b = new LocalBinding(num, sym, tag, init); - IPersistentMap localsMap = (IPersistentMap) LOCAL_ENV.get(); + IPersistentMap localsMap = (IPersistentMap) LOCAL_ENV.deref(); LOCAL_ENV.set(RT.assoc(localsMap, b.sym, b)); - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); method.locals = (IPersistentMap) RT.assoc(method.locals, b, b); method.indexlocals = (IPersistentMap) RT.assoc(method.indexlocals, num, b); return b; } private static int getAndIncLocalNum(){ - int num = ((Number) NEXT_LOCAL_NUM.get()).intValue(); - FnMethod m = (FnMethod) METHOD.get(); + int num = ((Number) NEXT_LOCAL_NUM.deref()).intValue(); + FnMethod m = (FnMethod) METHOD.deref(); if(num > m.maxLocal) m.maxLocal = num; NEXT_LOCAL_NUM.set(num + 1); @@ -3980,7 +3980,7 @@ private static Expr analyze(C context, Object form, String name) throws Exceptio catch(Throwable e) { if(!(e instanceof CompilerException)) - throw new CompilerException((String) SOURCE.get(), (Integer) LINE.get(), e); + throw new CompilerException((String) SOURCE.deref(), (Integer) LINE.deref(), e); else throw (CompilerException) e; } @@ -4115,7 +4115,7 @@ public static Object macroexpand1(Object x) throws Exception{ } private static Expr analyzeSeq(C context, ISeq form, String name) throws Exception{ - Integer line = (Integer) LINE.get(); + Integer line = (Integer) LINE.deref(); if(RT.meta(form) != null && RT.meta(form).containsKey(RT.LINE_KEY)) line = (Integer) RT.meta(form).valAt(RT.LINE_KEY); Var.pushThreadBindings( @@ -4143,7 +4143,7 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti catch(Throwable e) { if(!(e instanceof CompilerException)) - throw new CompilerException((String) SOURCE.get(), (Integer) LINE.get(), e); + throw new CompilerException((String) SOURCE.deref(), (Integer) LINE.deref(), e); else throw (CompilerException) e; } @@ -4183,7 +4183,7 @@ public static Object eval(Object form) throws Exception{ catch(Throwable e) { if(!(e instanceof CompilerException)) - throw new CompilerException((String) SOURCE.get(), (Integer) LINE.get(), e); + throw new CompilerException((String) SOURCE.deref(), (Integer) LINE.deref(), e); else throw (CompilerException) e; } @@ -4197,7 +4197,7 @@ public static Object eval(Object form) throws Exception{ private static int registerConstant(Object o){ if(!CONSTANTS.isBound()) return -1; - PersistentVector v = (PersistentVector) CONSTANTS.get(); + PersistentVector v = (PersistentVector) CONSTANTS.deref(); CONSTANTS.set(RT.conj(v, o)); return v.count(); } @@ -4206,7 +4206,7 @@ private static KeywordExpr registerKeyword(Keyword keyword){ if(!KEYWORDS.isBound()) return new KeywordExpr(keyword); - IPersistentMap keywordsMap = (IPersistentMap) KEYWORDS.get(); + IPersistentMap keywordsMap = (IPersistentMap) KEYWORDS.deref(); Object id = RT.get(keywordsMap, keyword); if(id == null) { @@ -4236,7 +4236,7 @@ private static Expr analyzeSymbol(Symbol sym) throws Exception{ if(c != null) { if(Reflector.getField(c,sym.name,true)!= null) - return new StaticFieldExpr((Integer) LINE.get(), c, sym.name); + return new StaticFieldExpr((Integer) LINE.deref(), c, sym.name); } } } @@ -4315,7 +4315,7 @@ static public Object resolveIn(Namespace n, Symbol sym, boolean allowPrivate) th Object o = n.getMapping(sym); if(o == null) { - if(RT.booleanCast(RT.ALLOW_UNRESOLVED_VARS.get())) + if(RT.booleanCast(RT.ALLOW_UNRESOLVED_VARS.deref())) { return sym; } @@ -4404,7 +4404,7 @@ static Var lookupVar(Symbol sym, boolean internNew) throws Exception{ private static void registerVar(Var var) throws Exception{ if(!VARS.isBound()) return; - IPersistentMap varsMap = (IPersistentMap) VARS.get(); + IPersistentMap varsMap = (IPersistentMap) VARS.deref(); Object id = RT.get(varsMap, var); if(id == null) { @@ -4415,7 +4415,7 @@ private static void registerVar(Var var) throws Exception{ } static Namespace currentNS(){ - return (Namespace) RT.CURRENT_NS.get(); + return (Namespace) RT.CURRENT_NS.deref(); } static void closeOver(LocalBinding b, FnMethod method){ @@ -4426,7 +4426,7 @@ static void closeOver(LocalBinding b, FnMethod method){ method.fn.closes = (IPersistentMap) RT.assoc(method.fn.closes, b, b); closeOver(b, method.parent); } - else if(IN_CATCH_FINALLY.get() != null) + else if(IN_CATCH_FINALLY.deref() != null) { method.localsUsedInCatchFinally = (PersistentHashSet) method.localsUsedInCatchFinally.cons(b.idx); } @@ -4437,10 +4437,10 @@ static void closeOver(LocalBinding b, FnMethod method){ static LocalBinding referenceLocal(Symbol sym) throws Exception{ if(!LOCAL_ENV.isBound()) return null; - LocalBinding b = (LocalBinding) RT.get(LOCAL_ENV.get(), sym); + LocalBinding b = (LocalBinding) RT.get(LOCAL_ENV.deref(), sym); if(b != null) { - FnMethod method = (FnMethod) METHOD.get(); + FnMethod method = (FnMethod) METHOD.deref(); closeOver(b, method); } return b; @@ -4485,7 +4485,7 @@ public static Object load(Reader rdr, String sourcePath, String sourceName) thro RT.map(LOADER, RT.makeClassLoader(), SOURCE_PATH, sourcePath, SOURCE, sourceName, - RT.CURRENT_NS, RT.CURRENT_NS.get(), + RT.CURRENT_NS, RT.CURRENT_NS.deref(), LINE_BEFORE, pushbackReader.getLineNumber(), LINE_AFTER, pushbackReader.getLineNumber() )); @@ -4512,7 +4512,7 @@ public static Object load(Reader rdr, String sourcePath, String sourceName) thro } static public void writeClassFile(String internalName, byte[] bytecode) throws Exception{ - String genPath = (String) COMPILE_PATH.get(); + String genPath = (String) COMPILE_PATH.deref(); if(genPath == null) throw new Exception("*compile-path* not set"); String[] dirs = internalName.split("/"); @@ -4544,7 +4544,7 @@ public static void pushNS(){ } public static Object compile(Reader rdr, String sourcePath, String sourceName) throws Exception{ - if(COMPILE_PATH.get() == null) + if(COMPILE_PATH.deref() == null) throw new Exception("*compile-path* not set"); Object EOF = new Object(); @@ -4555,7 +4555,7 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t Var.pushThreadBindings( RT.map(SOURCE_PATH, sourcePath, SOURCE, sourceName, - RT.CURRENT_NS, RT.CURRENT_NS.get(), + RT.CURRENT_NS, RT.CURRENT_NS.deref(), LINE_BEFORE, pushbackReader.getLineNumber(), LINE_AFTER, pushbackReader.getLineNumber(), CONSTANTS, PersistentVector.EMPTY, @@ -4588,9 +4588,9 @@ public static Object compile(Reader rdr, String sourcePath, String sourceName) t { LINE_AFTER.set(pushbackReader.getLineNumber()); Expr expr = analyze(C.EVAL, r); - fn.keywords = (IPersistentMap) KEYWORDS.get(); - fn.vars = (IPersistentMap) VARS.get(); - fn.constants = (PersistentVector) CONSTANTS.get(); + fn.keywords = (IPersistentMap) KEYWORDS.deref(); + fn.vars = (IPersistentMap) VARS.deref(); + fn.constants = (PersistentVector) CONSTANTS.deref(); expr.emit(C.EXPRESSION, fn, gen); expr.eval(); LINE_BEFORE.set(pushbackReader.getLineNumber()); diff --git a/src/jvm/clojure/lang/Delay.java b/src/jvm/clojure/lang/Delay.java index a0dfd0b6..a5dd713c 100644 --- a/src/jvm/clojure/lang/Delay.java +++ b/src/jvm/clojure/lang/Delay.java @@ -12,7 +12,7 @@ package clojure.lang; -public class Delay{ +public class Delay implements IDeref{ Object val; IFn fn; @@ -23,11 +23,11 @@ public Delay(IFn fn){ static public Object force(Object x) throws Exception{ return (x instanceof Delay) ? - ((Delay) x).get() + ((Delay) x).deref() : x; } -synchronized Object get() throws Exception{ +synchronized public Object deref() throws Exception{ if(fn != null) { val = fn.invoke(); diff --git a/src/jvm/clojure/lang/IDeref.java b/src/jvm/clojure/lang/IDeref.java new file mode 100644 index 00000000..b0865511 --- /dev/null +++ b/src/jvm/clojure/lang/IDeref.java @@ -0,0 +1,17 @@ +/** + * Copyright (c) Rich Hickey. All rights reserved. + * The use and distribution terms for this software are covered by the + * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) + * which can be found in the file epl-v10.html at the root of this distribution. + * By using this software in any fashion, you are agreeing to be bound by + * the terms of this license. + * You must not remove this notice, or any other, from this software. + **/ + +/* rich Feb 9, 2009 */ + +package clojure.lang; + +public interface IDeref{ +Object deref() throws Exception; +} diff --git a/src/jvm/clojure/lang/IRef.java b/src/jvm/clojure/lang/IRef.java index 641edec3..be5687af 100644 --- a/src/jvm/clojure/lang/IRef.java +++ b/src/jvm/clojure/lang/IRef.java @@ -12,11 +12,9 @@ package clojure.lang; -public interface IRef{ +public interface IRef extends IDeref{ - Object get() throws Exception; - - void setValidator(IFn vf); +void setValidator(IFn vf); IFn getValidator(); diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index 922d1cbf..53a7124d 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -90,6 +90,7 @@ static dispatchMacros['='] = new EvalReader();
dispatchMacros['!'] = new CommentReader();
dispatchMacros['<'] = new UnreadableReader();
+ dispatchMacros['_'] = new DiscardReader();
}
static boolean isWhitespace(int ch){
@@ -466,6 +467,14 @@ public static class CommentReader extends AFn{ }
+public static class DiscardReader extends AFn{
+ public Object invoke(Object reader, Object underscore) throws Exception{
+ PushbackReader r = (PushbackReader) reader;
+ read(r, true, null, true);
+ return r;
+ }
+}
+
public static class WrappingReader extends AFn{
final Symbol sym;
@@ -538,7 +547,7 @@ static Symbol garg(int n){ public static class FnReader extends AFn{
public Object invoke(Object reader, Object lparen) throws Exception{
PushbackReader r = (PushbackReader) reader;
- if(ARG_ENV.get() != null)
+ if(ARG_ENV.deref() != null)
throw new IllegalStateException("Nested #()s are not allowed");
try
{
@@ -548,7 +557,7 @@ public static class FnReader extends AFn{ Object form = read(r, true, null, true);
PersistentVector args = PersistentVector.EMPTY;
- PersistentTreeMap argsyms = (PersistentTreeMap) ARG_ENV.get();
+ PersistentTreeMap argsyms = (PersistentTreeMap) ARG_ENV.deref();
ISeq rargs = argsyms.rseq();
if(rargs != null)
{
@@ -580,7 +589,7 @@ public static class FnReader extends AFn{ }
static Symbol registerArg(int n){
- PersistentTreeMap argsyms = (PersistentTreeMap) ARG_ENV.get();
+ PersistentTreeMap argsyms = (PersistentTreeMap) ARG_ENV.deref();
if(argsyms == null)
{
throw new IllegalStateException("arg literal not in #()");
@@ -669,7 +678,7 @@ public static class SyntaxQuoteReader extends AFn{ Symbol sym = (Symbol) form;
if(sym.ns == null && sym.name.endsWith("#"))
{
- IPersistentMap gmap = (IPersistentMap) GENSYM_ENV.get();
+ IPersistentMap gmap = (IPersistentMap) GENSYM_ENV.deref();
if(gmap == null)
throw new IllegalStateException("Gensym literal not in syntax-quote");
Symbol gs = (Symbol) gmap.valAt(sym);
diff --git a/src/jvm/clojure/lang/MultiFn.java b/src/jvm/clojure/lang/MultiFn.java index bb818da4..7fd1ec1f 100644 --- a/src/jvm/clojure/lang/MultiFn.java +++ b/src/jvm/clojure/lang/MultiFn.java @@ -88,12 +88,12 @@ private boolean dominates(Object x, Object y) throws Exception{ private IPersistentMap resetCache(){ methodCache = getMethodTable(); - cachedHierarchy = hierarchy.get(); + cachedHierarchy = hierarchy.deref(); return methodCache; } synchronized private IFn getFn(Object dispatchVal) throws Exception{ - if(cachedHierarchy != hierarchy.get()) + if(cachedHierarchy != hierarchy.deref()) resetCache(); IFn targetFn = (IFn) methodCache.valAt(dispatchVal); if(targetFn != null) @@ -126,7 +126,7 @@ private IFn findAndCacheBestMethod(Object dispatchVal) throws Exception{ if(bestEntry == null) return null; //ensure basis has stayed stable throughout, else redo - if(cachedHierarchy == hierarchy.get()) + if(cachedHierarchy == hierarchy.deref()) { //place in cache methodCache = methodCache.assoc(dispatchVal, bestEntry.getValue()); diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java index 4a49c8cb..ae87c913 100644 --- a/src/jvm/clojure/lang/Numbers.java +++ b/src/jvm/clojure/lang/Numbers.java @@ -15,12 +15,6 @@ package clojure.lang; import java.math.BigInteger; import java.math.BigDecimal; import java.math.MathContext; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.LinkedList; -import java.util.Arrays; public class Numbers{ @@ -1039,35 +1033,35 @@ final static class BigDecimalOps implements Ops{ } final public Number add(Number x, Number y){ - MathContext mc = (MathContext) MATH_CONTEXT.get(); + MathContext mc = (MathContext) MATH_CONTEXT.deref(); return mc == null ? toBigDecimal(x).add(toBigDecimal(y)) : toBigDecimal(x).add(toBigDecimal(y), mc); } final public Number multiply(Number x, Number y){ - MathContext mc = (MathContext) MATH_CONTEXT.get(); + MathContext mc = (MathContext) MATH_CONTEXT.deref(); return mc == null ? toBigDecimal(x).multiply(toBigDecimal(y)) : toBigDecimal(x).multiply(toBigDecimal(y), mc); } public Number divide(Number x, Number y){ - MathContext mc = (MathContext) MATH_CONTEXT.get(); + MathContext mc = (MathContext) MATH_CONTEXT.deref(); return mc == null ? toBigDecimal(x).divide(toBigDecimal(y)) : toBigDecimal(x).divide(toBigDecimal(y), mc); } public Number quotient(Number x, Number y){ - MathContext mc = (MathContext) MATH_CONTEXT.get(); + MathContext mc = (MathContext) MATH_CONTEXT.deref(); return mc == null ? toBigDecimal(x).divideToIntegralValue(toBigDecimal(y)) : toBigDecimal(x).divideToIntegralValue(toBigDecimal(y), mc); } public Number remainder(Number x, Number y){ - MathContext mc = (MathContext) MATH_CONTEXT.get(); + MathContext mc = (MathContext) MATH_CONTEXT.deref(); return mc == null ? toBigDecimal(x).remainder(toBigDecimal(y)) : toBigDecimal(x).remainder(toBigDecimal(y), mc); @@ -1083,14 +1077,14 @@ final static class BigDecimalOps implements Ops{ //public Number subtract(Number x, Number y); final public Number negate(Number x){ - MathContext mc = (MathContext) MATH_CONTEXT.get(); + MathContext mc = (MathContext) MATH_CONTEXT.deref(); return mc == null ? ((BigDecimal) x).negate() : ((BigDecimal) x).negate(mc); } public Number inc(Number x){ - MathContext mc = (MathContext) MATH_CONTEXT.get(); + MathContext mc = (MathContext) MATH_CONTEXT.deref(); BigDecimal bx = (BigDecimal) x; return mc == null ? bx.add(BigDecimal.ONE) @@ -1098,7 +1092,7 @@ final static class BigDecimalOps implements Ops{ } public Number dec(Number x){ - MathContext mc = (MathContext) MATH_CONTEXT.get(); + MathContext mc = (MathContext) MATH_CONTEXT.deref(); BigDecimal bx = (BigDecimal) x; return mc == null ? bx.subtract(BigDecimal.ONE) diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index a277f89e..a3383cfe 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -334,7 +334,7 @@ public static void loadResourceScript(Class c, String name, boolean failIfNotFou } static public void init() throws Exception{ - ((PrintWriter)RT.ERR.get()).println("No need to call RT.init() anymore"); + ((PrintWriter)RT.ERR.deref()).println("No need to call RT.init() anymore"); } static public long lastModified(URL url,String libfile) throws Exception{ @@ -389,8 +389,8 @@ static public void load(String scriptbase, boolean failIfNotFound) throws Except try { Var.pushThreadBindings( - RT.map(CURRENT_NS, CURRENT_NS.get(), - WARN_ON_REFLECTION, WARN_ON_REFLECTION.get())); + RT.map(CURRENT_NS, CURRENT_NS.deref(), + WARN_ON_REFLECTION, WARN_ON_REFLECTION.deref())); loaded = (loadClassForName(scriptbase.replace('/','.') + LOADER_SUFFIX) != null); } finally @@ -400,7 +400,7 @@ static public void load(String scriptbase, boolean failIfNotFound) throws Except } if(!loaded && cljURL != null) { - if (booleanCast(Compiler.COMPILE_FILES.get())) + if (booleanCast(Compiler.COMPILE_FILES.deref())) compile(cljfile); else loadResourceScript(RT.class, cljfile); @@ -416,8 +416,8 @@ static void doInit() throws Exception{ load("clojure/set",false); Var.pushThreadBindings( - RT.map(CURRENT_NS, CURRENT_NS.get(), - WARN_ON_REFLECTION, WARN_ON_REFLECTION.get())); + RT.map(CURRENT_NS, CURRENT_NS.deref(), + WARN_ON_REFLECTION, WARN_ON_REFLECTION.deref())); try { Symbol USER = Symbol.create("user"); @@ -1193,15 +1193,15 @@ static public Object readString(String s){ static public void print(Object x, Writer w) throws Exception{ //call multimethod - if(PRINT_INITIALIZED.isBound() && RT.booleanCast(PRINT_INITIALIZED.get())) + if(PRINT_INITIALIZED.isBound() && RT.booleanCast(PRINT_INITIALIZED.deref())) PR_ON.invoke(x, w); //* else{ - boolean readably = booleanCast(PRINT_READABLY.get()); + boolean readably = booleanCast(PRINT_READABLY.deref()); if(x instanceof Obj) { Obj o = (Obj) x; - if(RT.count(o.meta()) > 0 && readably && booleanCast(PRINT_META.get())) + if(RT.count(o.meta()) > 0 && readably && booleanCast(PRINT_META.deref())) { IPersistentMap meta = o.meta(); w.write("#^"); @@ -1411,7 +1411,7 @@ static public Object format(Object o, String s, Object... args) throws Exception if(o == null) w = new StringWriter(); else if(Util.equals(o, T)) - w = (Writer) OUT.get(); + w = (Writer) OUT.deref(); else w = (Writer) o; doFormat(w, s, ArraySeq.create(args)); @@ -1495,7 +1495,7 @@ static public ClassLoader makeClassLoader(){ } static public ClassLoader baseLoader(){ - if(booleanCast(USE_CONTEXT_CLASSLOADER.get())) + if(booleanCast(USE_CONTEXT_CLASSLOADER.deref())) return Thread.currentThread().getContextClassLoader(); else if(ROOT_CLASSLOADER != null) return ROOT_CLASSLOADER; diff --git a/src/jvm/clojure/lang/Ref.java b/src/jvm/clojure/lang/Ref.java index 2a59b185..90faedcc 100644 --- a/src/jvm/clojure/lang/Ref.java +++ b/src/jvm/clojure/lang/Ref.java @@ -15,7 +15,6 @@ package clojure.lang; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.UUID; public class Ref extends ARef implements IFn, Comparable<Ref>, IRef{ public int compareTo(Ref ref) { @@ -27,7 +26,7 @@ public class Ref extends ARef implements IFn, Comparable<Ref>, IRef{ return 1; } - public static class TVal{ +public static class TVal{ Object val; long point; long msecs; @@ -94,7 +93,7 @@ Object currentVal(){ //* -public Object get(){ +public Object deref(){ LockingTransaction t = LockingTransaction.getRunning(); if(t == null) return currentVal(); @@ -190,7 +189,7 @@ public void trimHistory(){ final public IFn fn(){ - return (IFn) get(); + return (IFn) deref(); } public Object call() throws Exception{ diff --git a/src/jvm/clojure/lang/TransactionalHashMap.java b/src/jvm/clojure/lang/TransactionalHashMap.java index a738cc50..ba77b862 100644 --- a/src/jvm/clojure/lang/TransactionalHashMap.java +++ b/src/jvm/clojure/lang/TransactionalHashMap.java @@ -19,7 +19,7 @@ public class TransactionalHashMap<K, V> extends AbstractMap<K, V> implements Con final Ref[] bins; IPersistentMap mapAt(int bin){ - return (IPersistentMap) bins[bin].get(); + return (IPersistentMap) bins[bin].deref(); } final int binFor(Object k){ @@ -76,7 +76,7 @@ public V get(Object k){ public V put(K k, V v){ Ref r = bins[binFor(k)]; - IPersistentMap map = (IPersistentMap) r.get(); + IPersistentMap map = (IPersistentMap) r.deref(); Object ret = map.valAt(k); r.set(map.assoc(k, v)); return (V) ret; @@ -84,7 +84,7 @@ public V put(K k, V v){ public V remove(Object k){ Ref r = bins[binFor(k)]; - IPersistentMap map = (IPersistentMap) r.get(); + IPersistentMap map = (IPersistentMap) r.deref(); Object ret = map.valAt(k); //checked exceptions are a bad idea, especially in an interface try @@ -110,7 +110,7 @@ public void clear(){ for(int i = 0; i < bins.length; i++) { Ref r = bins[i]; - IPersistentMap map = (IPersistentMap) r.get(); + IPersistentMap map = (IPersistentMap) r.deref(); if(map.count() > 0) { r.set(PersistentHashMap.EMPTY); @@ -139,7 +139,7 @@ public Set<Entry<K, V>> entrySet(){ public V putIfAbsent(K k, V v){ Ref r = bins[binFor(k)]; - IPersistentMap map = (IPersistentMap) r.get(); + IPersistentMap map = (IPersistentMap) r.deref(); Entry e = map.entryAt(k); if(e == null) { @@ -152,7 +152,7 @@ public V putIfAbsent(K k, V v){ public boolean remove(Object k, Object v){ Ref r = bins[binFor(k)]; - IPersistentMap map = (IPersistentMap) r.get(); + IPersistentMap map = (IPersistentMap) r.deref(); Entry e = map.entryAt(k); if(e != null && e.getValue().equals(v)) { @@ -172,7 +172,7 @@ public boolean remove(Object k, Object v){ public boolean replace(K k, V oldv, V newv){ Ref r = bins[binFor(k)]; - IPersistentMap map = (IPersistentMap) r.get(); + IPersistentMap map = (IPersistentMap) r.deref(); Entry e = map.entryAt(k); if(e != null && e.getValue().equals(oldv)) { @@ -184,7 +184,7 @@ public boolean replace(K k, V oldv, V newv){ public V replace(K k, V v){ Ref r = bins[binFor(k)]; - IPersistentMap map = (IPersistentMap) r.get(); + IPersistentMap map = (IPersistentMap) r.deref(); Entry e = map.entryAt(k); if(e != null) { diff --git a/src/jvm/clojure/lang/Var.java b/src/jvm/clojure/lang/Var.java index dfc0436c..2dd3c8b7 100644 --- a/src/jvm/clojure/lang/Var.java +++ b/src/jvm/clojure/lang/Var.java @@ -128,6 +128,10 @@ public boolean isBound(){ } final public Object get(){ + return deref(); +} + +final public Object deref(){ Box b = getThreadBinding(); if(b != null) return b.val; @@ -143,7 +147,7 @@ public void setValidator(IFn vf){ } public Object alter(IFn fn, ISeq args) throws Exception{ - set(fn.applyTo(RT.cons(get(), args))); + set(fn.applyTo(RT.cons(deref(), args))); return this; } @@ -310,7 +314,7 @@ final Box getThreadBinding(){ } final public IFn fn(){ - return (IFn) get(); + return (IFn) deref(); } public Object call() throws Exception{ |