Skip to content

Commit 234d35c

Browse files
committed
Fix AOT namespace reloading issue that broke test runner
This fixes a critical bug where AOT-compiled namespaces would reinitialize their vars (including *loaded-libs*) when required multiple times, causing test failures when using the test runner with dynamic bindings. Problem: - When clojure.data.generators required clojure.core, the AOT loader would reinitialize *loaded-libs*, removing previously loaded namespaces - This caused clojure.test to be reloaded inside the test runner's binding of t/report, leading to "no such method AddMethod" errors when defmethod tried to add methods to a bound function Solution: - Made AOT loaders idempotent by checking namespace metadata before initializing - Each LoadNS() function now: 1. Checks if namespace has :aot-loaded metadata 2. Returns immediately if already loaded 3. Sets :aot-loaded metadata after initialization - This preserves *loaded-libs* and all other dynamic vars across multiple requires Changes: - Modified pkg/runtime/codegen.go to generate idempotent LoadNS functions - Regenerated all AOT loader files with the new logic - Updated Makefile test targets (from previous commit) This ensures AOT namespaces are only initialized once, preventing the corruption of global state like *loaded-libs* and fixing the multimethod binding issues in the test runner.
1 parent 5d9b908 commit 234d35c

12 files changed

Lines changed: 1042 additions & 830 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ vet:
183183
# vet is disabled until we fix errors in generated code
184184
test: test-glj test-suite # vet
185185

186-
# Run tests in test/glojure/test_glojure using the new test runner
186+
# Run tests in test/glojure/test_glojure using the new test runner
187187
test-glj: $(GLJ-CMD)
188188
$(GLJ-CMD) -m glojure.test-runner --dir test/glojure --format console
189189

pkg/runtime/codegen.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,17 @@ runtime.RegisterNSLoader(` + fmt.Sprintf("%q", rootResourceName) + `, LoadNS)
236236
`)
237237
initBuf.WriteString(fmt.Sprintf("// LoadNS initializes the namespace %q\n", ns.Name().String()))
238238
initBuf.WriteString("func LoadNS() {\n")
239+
240+
// Add idempotency check
241+
initBuf.WriteString(fmt.Sprintf(` // Check if already AOT-loaded
242+
if ns := lang.FindNamespace(lang.NewSymbol(%q)); ns != nil {
243+
if meta := ns.Meta(); meta != nil {
244+
if aotLoaded := meta.ValAt(lang.NewKeyword("aot-loaded")); aotLoaded != nil {
245+
return // Already loaded, skip reinitialization
246+
}
247+
}
248+
}
249+
`, ns.Name().String()))
239250

240251
//////////////////////////
241252
// Symbols
@@ -347,6 +358,19 @@ runtime.RegisterNSLoader(` + fmt.Sprintf("%q", rootResourceName) + `, LoadNS)
347358
}
348359
}
349360

361+
// Mark namespace as AOT-loaded
362+
initBuf.WriteString(fmt.Sprintf(`
363+
// Mark namespace as AOT-loaded
364+
if ns := lang.FindNamespace(lang.NewSymbol(%q)); ns != nil {
365+
// Set metadata directly
366+
meta := ns.Meta()
367+
if meta == nil {
368+
meta = lang.NewMap()
369+
}
370+
ns.ResetMeta(meta.Assoc(lang.NewKeyword("aot-loaded"), true).(lang.IPersistentMap))
371+
}
372+
`, ns.Name().String()))
373+
350374
// Closing brace for LoadNS
351375
initBuf.WriteString("}\n")
352376

pkg/stdlib/clojure/core/async/loader.go

Lines changed: 42 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/stdlib/clojure/core/loader.go

Lines changed: 713 additions & 695 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/stdlib/clojure/core/protocols/loader.go

Lines changed: 33 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)