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
Safely retrieve self
from proc in mrb_yield()
#5951
Conversation
src/proc.c
Outdated
* Probably created by mrb_load_irep(), mrb_load_string() or etc., | ||
* or occurred a out of memory in mrb_env_unshare(). | ||
*/ | ||
mrb_raise(mrb, E_ARGUMENT_ERROR, "self is lost"); |
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.
How about returning mrb_top_self
instead of raising an exception?
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.
I am not very positive.
I'm concerned that if mrb_top_self
is used, there will be a mismatch with the self
that the user expects, and this will cause confusion.
Is it really appropriate to return mrb_top_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.
I think so. As far as I see in the example in #5932, the issue happens with top-level proc. So the natural assumption for the receiver should be the toplevel self for most of the cases
On the other hand, if it raises exception, the user would be confused by not knowing how to handle this kind of error.
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.
I understand. Let's change it that way.
However, I would like to make an exception if mrb_env_unshare()
encounters out of memory.
I expect this can be detected by MRB_ENV_LEN(env) == 0
.
Relatedly, I would also allow the target class to be retrieved by mrb_proc_get_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.
Change completed.
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!
self
from procself
from proc in mrb_yield()
src/proc.c
Outdated
|
||
if (!e || e->tt != MRB_TT_ENV) { | ||
mrb_value self = mrb_top_self(mrb); | ||
*target_class_p = mrb_class(mrb, 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.
In this case, top-level target class should be mrb->object_class
I think.
Passing a proc generated by the following method to `mrb_yield()` or `mrb_yield_argv()` no longer causes `SIGSEGV`: - C functions made into proc objects with `mrb_proc_new_cfunc()`. - A proc object which is the top level of a program generated by `mrb_load_string_cxt()` etc. with `mrbc_context::no_exec` enabled. See also: mruby#5932
Right, I agree. |
Safely retrieve
self
from proc inmrb_yield()
Passing a proc generated by the following method to
mrb_yield()
ormrb_yield_argv()
no longer causesSIGSEGV
:mrb_proc_new_cfunc()
.mrb_load_string_cxt()
etc. withmrbc_context::no_exec
enabled.See also: #5932