Repository navigation
-mm=own: a class seen through an interface keeps its field families; interface calls open parameter families - #710
Merged
Conversation
…interface calls open parameter families An interface reaches a class's fields only through vtables built from the class, so a cast to an interface no longer opens the class's callback field families (any, unions, unknown and object still do). A method in an interface's vtable is called through ts.InterfaceSymbolRef with arguments its callback parameter families never saw; its vtable entry no longer counts as a seen call. Before, r.each(pool, drain) through an interface compiled with each's callback family closed and empty, so a call that freed pool's element was taken to release nothing (spec 58). 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.
Under
-mm=own, a class whose objects are seen through an interface now keeps its callback field families. This PR also closes a hole where a callback passed through an interface call was never checked. Spec section 58 and the user doc's limits are updated.Changes
A cast to an interface no longer opens field families. An interface reaches a class's fields only through a vtable built from the class (
<Class>.<Interface>..vtbl). That vtable is built where the class is known: in this module, or in a module that names the class, wherecallableFromOutsideof its constructor already opens the family. I checked each path in the IR:ts.PropertyRefof the class, which already opens the family...vtbl.<field>.thunk) that only loads the field and calls it. Storing through it is refused in every model.castInterfaceToInterfaceonly remaps the source vtable's slots.A cast to
any, a union,unknownorobjectstill opens the family, because another module could cast the object back to the class.Interface calls open callback parameter families (a fix). A method in an interface's vtable was treated like a class-vtable entry, so
callsOfcounted its vtable use as a call the family had seen. Butts.InterfaceSymbolRefcalls pass arguments the family never sees, from any module the interface reaches. So in this programeach'sffamily was closed and empty, andf(v)was taken to release nothing:drainfreespooland the elementvit holds, andv.nis then read from freed memory. Main compiles this today. Now a newinInterfaceVTablecheck finds a..vtblglobal whose class's..instanceOfnames a different..vtbl, and such an entry no longer counts as a seen call.The cost: a callback parameter of a method an interface reaches stays open, even where the method is called on its class.
Tests
own_callback_interface: a class seen as two interfaces. The callback field is stored by the constructor and by a method called on the class. It runs under own, rc, gc and none, and own emits no counting.own_err_callback_interface_param: the use-after-free above, refused at:34:11.own_err_callback_interface_field: a callback passed through an interface's method and stored into the field, refused at:46:11.Not in this PR
Two bugs found along the way. Both happen in every model:
h.f = show) fails with "saving to constant object", because the slot is a constant thunk.anyto an interface the class doesn't implement, then calling through it, crashes with an access violation.🤖 Generated with Claude Code