summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNozomi Hijikata <121233810+nozomemein@users.noreply.github.com>2026-01-23 14:01:26 +0900
committerGitHub <noreply@github.com>2026-01-23 00:01:26 -0500
commit5c5832706577219cef99f735735c7aac102e8a09 (patch)
treef0cb2a09bc47be935085a44326765d45bff4be25
parentf5ae56c8a28c3cfac94556aff8f3828e9236c610 (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.rs9
-rw-r--r--zjit/src/hir/opt_tests.rs32
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