ZJIT: Parse opt_empty_p into HIR

This commit is contained in:
Alan Wu 2025-06-06 21:51:05 +09:00
parent 96fdaf2e39
commit 9865aa94f7
Notes: git 2025-06-09 13:37:09 +00:00
2 changed files with 25 additions and 0 deletions

View File

@ -205,6 +205,13 @@ class TestZJIT < Test::Unit::TestCase
}, insns: [:opt_gt], call_threshold: 2
end
def test_opt_empty_p
assert_compiles('[false, false, true]', <<~RUBY, insns: [:opt_empty_p])
def test(x) = x.empty?
return test([1]), test("1"), test({})
RUBY
end
def test_opt_ge
assert_compiles '[false, true, true]', %q{
def test(a, b) = a >= b

View File

@ -2355,6 +2355,10 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
break; // Don't enqueue the next block as a successor
}
// These are opt_send_without_block and all the opt_* instructions
// specialized to a certain method that could also be serviced
// using the general send implementation. The optimizer start from
// a general send for all of these later in the pipeline.
YARVINSN_opt_nil_p |
YARVINSN_opt_plus |
YARVINSN_opt_minus |
@ -2371,6 +2375,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
YARVINSN_opt_length |
YARVINSN_opt_size |
YARVINSN_opt_aref |
YARVINSN_opt_empty_p |
YARVINSN_opt_send_without_block => {
let cd: *const rb_call_data = get_arg(pc, 0).as_ptr();
let call_info = unsafe { rb_get_call_data_ci(cd) };
@ -3806,6 +3811,19 @@ mod tests {
"#]]);
}
#[test]
fn opt_empty_p() {
eval("
def test(x) = x.empty?
");
assert_method_hir_with_opcode("test", YARVINSN_opt_empty_p, expect![[r#"
fn test:
bb0(v0:BasicObject, v1:BasicObject):
v4:BasicObject = SendWithoutBlock v1, :empty?
Return v4
"#]]);
}
#[test]
fn test_branchnil() {
eval("