Skip to content

Commit 0c2f54e

Browse files
committed
Add stack_popn helper
1 parent 8eb26eb commit 0c2f54e

1 file changed

Lines changed: 25 additions & 33 deletions

File tree

zjit/src/hir.rs

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,6 +2468,22 @@ impl FrameState {
24682468
self.stack.pop().ok_or_else(|| ParseError::StackUnderflow(self.clone()))
24692469
}
24702470

2471+
/// Return a vec of the top n stack operands, in the same order as they were on the stack.
2472+
fn stack_popn(&mut self, n: usize) -> Result<Vec<InsnId>, ParseError> {
2473+
let mut elements = Vec::with_capacity(n);
2474+
self.stack_popn_into(n, &mut elements)?;
2475+
Ok(elements)
2476+
}
2477+
2478+
fn stack_popn_into(&mut self, n: usize, destination: &mut Vec<InsnId>) -> Result<(), ParseError> {
2479+
unsafe { // Unsafely set the length, so we don't have to initialize the slots we're about to overwrite.
2480+
elements.set_len(n);
2481+
for i in (0..n).rev() { // Fill in reverse order, so we preserve the order of the stack.
2482+
elements[i] = self.stack_pop()?;
2483+
}
2484+
}
2485+
}
2486+
24712487
/// Get a stack-top operand
24722488
fn stack_top(&self) -> Result<InsnId, ParseError> {
24732489
self.stack.last().ok_or_else(|| ParseError::StackUnderflow(self.clone())).copied()
@@ -2787,21 +2803,13 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
27872803
YARVINSN_newarray => {
27882804
let count = get_arg(pc, 0).as_usize();
27892805
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
2790-
let mut elements = vec![];
2791-
for _ in 0..count {
2792-
elements.push(state.stack_pop()?);
2793-
}
2794-
elements.reverse();
2806+
let elements = state.stack_popn(count)?;
27952807
state.stack_push(fun.push_insn(block, Insn::NewArray { elements, state: exit_id }));
27962808
}
27972809
YARVINSN_opt_newarray_send => {
27982810
let count = get_arg(pc, 0).as_usize();
27992811
let method = get_arg(pc, 1).as_u32();
2800-
let mut elements = vec![];
2801-
for _ in 0..count {
2802-
elements.push(state.stack_pop()?);
2803-
}
2804-
elements.reverse();
2812+
let elements = state.stack_popn(count)?;
28052813
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
28062814
let (bop, insn) = match method {
28072815
VM_OPT_NEWARRAY_SEND_MAX => (BOP_MAX, Insn::ArrayMax { elements, state: exit_id }),
@@ -3074,11 +3082,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
30743082
}
30753083
let argc = unsafe { vm_ci_argc((*cd).ci) };
30763084

3077-
let mut args = vec![];
3078-
for _ in 0..argc {
3079-
args.push(state.stack_pop()?);
3080-
}
3081-
args.reverse();
3085+
let args = state.stack_popn(argc)?;
30823086

30833087
let recv = state.stack_pop()?;
30843088
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
@@ -3153,13 +3157,9 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
31533157
fun.push_insn(block, Insn::SideExit { state: exit_id, reason: SideExitReason::UnknownCallType });
31543158
break; // End the block
31553159
}
3156-
let argc = unsafe { vm_ci_argc((*cd).ci) };
31573160

3158-
let mut args = vec![];
3159-
for _ in 0..argc {
3160-
args.push(state.stack_pop()?);
3161-
}
3162-
args.reverse();
3161+
let argc = unsafe { vm_ci_argc((*cd).ci) };
3162+
let args = state.stack_popn(argc)?;
31633163

31643164
let recv = state.stack_pop()?;
31653165
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
@@ -3176,13 +3176,9 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
31763176
fun.push_insn(block, Insn::SideExit { state: exit_id, reason: SideExitReason::UnknownCallType });
31773177
break; // End the block
31783178
}
3179-
let argc = unsafe { vm_ci_argc((*cd).ci) };
31803179

3181-
let mut args = vec![];
3182-
for _ in 0..argc {
3183-
args.push(state.stack_pop()?);
3184-
}
3185-
args.reverse();
3180+
let argc = unsafe { vm_ci_argc((*cd).ci) };
3181+
let args = state.stack_popn(argc)?;
31863182

31873183
let recv = state.stack_pop()?;
31883184
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
@@ -3236,12 +3232,8 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
32363232
YARVINSN_invokebuiltin => {
32373233
let bf: rb_builtin_function = unsafe { *get_arg(pc, 0).as_ptr() };
32383234

3239-
let mut args = vec![];
3240-
for _ in 0..bf.argc {
3241-
args.push(state.stack_pop()?);
3242-
}
3243-
args.push(self_param);
3244-
args.reverse();
3235+
let mut args = vec![self_param];
3236+
state.stack_popn_into(bf.argc as usize, &mut args)?;
32453237

32463238
let exit_id = fun.push_insn(block, Insn::Snapshot { state: exit_state });
32473239

0 commit comments

Comments
 (0)