summaryrefslogtreecommitdiff
path: root/yjit
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2023-08-17 16:18:12 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2023-08-17 17:14:46 -0400
commit9683eb06cf91664cfe18f61677b2624fbaf8e3b0 (patch)
tree76fdc6295ba7ea58bcbde69331b8a814e89c7cee /yjit
parent57ec167306672960ce4c65586a96752ad43461c7 (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.rs30
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.