use std::collections::HashMap;
use std::sync::Mutex;
use crate::bitvector::BV;
use crate::config::ISAConfig;
use crate::executor::{start_single, LocalFrame, TaskState};
use crate::ir::*;
use crate::log;
use crate::zencode;
fn initialize_letbindings<'ir, B: BV>(
arch: &'ir [Def<Name, B>],
shared_state: &SharedState<'ir, B>,
regs: &Bindings<'ir, B>,
letbindings: &Mutex<Bindings<'ir, B>>,
) {
for def in arch.iter() {
if let Def::Let(bindings, setup) = def {
let vars: Vec<_> = bindings.iter().map(|(id, ty)| (*id, ty)).collect();
let task_state = TaskState::new();
let task = {
let lets = letbindings.lock().unwrap();
LocalFrame::new(TOP_LEVEL_LET, &vars, None, setup).add_regs(®s).add_lets(&lets).task(0, &task_state)
};
start_single(
task,
&shared_state,
&letbindings,
&move |_tid, _task_id, result, shared_state, _solver, letbindings| match result {
Ok((_, frame)) => {
for (id, _) in bindings.iter() {
let symbol = zencode::decode(shared_state.symtab.to_str(*id));
match frame.vars().get(id) {
Some(value) => {
let mut state = letbindings.lock().unwrap();
state.insert(*id, value.clone());
let symbol = zencode::decode(shared_state.symtab.to_str(*id));
log!(log::VERBOSE, &format!("{} = {:?}", symbol, value));
}
None => log!(log::VERBOSE, &format!("No value for symbol {}", symbol)),
}
}
}
Err(err) => log!(log::VERBOSE, &format!("Failed to evaluate letbinding: {:?}", err)),
},
);
}
}
}
fn initialize_register_state<'ir, B: BV>(
defs: &'ir [Def<Name, B>],
initial_registers: &HashMap<Name, Val<B>>,
symtab: &Symtab,
) -> Bindings<'ir, B> {
let mut registers = HashMap::new();
for def in defs.iter() {
if let Def::Register(id, ty) = def {
if let Some(value) = initial_registers.get(id) {
value.plausible(ty, symtab).unwrap_or_else(|_| panic!("Bad initial value for {}", symtab.to_str(*id)));
registers.insert(*id, UVal::Init(value.clone()));
} else {
registers.insert(*id, UVal::Uninit(ty));
}
}
}
registers
}
pub struct Initialized<'ir, B> {
pub regs: Bindings<'ir, B>,
pub lets: Bindings<'ir, B>,
pub shared_state: SharedState<'ir, B>,
}
pub fn initialize_architecture<'ir, B: BV>(
arch: &'ir mut [Def<Name, B>],
symtab: Symtab<'ir>,
isa_config: &ISAConfig<B>,
mode: AssertionMode,
) -> Initialized<'ir, B> {
insert_monomorphize(arch);
insert_primops(arch, mode);
let regs = initialize_register_state(arch, &isa_config.default_registers, &symtab);
let lets = Mutex::new(HashMap::new());
let shared_state = SharedState::new(symtab, arch, isa_config.probes.clone(), isa_config.reset_registers.clone());
initialize_letbindings(arch, &shared_state, ®s, &lets);
Initialized { regs, lets: lets.into_inner().unwrap(), shared_state }
}