Skip to content

Commit 45fedc3

Browse files
st0012amomchilov
andcommitted
ZJIT: Add stack_pop_n to FrameState
Co-authored-by: Alexander Momchilov <alexander.momchilov@shopify.com>
1 parent f986b25 commit 45fedc3

1 file changed

Lines changed: 18 additions & 41 deletions

File tree

zjit/src/hir.rs

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2486,6 +2486,16 @@ impl FrameState {
24862486
self.stack.pop().ok_or_else(|| ParseError::StackUnderflow(self.clone()))
24872487
}
24882488

2489+
fn stack_pop_n(&mut self, count: usize) -> Result<Vec<InsnId>, ParseError> {
2490+
// Check if we have enough values on the stack
2491+
let stack_len = self.stack.len();
2492+
if stack_len < count {
2493+
return Err(ParseError::StackUnderflow(self.clone()));
2494+
}
2495+
2496+
Ok(self.stack.split_off(stack_len - count))
2497+
}
2498+
24892499
/// Get a stack-top operand
24902500
fn stack_top(&self) -> Result<InsnId, ParseError> {
24912501
self.stack.last().ok_or_else(|| ParseError::StackUnderflow(self.clone())).copied()
@@ -2809,35 +2819,20 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
28092819
YARVINSN_concatstrings => {
28102820
let count = get_arg(pc, 0).as_u32();
28112821
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
2812-
// TODO: Pre-initialize the vector with the correct capacity
2813-
// TODO: Fill the vector in the order without needing reversing
2814-
// Create an issue for this
2815-
let mut strings = vec![];
2816-
for _ in 0..count {
2817-
strings.push(state.stack_pop()?);
2818-
}
2819-
strings.reverse();
2822+
let strings = state.stack_pop_n(count as usize)?;
28202823
let insn_id = fun.push_insn(block, Insn::StringConcat { strings, state: exit_id });
28212824
state.stack_push(insn_id);
28222825
}
28232826
YARVINSN_newarray => {
28242827
let count = get_arg(pc, 0).as_usize();
28252828
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
2826-
let mut elements = vec![];
2827-
for _ in 0..count {
2828-
elements.push(state.stack_pop()?);
2829-
}
2830-
elements.reverse();
2829+
let elements = state.stack_pop_n(count)?;
28312830
state.stack_push(fun.push_insn(block, Insn::NewArray { elements, state: exit_id }));
28322831
}
28332832
YARVINSN_opt_newarray_send => {
28342833
let count = get_arg(pc, 0).as_usize();
28352834
let method = get_arg(pc, 1).as_u32();
2836-
let mut elements = vec![];
2837-
for _ in 0..count {
2838-
elements.push(state.stack_pop()?);
2839-
}
2840-
elements.reverse();
2835+
let elements = state.stack_pop_n(count)?;
28412836
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
28422837
let (bop, insn) = match method {
28432838
VM_OPT_NEWARRAY_SEND_MAX => (BOP_MAX, Insn::ArrayMax { elements, state: exit_id }),
@@ -2902,13 +2897,10 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
29022897
}
29032898
YARVINSN_pushtoarray => {
29042899
let count = get_arg(pc, 0).as_usize();
2905-
let mut vals = vec![];
2906-
for _ in 0..count {
2907-
vals.push(state.stack_pop()?);
2908-
}
2900+
let vals = state.stack_pop_n(count)?;
29092901
let array = state.stack_pop()?;
29102902
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
2911-
for val in vals.into_iter().rev() {
2903+
for val in vals.into_iter() {
29122904
fun.push_insn(block, Insn::ArrayPush { array, val, state: exit_id });
29132905
}
29142906
state.stack_push(array);
@@ -3110,12 +3102,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
31103102
}
31113103
let argc = unsafe { vm_ci_argc((*cd).ci) };
31123104

3113-
let mut args = vec![];
3114-
for _ in 0..argc {
3115-
args.push(state.stack_pop()?);
3116-
}
3117-
args.reverse();
3118-
3105+
let args = state.stack_pop_n(argc as usize)?;
31193106
let recv = state.stack_pop()?;
31203107
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
31213108
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, cd, args, state: exit_id });
@@ -3191,12 +3178,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
31913178
}
31923179
let argc = unsafe { vm_ci_argc((*cd).ci) };
31933180

3194-
let mut args = vec![];
3195-
for _ in 0..argc {
3196-
args.push(state.stack_pop()?);
3197-
}
3198-
args.reverse();
3199-
3181+
let args = state.stack_pop_n(argc as usize)?;
32003182
let recv = state.stack_pop()?;
32013183
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
32023184
let send = fun.push_insn(block, Insn::SendWithoutBlock { self_val: recv, cd, args, state: exit_id });
@@ -3214,12 +3196,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
32143196
}
32153197
let argc = unsafe { vm_ci_argc((*cd).ci) };
32163198

3217-
let mut args = vec![];
3218-
for _ in 0..argc {
3219-
args.push(state.stack_pop()?);
3220-
}
3221-
args.reverse();
3222-
3199+
let args = state.stack_pop_n(argc as usize)?;
32233200
let recv = state.stack_pop()?;
32243201
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
32253202
let send = fun.push_insn(block, Insn::Send { self_val: recv, cd, blockiseq, args, state: exit_id });

0 commit comments

Comments
 (0)