From: Max Bernstein Date: Fri, 2 May 2025 21:11:52 +0000 (-0400) Subject: Parse topn, opt_length, opt_size into HIR X-Git-Url: https://repo.or.cz/ruby.git/commitdiff_plain/925da368763487c495f47c9e7f17a252ff38a105 Parse topn, opt_length, opt_size into HIR --- diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index da56738231..72cd855bba 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -1573,6 +1573,12 @@ impl FrameState { self.stack[idx] = opnd; } + /// Get a stack operand at idx + fn stack_topn(&mut self, idx: usize) -> Result { + let idx = self.stack.len() - idx - 1; + self.stack.get(idx).ok_or_else(|| ParseError::StackUnderflow(self.clone())).copied() + } + fn setlocal(&mut self, ep_offset: u32, opnd: InsnId) { let idx = ep_offset_to_local_idx(self.iseq, ep_offset); self.locals[idx] = opnd; @@ -1896,6 +1902,11 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { let top = state.stack_top()?; state.stack_setn(n, top); } + YARVINSN_topn => { + let n = get_arg(pc, 0).as_usize(); + let top = state.stack_topn(n)?; + state.stack_push(top); + } YARVINSN_adjuststack => { let mut n = get_arg(pc, 0).as_usize(); while n > 0 { @@ -1946,6 +1957,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result { YARVINSN_opt_ge | YARVINSN_opt_ltlt | YARVINSN_opt_aset | + YARVINSN_opt_length | + YARVINSN_opt_size | 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) }; @@ -2907,6 +2920,34 @@ mod tests { Return v5 "#]]); } + + #[test] + fn test_opt_length() { + eval(" + def test(a,b) = [a,b].length + "); + assert_method_hir("test", expect![[r#" + fn test: + bb0(v0:BasicObject, v1:BasicObject): + v4:ArrayExact = NewArray v0, v1 + v6:BasicObject = SendWithoutBlock v4, :length + Return v6 + "#]]); + } + + #[test] + fn test_opt_size() { + eval(" + def test(a,b) = [a,b].size + "); + assert_method_hir("test", expect![[r#" + fn test: + bb0(v0:BasicObject, v1:BasicObject): + v4:ArrayExact = NewArray v0, v1 + v6:BasicObject = SendWithoutBlock v4, :size + Return v6 + "#]]); + } } #[cfg(test)] @@ -3850,4 +3891,32 @@ mod opt_tests { Return v12 "#]]); } + + #[test] + fn test_opt_length() { + eval(" + def test(a,b) = [a,b].length + "); + assert_optimized_method_hir("test", expect![[r#" + fn test: + bb0(v0:BasicObject, v1:BasicObject): + v4:ArrayExact = NewArray v0, v1 + v6:BasicObject = SendWithoutBlock v4, :length + Return v6 + "#]]); + } + + #[test] + fn test_opt_size() { + eval(" + def test(a,b) = [a,b].size + "); + assert_optimized_method_hir("test", expect![[r#" + fn test: + bb0(v0:BasicObject, v1:BasicObject): + v4:ArrayExact = NewArray v0, v1 + v6:BasicObject = SendWithoutBlock v4, :size + Return v6 + "#]]); + } }