summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
authorAlan Wu <[email protected]>2024-04-22 14:33:34 -0400
committerGitHub <[email protected]>2024-04-22 18:33:34 +0000
commitaeb08bc8a71006b63a6588ef5129b7723c8219fc (patch)
tree2563b237cc301900a55ad63c0d251923c33198af /object.c
parent1bb7638e7a864db9b635c5d41f18653e8451dbc7 (diff)
YJIT: Fix String#setbyte crashing for converted arguments
Previously, passing objects that respond to #to_int to `String#setbyte` resulted in a crash when compiled by YJIT. This was due to the lazily pushed frame from rb_yjit_lazy_push_frame() lingering and not being popped by an exception as expected. The fix is to ensure that `ec->cfp` is restored to before the lazy frame push in case the method call for conversion succeeds. Right now, this is only for conversion to integers. Found running `ruby/spec`. * clarify comment We just need to make sure `ec->cfp` is always preserved and this can convert without rising when `raise` is true.
Diffstat (limited to 'object.c')
-rw-r--r--object.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/object.c b/object.c
index 54240f0774..0a8ce4dc0f 100644
--- a/object.c
+++ b/object.c
@@ -3236,15 +3236,22 @@ ALWAYS_INLINE(static VALUE rb_to_integer_with_id_exception(VALUE val, const char
static inline VALUE
rb_to_integer_with_id_exception(VALUE val, const char *method, ID mid, int raise)
{
+ // We need to pop the lazily pushed frame when not raising an exception.
+ rb_control_frame_t *current_cfp;
VALUE v;
if (RB_INTEGER_TYPE_P(val)) return val;
+ current_cfp = GET_EC()->cfp;
rb_yjit_lazy_push_frame(GET_EC()->cfp->pc);
v = try_to_int(val, mid, raise);
- if (!raise && NIL_P(v)) return Qnil;
+ if (!raise && NIL_P(v)) {
+ GET_EC()->cfp = current_cfp;
+ return Qnil;
+ }
if (!RB_INTEGER_TYPE_P(v)) {
conversion_mismatch(val, "Integer", method, v);
}
+ GET_EC()->cfp = current_cfp;
return v;
}
#define rb_to_integer(val, method, mid) \