-
Notifications
You must be signed in to change notification settings - Fork 193
Fix cext support for google-protobuf #3861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…`frozen?`. MRI defines `frozen?` with `rb_obj_frozen_p`, which in turn, uses `RB_OBJ_FROZEN`. Since TruffleRuby doesn't have flag bits in an object header like MRI does, we implement `RB_OBJ_FROZEN` with `rb_obj_frozen_p`, which would lead to an infinite loop if a native extension redefined `frozen?` in terms of `RB_OBJ_FROZEN`. We break the loop by introducing a new primitive, which a native extension would not be able to redefine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the fixes!
@@ -49,3 +49,8 @@ bool rb_warning_category_enabled_p(rb_warning_category_t category) { | |||
void rb_tr_warn_va_list(const char *fmt, va_list args) { | |||
RUBY_CEXT_INVOKE("rb_tr_warn", rb_vsprintf(fmt, args)); | |||
} | |||
|
|||
void rb_error_frozen_object(VALUE frozen_obj) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move it to exception.c
?
In general we don't follow whatever the .c
file is in CRuby, instead we group by function prefix as documented by a comment at the top of the file.
BTW I'm not sure why we even have this file named as error.c
, it should be renamed to warning.c
. Could be done in this PR too while we noticed it.
@@ -2347,6 +2347,10 @@ def rb_eval_cmd_kw(cmd, args, kw_splat) | |||
end | |||
end | |||
|
|||
def rb_error_frozen_object(object) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a C API spec in exception_spec.c/rb? (to ensure it works as expected and it's not untested code)
@@ -410,6 +410,16 @@ static VALUE object_spec_custom_alloc_func_p(VALUE self, VALUE klass) { | |||
return allocator ? Qtrue : Qfalse; | |||
} | |||
|
|||
static VALUE object_spec_redefine_rb_obj_frozen_p(VALUE self) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static VALUE object_spec_redefine_rb_obj_frozen_p(VALUE self) { | |
static VALUE object_spec_redefine_frozen(VALUE self) { |
redefine_rb_obj_frozen_p
sounds too confusing to me, we can't redefine a C function
@@ -410,6 +410,16 @@ static VALUE object_spec_custom_alloc_func_p(VALUE self, VALUE klass) { | |||
return allocator ? Qtrue : Qfalse; | |||
} | |||
|
|||
static VALUE object_spec_redefine_rb_obj_frozen_p(VALUE self) { | |||
// The purpose of this spec is to verify that `rb_obj_frozen_p` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// The purpose of this spec is to verify that `rb_obj_frozen_p` | |
// The purpose of this spec is to verify that `obj.frozen?` |
While trying to run the google-protobuf test suite I ran into a couple of problems related to native extensions.
RB_OBJ_FROZEN
could lead to infinite recursion. At least one of the Protobuf types definesfrozen?
and useRB_OBJ_FROZEN
to avoid a loop. I resolved that issue by adding a new primitive.rb_error_frozen_object
.I didn't add a spec for
rb_error_frozen_object
, partially because it wasn't clear where to put it. The function only seems to be called in MRI wheninstance_variable_set
is invoked on a special const. Also, I added the function to error.c because that's where it lives in MRI. But, I see we have other functions that we've moved from error.c to exception.c (or, they moved in MRI and we didn't update to match). I don't particularly care where we put it; I can move it if anyone has a strong preference.There may be other compatibility issues to resolve in order to get the gem fully functional. But, it's hard for me to tell due to the crash in #3860.