use super::{Executor, InstructionPtr};
use crate::{
core::UntypedVal,
engine::utils::unreachable_unchecked,
ir::{AnyConst32, Const32, FixedSlotSpan, Op, Slot, SlotSpan},
};
use core::slice;
impl Executor<'_> {
fn execute_copy_impl<T>(&mut self, result: Slot, value: T, f: fn(&mut Self, T) -> UntypedVal) {
let value = f(self, value);
self.set_stack_slot(result, value);
self.next_instr()
}
pub fn execute_copy(&mut self, result: Slot, value: Slot) {
self.execute_copy_impl(result, value, |this, value| this.get_stack_slot(value))
}
pub fn execute_copy_2(&mut self, results: FixedSlotSpan<2>, values: [Slot; 2]) {
self.execute_copy_2_impl(results, values);
self.next_instr()
}
fn execute_copy_2_impl(&mut self, results: FixedSlotSpan<2>, values: [Slot; 2]) {
let result0 = results.span().head();
let result1 = result0.next();
let tmp = self.get_stack_slot(values[1]);
self.set_stack_slot(result0, self.get_stack_slot(values[0]));
self.set_stack_slot(result1, tmp);
}
pub fn execute_copy_imm32(&mut self, result: Slot, value: AnyConst32) {
self.execute_copy_impl(result, value, |_, value| UntypedVal::from(u32::from(value)))
}
pub fn execute_copy_i64imm32(&mut self, result: Slot, value: Const32<i64>) {
self.execute_copy_impl(result, value, |_, value| UntypedVal::from(i64::from(value)))
}
pub fn execute_copy_f64imm32(&mut self, result: Slot, value: Const32<f64>) {
self.execute_copy_impl(result, value, |_, value| UntypedVal::from(f64::from(value)))
}
pub fn execute_copy_span(&mut self, results: SlotSpan, values: SlotSpan, len: u16) {
self.execute_copy_span_impl(results, values, len);
self.next_instr();
}
pub fn execute_copy_span_impl(&mut self, results: SlotSpan, values: SlotSpan, len: u16) {
let results = results.iter(len);
let values = values.iter(len);
for (result, value) in results.into_iter().zip(values.into_iter()) {
let value = self.get_stack_slot(value);
self.set_stack_slot(result, value);
}
}
pub fn execute_copy_many(&mut self, results: SlotSpan, values: [Slot; 2]) {
self.ip.add(1);
self.ip = self.execute_copy_many_impl(self.ip, results, &values);
self.next_instr()
}
pub fn execute_copy_many_impl(
&mut self,
ip: InstructionPtr,
results: SlotSpan,
values: &[Slot],
) -> InstructionPtr {
let mut ip = ip;
let mut result = results.head();
let mut copy_values = |values: &[Slot]| {
for &value in values {
let value = self.get_stack_slot(value);
self.set_stack_slot(result, value);
result = result.next();
}
};
copy_values(values);
while let Op::SlotList { regs } = ip.get() {
copy_values(regs);
ip.add(1);
}
let values = match ip.get() {
Op::Slot { slot } => slice::from_ref(slot),
Op::Slot2 { slots } => slots,
Op::Slot3 { slots } => slots,
unexpected => {
unsafe {
unreachable_unchecked!("expected slot-list finalizer but found: {unexpected:?}")
}
}
};
copy_values(values);
ip
}
}