diff options
| author | Max Bernstein <rubybugs@bernsteinbear.com> | 2025-10-30 13:30:08 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-30 17:30:08 +0000 |
| commit | 57f76f62d5e12766465f11ebb0d0b0b0d4d549ce (patch) | |
| tree | d0df05c96daa9a2cc79d18ad4a88c5bd232e5626 | |
| parent | 481f994449f35ce4050757561e89a776903ee425 (diff) | |
ZJIT: Fix incorrect self.class.respond_to? folding (#15001)
Right now we have a subtle type system bug around `types::Class`. Until
that is resolved, stop marking `Kernel#class` as returning
`types::Class`, which fixes Rubocop.
Re: https://github.com/Shopify/ruby/issues/850
| -rw-r--r-- | zjit/src/cruby_methods.rs | 4 | ||||
| -rw-r--r-- | zjit/src/hir/opt_tests.rs | 86 | ||||
| -rw-r--r-- | zjit/src/hir/tests.rs | 4 |
3 files changed, 90 insertions, 4 deletions
diff --git a/zjit/src/cruby_methods.rs b/zjit/src/cruby_methods.rs index 12d226ce51..bd3409ff07 100644 --- a/zjit/src/cruby_methods.rs +++ b/zjit/src/cruby_methods.rs @@ -231,7 +231,9 @@ pub fn init() -> Annotations { annotate_builtin!(rb_mKernel, "Float", types::Float); annotate_builtin!(rb_mKernel, "Integer", types::Integer); - annotate_builtin!(rb_mKernel, "class", types::Class, leaf); + // TODO(max): Annotate rb_mKernel#class as returning types::Class. Right now there is a subtle + // type system bug that causes an issue if we make it return types::Class. + annotate_builtin!(rb_mKernel, "class", types::HeapObject, leaf); annotate_builtin!(rb_mKernel, "frozen?", types::BoolExact); annotate_builtin!(rb_cSymbol, "name", types::StringExact); annotate_builtin!(rb_cSymbol, "to_s", types::StringExact); diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index c7764bd290..d697065da9 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -2358,7 +2358,7 @@ mod hir_opt_tests { PatchPoint MethodRedefined(Module@0x1010, class@0x1018, cme:0x1020) PatchPoint NoSingletonClass(Module@0x1010) IncrCounter inline_iseq_optimized_send_count - v26:Class = InvokeBuiltin leaf _bi20, v21 + v26:HeapObject = InvokeBuiltin leaf _bi20, v21 CheckInterrupts Return v26 "); @@ -7050,4 +7050,88 @@ mod hir_opt_tests { Return v19 "); } + + #[test] + fn test_fold_self_class_respond_to_true() { + eval(r#" + class C + class << self + attr_accessor :_lex_actions + private :_lex_actions, :_lex_actions= + end + self._lex_actions = [1, 2, 3] + def initialize + if self.class.respond_to?(:_lex_actions, true) + :CORRECT + else + :oh_no_wrong + end + end + end + C.new # warm up + TEST = C.instance_method(:initialize) + "#); + assert_snapshot!(hir_string_proc("TEST"), @r" + fn initialize@<compiled>:9: + bb0(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + Jump bb2(v1) + bb1(v4:BasicObject): + EntryPoint JIT(0) + Jump bb2(v4) + bb2(v6:BasicObject): + PatchPoint MethodRedefined(C@0x1000, class@0x1008, cme:0x1010) + PatchPoint NoSingletonClass(C@0x1000) + v40:HeapObject[class_exact:C] = GuardType v6, HeapObject[class_exact:C] + IncrCounter inline_iseq_optimized_send_count + v43:HeapObject = InvokeBuiltin leaf _bi20, v40 + v12:StaticSymbol[:_lex_actions] = Const Value(VALUE(0x1038)) + v13:TrueClass = Const Value(true) + PatchPoint MethodRedefined(Class@0x1040, respond_to?@0x1048, cme:0x1050) + PatchPoint NoSingletonClass(Class@0x1040) + v47:ModuleSubclass[class_exact*:Class@VALUE(0x1040)] = GuardType v43, ModuleSubclass[class_exact*:Class@VALUE(0x1040)] + PatchPoint MethodRedefined(Class@0x1040, _lex_actions@0x1078, cme:0x1080) + PatchPoint NoSingletonClass(Class@0x1040) + v51:TrueClass = Const Value(true) + IncrCounter inline_cfunc_optimized_send_count + CheckInterrupts + v22:StaticSymbol[:CORRECT] = Const Value(VALUE(0x10a8)) + CheckInterrupts + Return v22 + "); + } + + #[test] + fn test_fold_self_class_name() { + eval(r#" + class C; end + def test(o) = o.class.name + test(C.new) + "#); + assert_snapshot!(hir_string("test"), @r" + fn test@<compiled>:3: + bb0(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + v2:BasicObject = GetLocal l0, SP@4 + Jump bb2(v1, v2) + bb1(v5:BasicObject, v6:BasicObject): + EntryPoint JIT(0) + Jump bb2(v5, v6) + bb2(v8:BasicObject, v9:BasicObject): + PatchPoint MethodRedefined(C@0x1000, class@0x1008, cme:0x1010) + PatchPoint NoSingletonClass(C@0x1000) + v24:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] + IncrCounter inline_iseq_optimized_send_count + v27:HeapObject = InvokeBuiltin leaf _bi20, v24 + PatchPoint MethodRedefined(Class@0x1038, name@0x1040, cme:0x1048) + PatchPoint NoSingletonClass(Class@0x1038) + v31:ModuleSubclass[class_exact*:Class@VALUE(0x1038)] = GuardType v27, ModuleSubclass[class_exact*:Class@VALUE(0x1038)] + IncrCounter inline_cfunc_optimized_send_count + v33:StringExact|NilClass = CCall name@0x1070, v31 + CheckInterrupts + Return v33 + "); + } } diff --git a/zjit/src/hir/tests.rs b/zjit/src/hir/tests.rs index df14ba5a7c..32c71dc5d3 100644 --- a/zjit/src/hir/tests.rs +++ b/zjit/src/hir/tests.rs @@ -2712,9 +2712,9 @@ pub mod hir_build_tests { EntryPoint JIT(0) Jump bb2(v4) bb2(v6:BasicObject): - v11:Class = InvokeBuiltin leaf _bi20, v6 + v11:HeapObject = InvokeBuiltin leaf _bi20, v6 Jump bb3(v6, v11) - bb3(v13:BasicObject, v14:Class): + bb3(v13:BasicObject, v14:HeapObject): CheckInterrupts Return v14 "); |
