diff options
| author | Nozomi Hijikata <121233810+nozomemein@users.noreply.github.com> | 2026-01-23 14:01:26 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-23 00:01:26 -0500 |
| commit | 5c5832706577219cef99f735735c7aac102e8a09 (patch) | |
| tree | f0cb2a09bc47be935085a44326765d45bff4be25 | |
| parent | f5ae56c8a28c3cfac94556aff8f3828e9236c610 (diff) | |
ZJIT: Resolve alias in reduce_send_to_ccall (#15947)
Just minor fix to resolve aliases in `reduce_send_to_ccall`.
| -rw-r--r-- | zjit/src/hir.rs | 9 | ||||
| -rw-r--r-- | zjit/src/hir/opt_tests.rs | 32 |
2 files changed, 38 insertions, 3 deletions
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 18649b9800..2aa74dce8b 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -3782,15 +3782,18 @@ impl Function { }; // Do method lookup - let cme: *const rb_callable_method_entry_struct = unsafe { rb_callable_method_entry(recv_class, method_id) }; + let mut cme: *const rb_callable_method_entry_struct = unsafe { rb_callable_method_entry(recv_class, method_id) }; if cme.is_null() { fun.set_dynamic_send_reason(send_insn_id, SendNotOptimizedMethodType(MethodType::Null)); return Err(()); } // Filter for C methods - // TODO(max): Handle VM_METHOD_TYPE_ALIAS - let def_type = unsafe { get_cme_def_type(cme) }; + let mut def_type = unsafe { get_cme_def_type(cme) }; + while def_type == VM_METHOD_TYPE_ALIAS { + cme = unsafe { rb_aliased_callable_method_entry(cme) }; + def_type = unsafe { get_cme_def_type(cme) }; + } if def_type != VM_METHOD_TYPE_CFUNC { return Err(()); } diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index dcfcc1e136..0110af3f2c 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -832,6 +832,38 @@ mod hir_opt_tests { } #[test] + fn test_optimize_send_to_aliased_cfunc_from_module() { + eval(" + class C + include Enumerable + def each; yield 1; end + alias bar map + end + def test(o) = o.bar { |x| x } + test C.new; test C.new + "); + assert_snapshot!(hir_string("test"), @r" + fn test@<compiled>:7: + bb0(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + v2:BasicObject = GetLocal :o, 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 NoSingletonClass(C@0x1000) + PatchPoint MethodRedefined(C@0x1000, bar@0x1008, cme:0x1010) + v23:HeapObject[class_exact:C] = GuardType v9, HeapObject[class_exact:C] + v24:BasicObject = CCallWithFrame v23, :Enumerable#bar@0x1038, block=0x1040 + v15:BasicObject = GetLocal :o, l0, EP@3 + CheckInterrupts + Return v24 + "); + } + + #[test] fn test_optimize_nonexistent_top_level_call() { eval(" def foo |
