use std::collections::{BTreeMap, BTreeSet};
use crate::instruction::{Instruction, OpCode};
use super::super::HighLevelEmitter;
impl HighLevelEmitter {
pub(crate) fn with_program(instructions: &[Instruction]) -> Self {
let mut emitter = Self {
program: instructions.to_vec(),
emit_trace_comments: true,
..Self::default()
};
for (index, instruction) in instructions.iter().enumerate() {
emitter.index_by_offset.insert(instruction.offset, index);
}
emitter.analyze_do_while_loops();
emitter.pre_register_backward_jump_labels();
emitter
}
pub(crate) fn set_argument_labels(&mut self, labels: &[String]) {
for (index, label) in labels.iter().enumerate() {
self.argument_labels.insert(index, label.clone());
}
let starts_with_initslot = self
.program
.first()
.is_some_and(|instruction| instruction.opcode == OpCode::Initslot);
if !starts_with_initslot {
self.stack.extend(labels.iter().rev().cloned());
}
}
pub(crate) fn set_callt_labels(&mut self, labels: Vec<String>) {
self.callt_labels = labels;
}
pub(crate) fn set_callt_param_counts(&mut self, counts: Vec<usize>) {
self.callt_param_counts = counts;
}
pub(crate) fn set_callt_returns_value(&mut self, returns: Vec<bool>) {
self.callt_returns_value = returns;
}
pub(crate) fn set_method_labels_by_offset(&mut self, labels: &BTreeMap<usize, String>) {
self.method_labels_by_offset = labels.clone();
}
pub(crate) fn set_method_arg_counts_by_offset(&mut self, counts: &BTreeMap<usize, usize>) {
self.method_arg_counts_by_offset = counts.clone();
}
pub(crate) fn set_call_targets_by_offset(&mut self, targets: &BTreeMap<usize, usize>) {
self.call_targets_by_offset = targets.clone();
}
pub(crate) fn set_calla_targets_by_offset(&mut self, targets: &BTreeMap<usize, usize>) {
self.calla_targets_by_offset = targets.clone();
}
pub(crate) fn set_noreturn_method_offsets(&mut self, offsets: &BTreeSet<usize>) {
self.noreturn_method_offsets = offsets.clone();
}
pub(crate) fn set_inline_single_use_temps(&mut self, enabled: bool) {
self.inline_single_use_temps = enabled;
}
pub(crate) fn set_emit_trace_comments(&mut self, enabled: bool) {
self.emit_trace_comments = enabled;
}
pub(crate) fn set_returns_void(&mut self, value: bool) {
self.returns_void = value;
}
}