You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
warning: OpenStruct#define_singleton_method accesses caller method's state and should not be aliased #40
jruby 9.3.3.0 now shows the following warning.
It did not show up in jruby 9.3.2.0.
jruby 9.3.3.0 (2.6.8) 2022-01-19 b26de1f5c5 OpenJDK 64-Bit Server VM 11.0.13+8-Ubuntu-0ubuntu1.20.04 on 11.0.13+8-Ubuntu-0ubuntu1.20.04 +jit [linux-x86_64]
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/ostruct.rb:464: warning: OpenStruct#define_singleton_method accesses caller method's state and should not be aliased
uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/ostruct.rb:468: warning: OpenStruct#block_given? accesses caller method's state and should not be aliased
@marcandre This is the same issue for a couple other methods. I'm not sure why they were not reported before.
define_singleton_method needs to read the caller's frame visibility. It might be possible to eliminate this requirement in JRuby. Aliasing to another method name means we might not prepare that frame, so we warn.
block_given? also accesses the caller's frame, to get the block it was passed. This might also be possible to eliminate in JRuby, since the only time we can't get the passed block from the incoming arguments is when block_given? is called within a block body, which already forces a frame.
In the short term, though, these should probably be blacklisted for aliasing or overwriting, as they are part of the core plumbing of types and method calls.
Hmm, except that I actually use define_singleton_method!.
The problem is not the new name, it's that the old name is associated with a method that has special access to the caller frame. We know define_singleton_method' needs a frame. We do not know define-singleton_method!` needs a frame, so we warn.
The warning is because we do not necessarily know if we have already compiled code without a frame that calls define_singleton_method!.
isn't define_singleton_method always equivalent to singleton_class.define_method?
It is, and both require access to the caller's frame to get the current visibility.
isn't define_singleton_method always equivalent to singleton_class.define_method?
It is, and both require access to the caller's frame to get the current visibility.
My point is I don't understand why define_singleton_method needs the current visibility (by which you mean private/protected/public, right?), since AFAIK the defined method is always public.
I'm even more confused now that you say that singleton_class also does, even though it makes no sense to me, and there is no warning when it is aliased by ostruct.
Final confusion: doesn't define_method need the current visibility and thus aliasing it should issue a warning but it doesn't currently?
Hmmm, that may be the case. We implement define_singleton_method using define_method.
If you are right we can remove this restriction.
now that you say that singleton_class also does
define_method needs visibility, not singleton_class.
doesn't define_method need the current visibility and thus aliasing it should issue a warning but it doesn't currently
Are you aliasing it? It is defined on Module, not Object, so I would assume OpenStruct does not alias it.
Also, why are you aliasing the private method block_given?? Nobody can normally call it against another object, and if they did it would still act on the caller frame and nothing related to the object. Better to leave it untouched.
It does seem to be the case that define_singleton_method always defines public methods (which I suppose makes sense). I think we can remove the frame restriction for that one in 9.3.4 but I will confer with @enebo.
Confirmed! I will deal with the define_singleton_method issue and report back. Just want a chance to look over the C code and confirm they always force public visibility.
Activity
yamam commentedon Jan 24, 2022
I'm sorry, I'll report an Issue to Jruby as I think it's a JRuby problem.
marcandre commentedon Jan 25, 2022
I'll reopen, I imagine this is related to #30
headius commentedon Jan 27, 2022
@marcandre This is the same issue for a couple other methods. I'm not sure why they were not reported before.
In the short term, though, these should probably be blacklisted for aliasing or overwriting, as they are part of the core plumbing of types and method calls.
marcandre commentedon Jan 27, 2022
Hmm, except that I actually use
define_singleton_method!.I'm not sure of the technical details, but isn't
define_singleton_methodalways equivalent tosingleton_class.define_method?headius commentedon Jan 28, 2022
The problem is not the new name, it's that the old name is associated with a method that has special access to the caller frame. We know
define_singleton_method' needs a frame. We do not knowdefine-singleton_method!` needs a frame, so we warn.The warning is because we do not necessarily know if we have already compiled code without a frame that calls
define_singleton_method!.It is, and both require access to the caller's frame to get the current visibility.
marcandre commentedon Jan 28, 2022
My point is I don't understand why
define_singleton_methodneeds the current visibility (by which you meanprivate/protected/public, right?), since AFAIK the defined method is always public.I'm even more confused now that you say that
singleton_classalso does, even though it makes no sense to me, and there is no warning when it is aliased byostruct.Final confusion: doesn't
define_methodneed the current visibility and thus aliasing it should issue a warning but it doesn't currently?headius commentedon Jan 28, 2022
Hmmm, that may be the case. We implement
define_singleton_methodusingdefine_method.If you are right we can remove this restriction.
define_methodneeds visibility, notsingleton_class.Are you aliasing it? It is defined on Module, not Object, so I would assume OpenStruct does not alias it.
Also, why are you aliasing the private method
block_given?? Nobody can normally call it against another object, and if they did it would still act on the caller frame and nothing related to the object. Better to leave it untouched.headius commentedon Jan 28, 2022
It does seem to be the case that
define_singleton_methodalways defines public methods (which I suppose makes sense). I think we can remove the frame restriction for that one in 9.3.4 but I will confer with @enebo.marcandre commentedon Jan 28, 2022
Ugh, no, you're right of course.
So, in summary:
ostructwill not aliasblock_given?on JRubydefine_singleton_methodshould not warn on JRuby (to be confirmed)Alternative to 2 would be for
ostructto callsingleton_class!.define_methodinstead, but I'd rather avoid that if possible.headius commentedon Jan 28, 2022
Confirmed! I will deal with the
define_singleton_methodissue and report back. Just want a chance to look over the C code and confirm they always force public visibility.Avoid aliasing `block_given?` for JRuby [Fixes #40]
marcandre commentedon Jan 29, 2022
PR ready
headius commentedon Jan 31, 2022
Back to work this morning and I will look into the define_singleton_method visibility thing to confirm.
15 remaining items
fix warning:method should not be aliased
fix warning:method should not be aliased
fix warning:method should not be aliased
fix warning:method should not be aliased
fix warning:method should not be aliased
fix warning:method should not be aliased
fix jruby warning
fix jruby warning
fix jruby warning
ignore jruby alias_method method warning
ignore jruby alias_method method warning
ignore jruby alias_method method warning
Avoid aliasing `block_given?` for JRuby [Fixes ruby#40]
ignore jruby alias_method method warning
ignore jruby alias_method method warning