Repository navigation
Conversation
When a C extension reuses one variable as both the superclass argument
and the target of rb_define_class_under:
VALUE cSocket = rb_const_get(rb_cObject, rb_intern("Socket"));
cSocket = rb_define_class_under(mExample, "Socket", cSocket);
the C parser recorded the superclass as the variable name "cSocket".
Store#resolve_c_superclasses then resolved that variable to the class
being defined, so Example::Socket became its own superclass.
Look up a superclass variable that was assigned from
rb_const_get(under, rb_intern("Name")) and use that class name instead,
and never let resolve_c_superclasses make a class its own superclass.
Fixes ruby#1782
Documentation previewCommit: |
This branch has not been deployed
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.
Fixes #1782. When a C extension gets a class with
rb_const_getand then reuses the same variable as both the superclass and the target ofrb_define_class_under(as kgio does), the C parser recorded the superclass as the variable name"cSocket".Store#resolve_c_superclasseslater resolved that variable to the class being defined, soExample::Socketbecame its own superclass. Since #1785 this no longer overflows the stack, butristill showsExample::Socket < Example::Socket.handle_class_modulenow looks up a superclass variable it doesn't already know. If it was assigned fromrb_const_get(under, rb_intern("Name"))(orrb_const_get_at/rb_intern_const), it uses that class name:Namewhenunderisrb_cObject,Under::Namefor another known module. If the variable is assigned different constants in different places, the lookup gives up and keeps the variable name rather than guess. The issue's example now documentsExample::Socket < Socket. The same lookup also fixes a plainrb_define_class("Foo", cBase)wherecBasecame fromrb_const_get, which used to show the variable name as the superclass. With kgio's sources,Kgio::Socket,TCPSocket,TCPServer,UNIXSocketandUNIXServernow get their real superclasses. The superclasses documented for Ruby's ownext/*.cdon't change.As a safety net,
resolve_c_superclassesno longer replaces a superclass with the class itself (the minimum suggested in the issue). Then an unresolvable variable stays a name rather than forming a cycle.The first hunk touches the same line as #1831 (
parent_name = ...inhandle_class_module), so whichever lands second will need a small rebase. I'm happy to do it.