Skip to content

Commit 7bdda74

Browse files
Scope generated IDs by namespace
This ensures that the same IDs are used when compiling anonymous functions/constants/reify/eval/auto/gensym, without depending on the global namespace compilation order.
1 parent fb22fd7 commit 7bdda74

File tree

4 files changed

+19
-12
lines changed

4 files changed

+19
-12
lines changed

src/clj/clojure/core.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@
610610
{:added "1.0"
611611
:static true}
612612
([] (gensym "G__"))
613-
([prefix-string] (. clojure.lang.Symbol (intern (str prefix-string (str (. clojure.lang.RT (nextID))))))))
613+
([prefix-string] (. clojure.lang.Symbol (intern (str prefix-string (str (. clojure.lang.RT (nextID (str (.getName *ns*))))))))))
614614

615615

616616
(defn keyword

src/jvm/clojure/lang/Compiler.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4498,12 +4498,12 @@ static Expr parse(C context, ISeq form, String name) {
44984498

44994499
if(RT.second(form) instanceof Symbol) {
45004500
nm = (Symbol) RT.second(form);
4501-
name = nm.name + "__" + RT.nextID();
4501+
name = nm.name + "__" + RT.nextID(basename);
45024502
} else {
45034503
if(name == null)
4504-
name = "fn__" + RT.nextID();
4504+
name = "fn__" + RT.nextID(basename);
45054505
else if (enclosingMethod != null)
4506-
name += "__" + RT.nextID();
4506+
name += "__" + RT.nextID(basename);
45074507
}
45084508

45094509
String simpleName = munge(name).replace(".", "_DOT_");
@@ -4603,7 +4603,7 @@ else if(methodArray[f.reqParms.count()] == null)
46034603
fn.protocolCallsites = (IPersistentVector) PROTOCOL_CALLSITES.deref();
46044604
fn.varCallsites = (IPersistentSet) VAR_CALLSITES.deref();
46054605

4606-
fn.constantsID = RT.nextID();
4606+
fn.constantsID = RT.nextID(basename);
46074607
// DynamicClassLoader loader = (DynamicClassLoader) LOADER.get();
46084608
// loader.registerConstants(fn.constantsID, fn.constants.toArray());
46094609
}
@@ -6821,7 +6821,7 @@ public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
68216821
BindingInit bi = (BindingInit) bis.first();
68226822
String lname = bi.binding.name;
68236823
if(lname.endsWith("__auto__"))
6824-
lname += RT.nextID();
6824+
lname += RT.nextID(currentNS().getName().toString());
68256825
Class primc = maybePrimitiveType(bi.init);
68266826
if(primc != null)
68276827
gen.visitLocalVariable(lname, Type.getDescriptor(primc), null, loopLabel, end,
@@ -7052,7 +7052,7 @@ public void doEmit(C context, ObjExpr objx, GeneratorAdapter gen, boolean emitUn
70527052
BindingInit bi = (BindingInit) bis.first();
70537053
String lname = bi.binding.name;
70547054
if(lname.endsWith("__auto__"))
7055-
lname += RT.nextID();
7055+
lname += RT.nextID(currentNS().getName().toString());
70567056
Class primc = maybePrimitiveType(bi.init);
70577057
if(primc != null)
70587058
gen.visitLocalVariable(lname, Type.getDescriptor(primc), null, bindingLabels.get(bi), end,
@@ -7695,7 +7695,7 @@ else if((form instanceof IType) ||
76957695
&& ((Symbol) RT.first(form)).name.startsWith("def"))))
76967696
{
76977697
ObjExpr fexpr = (ObjExpr) analyze(C.EXPRESSION, RT.list(FN, PersistentVector.EMPTY, form),
7698-
"eval" + RT.nextID());
7698+
"eval" + RT.nextID(currentNS().getName().toString()));
76997699
IFn fn = (IFn) fexpr.eval();
77007700
return fn.invoke();
77017701
}
@@ -8475,7 +8475,7 @@ public Expr parse(C context, Object frm) {
84758475
String basename = enclosingMethod != null ?
84768476
(trimGenID(enclosingMethod.objx.name) + "$")
84778477
: (munge(currentNS().name.name) + "$");
8478-
String simpleName = "reify__" + RT.nextID();
8478+
String simpleName = "reify__" + RT.nextID(currentNS().getName().toString());
84798479
String classname = basename + simpleName;
84808480

84818481
ISeq rform = RT.next(form);
@@ -8594,7 +8594,7 @@ VAR_CALLSITES, emptyVarCallSites(),
85948594
ret.keywords = (IPersistentMap) KEYWORDS.deref();
85958595
ret.vars = (IPersistentMap) VARS.deref();
85968596
ret.constants = (PersistentVector) CONSTANTS.deref();
8597-
ret.constantsID = RT.nextID();
8597+
ret.constantsID = RT.nextID(currentNS().getName().toString());
85988598
ret.keywordCallsites = (IPersistentVector) KEYWORD_CALLSITES.deref();
85998599
ret.protocolCallsites = (IPersistentVector) PROTOCOL_CALLSITES.deref();
86008600
ret.varCallsites = (IPersistentSet) VAR_CALLSITES.deref();

src/jvm/clojure/lang/LispReader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ public Object invoke(Object reader, Object hash, Object opts, Object pendingForm
863863
}
864864

865865
static Symbol garg(int n){
866-
return Symbol.intern(null, (n == -1 ? "rest" : ("p" + n)) + "__" + RT.nextID() + "#");
866+
return Symbol.intern(null, (n == -1 ? "rest" : ("p" + n)) + "__" + RT.nextID(((Namespace)RT.CURRENT_NS.deref()).getName().toString()) + "#");
867867
}
868868

869869
public static class FnReader extends AFn{
@@ -1022,7 +1022,7 @@ else if(form instanceof Symbol)
10221022
if(gs == null)
10231023
GENSYM_ENV.set(gmap.assoc(sym, gs = Symbol.intern(null,
10241024
sym.name.substring(0, sym.name.length() - 1)
1025-
+ "__" + RT.nextID() + "__auto__")));
1025+
+ "__" + RT.nextID(((Namespace)RT.CURRENT_NS.deref()).getName().toString()) + "__auto__")));
10261026
sym = gs;
10271027
}
10281028
else if(sym.ns == null && sym.name.endsWith("."))

src/jvm/clojure/lang/RT.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.net.MalformedURLException;
1616
import java.net.URISyntaxException;
1717
import java.net.URI;
18+
import java.util.concurrent.ConcurrentHashMap;
1819
import java.util.concurrent.atomic.AtomicInteger;
1920
import java.util.concurrent.Callable;
2021
import java.util.*;
@@ -294,6 +295,7 @@ private Object readResolve() throws ObjectStreamException {
294295
}
295296
}
296297

298+
static Map<String, AtomicInteger> scopedIds = new ConcurrentHashMap<>();
297299
static AtomicInteger id = new AtomicInteger(1);
298300

299301
static public URL toUrl(String url) throws MalformedURLException {
@@ -524,6 +526,11 @@ static public int nextID(){
524526
return id.getAndIncrement();
525527
}
526528

529+
public static int nextID(String scope) {
530+
AtomicInteger id = scopedIds.computeIfAbsent(scope, k -> new AtomicInteger(1));
531+
return id.getAndIncrement();
532+
}
533+
527534
// Load a library in the System ClassLoader instead of Clojure's own.
528535
public static void loadLibrary(String libname){
529536
System.loadLibrary(libname);

0 commit comments

Comments
 (0)