[#108552] [Ruby master Bug#18782] Race conditions in autoload when loading the same feature with multiple threads. — "ioquatix (Samuel Williams)" <noreply@...>
Issue #18782 has been reported by ioquatix (Samuel Williams).
11 messages
2022/05/14
[ruby-core:108477] Issue/limitations with differences between ruby eval() and C API rb_eval_string()
From:
David Ljung Madison Stellar <ruby-lang.org@...>
Date:
2022-05-07 05:15:20 UTC
List:
ruby-core #108477
The rb_eval_string() is seemingly capable of everything that eval is capable of, with
one slight deviation. The binding is oddly setup to be correct except for the receiver/self.
This means that while these both act the same:
ruby: eval("puts someLocalVariable")
C API: rb_eval_string("puts someLocalVariable")
These do not:
ruby: eval("puts @someInstanceVar") # Works
C API: rb_eval_string("puts @someInstanceVar") # nil
And this is because these do not work:
ruby: eval("puts self") # self of calling context
ruby: eval("puts binding().receiver") # self of calling context
C API: rb_eval_string("puts self") # main
C API: rb_eval_string("puts binding().receiver") # main
We can see the problem in the MRI source in ruby_eval_string_from_file() which has:
return eval_string_with_cref(rb_vm_top_self(), rb_str_new2(str), NULL, file, 1);
We've passed in rb_vm_top_self instead of the correct 'self'
Although possibly the issue is in the API itself with the fact that there's no way to plumb
through the receiver that you are given in the C extension method function call, i.e.:
// My C extension that calls eval and knows what it's 'self' is.
VALUE method_myCMethod(int argc, VALUE *argv, VALUE self) {
rb_eval_string("..."); // <- no way to be given self?
}
Having said that, rb_eval_string is able to determine the vast majority of the
binding context, since it correctly builds the binding() object *except* that
the receiver is set to main, so perhaps this is something that *can* be determined.
It is something that the builtin eval is able to do, after all. So possibly this
is just a failure with MRI. I don't have other rubies to test. (I'm on ruby 2.7.0)
Is there a way to fix this - to get the proper execution context *including* the
receiver, or does this need an API change where the user needs to send self in?
And I would argue this is a bug, because we are essentially given a corrupted
result from binding() - one where we may have access to the local variables of
an instance method, but one where the self itself is not properly set. That's
not an actual legit binding state in the ruby code.
Dave++
---------------------------------------------------------------------------
Dave Madison Stellar (he/him) http://GetDave.com/ 415.341.5555
--- I am totally into Ruby now. I love it. It rules with an iron fist. --
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>