diff options
| author | Takashi Kokubun <takashikkbn@gmail.com> | 2026-03-27 13:23:03 -0700 |
|---|---|---|
| committer | Takashi Kokubun <takashikkbn@gmail.com> | 2026-03-27 15:33:51 -0700 |
| commit | 16e96105a75d455e9f6666ff63bf854e6ccb619d (patch) | |
| tree | 57ba2a8465f4a62f9bf3f45eac39427297c99e01 /zjit | |
| parent | 6519a7749631538a74b63e182be9a171c1afdc84 (diff) | |
ZJIT: Add tests for invokeblock IFUNC specialization
Test Enumerable#map on a class with a Ruby `each` that uses `yield`.
This exercises the IFUNC block handler path in invokeblock, where
Enumerable C code creates an IFUNC wrapping the user's block.
Diffstat (limited to 'zjit')
| -rw-r--r-- | zjit/src/codegen_tests.rs | 17 | ||||
| -rw-r--r-- | zjit/src/hir/opt_tests.rs | 40 |
2 files changed, 57 insertions, 0 deletions
diff --git a/zjit/src/codegen_tests.rs b/zjit/src/codegen_tests.rs index 3a21b001cd..db94a32036 100644 --- a/zjit/src/codegen_tests.rs +++ b/zjit/src/codegen_tests.rs @@ -4701,6 +4701,23 @@ fn test_invokeblock_multiple_yields() { } #[test] +fn test_invokeblock_ifunc_map() { + eval(" + class MyList + include Enumerable + def each + yield 1 + yield 2 + yield 3 + end + end + def test = MyList.new.map { |x| x * 2 } + test + "); + assert_snapshot!(assert_compiles("test"), @"[2, 4, 6]"); +} + +#[test] fn test_ccall_variadic_with_multiple_args() { eval(" def test diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index 40d126d56f..315467ca72 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -15075,4 +15075,44 @@ mod hir_opt_tests { Return v36 "); } + + #[test] + fn test_invokeblock_ifunc() { + eval(" + class IFuncTestList + include Enumerable + def each + yield 1 + yield 2 + end + end + IFuncTestList.new.map { |x| x } + "); + assert_snapshot!(hir_string_proc("IFuncTestList.instance_method(:each)"), @" + fn each@<compiled>:5: + bb1(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + Jump bb3(v1) + bb2(): + EntryPoint JIT(0) + v4:BasicObject = LoadArg :self@0 + Jump bb3(v4) + bb3(v6:BasicObject): + v10:Fixnum[1] = Const Value(1) + v12:CPtr = GetEP 0 + v13:CInt64 = LoadField v12, :_env_data_index_specval@0x1000 + v14:CInt64 = GuardAnyBitSet v13, CUInt64(1) + v15:CInt64 = GuardAnyBitSet v13, CUInt64(2) + v16:BasicObject = InvokeBlockIfunc v13, v10 + v20:Fixnum[2] = Const Value(2) + v22:CPtr = GetEP 0 + v23:CInt64 = LoadField v22, :_env_data_index_specval@0x1000 + v24:CInt64 = GuardAnyBitSet v23, CUInt64(1) + v25:CInt64 = GuardAnyBitSet v23, CUInt64(2) + v26:BasicObject = InvokeBlockIfunc v23, v20 + CheckInterrupts + Return v26 + "); + } } |
