Repository navigation
A global declared in top-level code owns what it is given (rc; -mm=own phase 6, PR 1) - #444
Merged
Merged
Conversation
`const t = new C()` in top-level code stored the instance into the global with no reference of its own, and the end-of-block release (§9.30) then gave the value's reference back, leaving the global pointing at a freed block once the top-level code ended. An assignment to a global already hands the count over (isOwnedGlobalSlot, 5ai); the declaration's store now does the same: it takes over an owned reference or retains, and releases what the slot held before (a `var` met again in a loop). Under rc it is not observable today: nothing runs after a program's top-level code (a `var` in a nested block is released at the end of the top-level code too, not of its block), and a module with top-level code cannot be imported. Under -mm=own the store read as a move and the release as a second reference, which failed 28 corpus files. No branch on the memory model in MLIRGen: gc erases the retain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The first PR of
-mm=ownphase 6 (corpus report and diagnostics polish). It is an rc-side fix, so it stands alone and can merge on its own.The bug
When top-level code declares a global (
const t = new C(), orlet/var), its initial value is stored into the global with no reference of its own. The end-of-block release (§9.30) then gives the value's reference back when the top-level code ends, so the global points at a freed block. 5ai fixed this for an assignment to a global (t = new C(), throughisOwnedGlobalSlot), but not for the declaration's store (MLIRGenImpl.h, the "not global scope" branch).The fix
The declaration's store now takes the owning-slot path, the same one an assignment takes:
varmet again in a loop. A global starts at zero, so the first release does nothing.This doesn't branch on the memory model in MLIRGen (spec §4.3): gc erases the retain.
Why it matters
Found, not fixed (every model, outside this PR)
print(...)), imported as source, fails with "Global is referenced by parentless instruction! @puts" (invalid LLVM IR).-shared, an exportedconstfrom such a module can't be resolved by the importer ("can't resolve name").Verification
test-compile-gc-defaultlib-collector, is the stale installed default library, as on -mm=own phase 5a: a closure that does not escape borrows what it captures #436-Builtin iterator methods without the default library: a.map(f).map(g) #443. The rc suite is unchanged.-mm=own, AOT and JIT, with gc's output (import_class_interface.tsas itsexport_pair; its non--sharedJIT mode is unsupported under every model):00class_from_tuple,00class_indexer,00class_protected_constr,00if_conditional_compile,00safe_cast_typeof,00toplevel_control_flow,00toplevel_no_main_with_helpers,import_class_interface.Test
own/own_global_script.tsruns under own, rc, none and gc. It coversconst,letandvarglobals in top-level code (a class and a string), avarin a nested block, reads from a function after the heap is churned, and an overwrite.🤖 Generated with Claude Code