diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2023-08-17 16:18:12 -0400 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2023-08-17 17:14:46 -0400 |
commit | 9683eb06cf91664cfe18f61677b2624fbaf8e3b0 (patch) | |
tree | 76fdc6295ba7ea58bcbde69331b8a814e89c7cee /yjit | |
parent | 57ec167306672960ce4c65586a96752ad43461c7 (diff) |
YJIT: Fix Kernel#respond_to? handling of rb_f_notimplement
We should return false for this type of special methods but wasn't
previously. Was reproducible with:
make test-all TESTS=../test/-ext-/test_notimplement.rb RUN_OPTS='--yjit-call-threshold=1'
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/8239
Diffstat (limited to 'yjit')
-rw-r--r-- | yjit/src/codegen.rs | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 88c5677551..aea105a4f3 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -4885,20 +4885,28 @@ fn jit_obj_respond_to( }; let result = match (visibility, allow_priv) { - (METHOD_VISI_UNDEF, _) => Qfalse, // No method => false - (METHOD_VISI_PUBLIC, _) => Qtrue, // Public method => true regardless of include_all - (_, Some(true)) => Qtrue, // include_all => always true + (METHOD_VISI_UNDEF, _) => { + // No method, we can return false given respond_to_missing? hasn't been overridden. + // In the future, we might want to jit the call to respond_to_missing? + if !assume_method_basic_definition(jit, asm, ocb, recv_class, idRespond_to_missing.into()) { + return false; + } + Qfalse + } + (METHOD_VISI_PUBLIC, _) | // Public method => fine regardless of include_all + (_, Some(true)) => { // include_all => all visibility are acceptable + // Method exists and has acceptable visibility + if cme_def_type == VM_METHOD_TYPE_NOTIMPLEMENTED { + // C method with rb_f_notimplement(). `respond_to?` returns false + // without consulting `respond_to_missing?`. + Qfalse + } else { + Qtrue + } + } (_, _) => return false // not public and include_all not known, can't compile }; - if result != Qtrue { - // Only if respond_to_missing? hasn't been overridden - // In the future, we might want to jit the call to respond_to_missing? - if !assume_method_basic_definition(jit, asm, ocb, recv_class, idRespond_to_missing.into()) { - return false; - } - } - // Invalidate this block if method lookup changes for the method being queried. This works // both for the case where a method does or does not exist, as for the latter we asked for a // "negative CME" earlier. |