summaryrefslogtreecommitdiff
path: root/zjit
diff options
context:
space:
mode:
authorB6 <52599949+a5-stable@users.noreply.github.com>2026-05-19 02:01:05 +0900
committerGitHub <noreply@github.com>2026-05-18 13:01:05 -0400
commit4351ee9652611b12051ad07f8de7b47f7b35927f (patch)
treedc9250fa45652a56b85a0c78040a69a6eeb5b460 /zjit
parent871177408bfbeb1561641d761f0e92ddd1875130 (diff)
ZJIT: StringExact/NilClass for GetSpecialSymbol and GetSpecialNumber (#17012)
According to `rb_reg_nth_match`, `rb_reg_match_pre(post/last)`, `GetSpecialSymbol` and `GetSpecialNumber` always returns `StringExact` or `NilClass`. Fix `infer_type` to `StringExact|NilClass` instead of `BasicObject`.
Diffstat (limited to 'zjit')
-rw-r--r--zjit/src/hir.rs4
-rw-r--r--zjit/src/hir/tests.rs60
2 files changed, 62 insertions, 2 deletions
diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs
index e350387dc2..e5976a4045 100644
--- a/zjit/src/hir.rs
+++ b/zjit/src/hir.rs
@@ -2998,8 +2998,8 @@ impl Function {
Insn::GetEP { .. } => types::CPtr,
Insn::LoadSelf => types::BasicObject,
&Insn::LoadField { return_type, .. } => return_type,
- Insn::GetSpecialSymbol { .. } => types::BasicObject,
- Insn::GetSpecialNumber { .. } => types::BasicObject,
+ Insn::GetSpecialSymbol { .. } => types::StringExact.union(types::NilClass),
+ Insn::GetSpecialNumber { .. } => types::StringExact.union(types::NilClass),
Insn::GetClassVar { .. } => types::BasicObject,
Insn::ToNewArray { .. } => types::ArrayExact,
Insn::ToArray { .. } => types::ArrayExact,
diff --git a/zjit/src/hir/tests.rs b/zjit/src/hir/tests.rs
index 7466d4bb1a..566cf7aeb7 100644
--- a/zjit/src/hir/tests.rs
+++ b/zjit/src/hir/tests.rs
@@ -5525,6 +5525,66 @@ pub(crate) mod hir_build_tests {
assert!(hir.contains("BreakPoint"));
assert!(hir.contains("Return v"));
}
+
+ #[test]
+ fn test_getspecialnumber() {
+ eval("
+ def test(a)
+ a =~/(hello)/
+ $1
+ end
+ ");
+ assert_snapshot!(hir_string("test"), @"
+ fn test@<compiled>:3:
+ bb1():
+ EntryPoint interpreter
+ v1:BasicObject = LoadSelf
+ v2:CPtr = LoadSP
+ v3:BasicObject = LoadField v2, :a@0x1000
+ Jump bb3(v1, v3)
+ bb2():
+ EntryPoint JIT(0)
+ v6:BasicObject = LoadArg :self@0
+ v7:BasicObject = LoadArg :a@1
+ Jump bb3(v6, v7)
+ bb3(v9:BasicObject, v10:BasicObject):
+ v15:RegexpExact[VALUE(0x1008)] = Const Value(VALUE(0x1008))
+ v18:BasicObject = Send v10, :=~, v15 # SendFallbackReason: Uncategorized(opt_regexpmatch2)
+ v22:StringExact|NilClass = GetSpecialNumber 2
+ CheckInterrupts
+ Return v22
+ ");
+ }
+
+ #[test]
+ fn test_getspecialsymbol() {
+ eval("
+ def test(a)
+ a =~/(hello)/
+ $&
+ end
+ ");
+ assert_snapshot!(hir_string("test"), @"
+ fn test@<compiled>:3:
+ bb1():
+ EntryPoint interpreter
+ v1:BasicObject = LoadSelf
+ v2:CPtr = LoadSP
+ v3:BasicObject = LoadField v2, :a@0x1000
+ Jump bb3(v1, v3)
+ bb2():
+ EntryPoint JIT(0)
+ v6:BasicObject = LoadArg :self@0
+ v7:BasicObject = LoadArg :a@1
+ Jump bb3(v6, v7)
+ bb3(v9:BasicObject, v10:BasicObject):
+ v15:RegexpExact[VALUE(0x1008)] = Const Value(VALUE(0x1008))
+ v18:BasicObject = Send v10, :=~, v15 # SendFallbackReason: Uncategorized(opt_regexpmatch2)
+ v22:StringExact|NilClass = GetSpecialSymbol LastMatch
+ CheckInterrupts
+ Return v22
+ ");
+ }
}
/// Test successor and predecessor set computations.