-mm=own: a library exports which of its functions destroy nothing - #409
Merged
Merged
Conversation
A library built under own now writes, beside its memory-model marker __tsmm_own_<module>, an exported string __tsown_<module>: the exported functions that have __own_no_drops, one name per line. The signature pass writes it as a copy of the marker global, so it is exported the way the marker is on every platform and MLIRGen emits the same under own as under rc. The importer reads it beside the marker (from the loaded library or from the file) and keeps the names on its module, ts.own_imported_no_drops, in every model. The signature pass resolves a call to one - through a declaration linked with the import library, or through the global a library loaded at run time fills from SearchForAddressOfSymbol - as known and drop-free, like the .instanceOf slot. A global whose address is used other than to load from it is not trusted. Only this fact crosses. A missing one only makes an importer report more, so a module linking the library statically, which re-parses its source and sees no facts, stays sound. The kept-parameter and borrowed-result facts change the callee's body; an importer that does not know them frees twice, and under own there is no counting to adapt the call with. Tests: a -shared pair under JIT and AOT (a borrow of a parameter's field held across the imported calls), and on Windows a script that checks an unlisted dropping function is still rejected and that the same program is rejected against the library built under rc, which lists nothing. 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 last phase-4 leftover (spec §3.2, §15.7): a library built under
-mm=owntells its importers which of its exported functions destroy nothing.What crosses, and why only this
A library now exports
__tsown_<module>beside its marker__tsmm_own_<module>. It lists, one name per line, the exported functions that have__own_no_drops.The other two facts can't cross.
__own_paramsand__own_result_borrowschange the callee's body: its retains are gone.A missing
__own_no_dropsonly makes an importer report more errors, so it is safe to export in every link mode.How
Export.
OwnershipSignaturePasswrites the list as a copy of the marker global, under another name and value. It is therefore exported the way the marker is on Windows and Linux, and MLIRGen emits the same IR under own as under rc (test-own-mlirgen-matches-rc).Import.
mlirGenImportSharedLibreads the list beside the marker, from the loaded library or from the file. It records the names as the module attributets.own_imported_no_dropsin every model, for the same reason; only own reads it.Resolution. The signature pass treats a call to a listed function as known and drop-free, like the
.instanceOfslot, in two forms:Load(AddressOf @f), wherefis filled bySearchForAddressOfSymbol("<name>")when the library is loaded at run time. Such a global is not trusted if its address is used other than to load from it.A virtual call to a method of an imported class stays unknown, because the importer may override it.
The JIT cache already hashes every imported library as a dependency, so rebuilding a library invalidates its importers' cached objects.
Tests
own/import_own_no_drops.ts+own/export_own_no_drops.ts, as a-sharedpair under JIT and AOT. The importer holds a borrow of a parameter's field across calls tototalandM.first.own-shared-no-drops.cmake(Windows) checks two things:import_own_err_imported_drops.tsis still rejected, becauseshrinkremoves an element and isn't listed;-sharedpair ran there too, and it can only compile if the facts crossed.-mm=owncorpus: unchanged at 303 compiling files.Found, not fixed
An importer under own can't yet build an object of an imported class:
new H()through the library reports'this value' is used here after its value was moved. This predates the change and is recorded in §15.7.Independent of #407 and #408.
🤖 Generated with Claude Code