forked from MightyPork/crsn
parent
d489b214e0
commit
8222efe6da
@ -0,0 +1,126 @@ |
||||
use std::any::{Any, TypeId}; |
||||
use std::collections::HashMap; |
||||
|
||||
use crate::asm::data::{DstDisp, Rd, Register, SrcDisp, Wr}; |
||||
use crate::asm::data::literal::{Addr, Value}; |
||||
use crate::asm::instr::op::EvalRes; |
||||
use crate::runtime::fault::Fault; |
||||
use crate::runtime::frame::{CallStack, REG_COUNT, StackFrame}; |
||||
use crate::runtime::program::Program; |
||||
use crate::asm::instr::Cond; |
||||
use crate::runtime::frame::status::StatusFlags; |
||||
|
||||
pub struct RunState { |
||||
/// Active stack frame
|
||||
pub frame: StackFrame, |
||||
/// Call stack
|
||||
pub call_stack: CallStack, |
||||
/// Extension data
|
||||
pub ext_data: HashMap<TypeId, Box<dyn Any + Send>>, |
||||
} |
||||
|
||||
impl RunState { |
||||
pub fn ext_mut<T: Send + Default + 'static>(&mut self) -> &mut T { |
||||
if !self.ext_data.contains_key(&TypeId::of::<T>()) { |
||||
self.ext_data.insert(TypeId::of::<T>(), Box::new(T::default())); |
||||
} |
||||
|
||||
self.ext_data.get_mut(&TypeId::of::<T>()).unwrap() |
||||
.downcast_mut().unwrap() |
||||
} |
||||
|
||||
pub fn set_flag(&mut self, cond : Cond, set : bool) { |
||||
if set { |
||||
self.frame.status.set(cond); |
||||
} |
||||
} |
||||
|
||||
pub fn test_cond(&self, cond : Cond) -> bool { |
||||
self.frame.status.test(cond) |
||||
} |
||||
|
||||
pub fn set_pc(&mut self, pc: Addr) { |
||||
self.frame.pc = pc; |
||||
} |
||||
|
||||
pub fn get_pc(&self) -> Addr { |
||||
self.frame.pc |
||||
} |
||||
|
||||
pub fn clear_status(&mut self) { |
||||
self.frame.status.clear(); |
||||
} |
||||
|
||||
pub fn update_status(&mut self, val: Value) { |
||||
self.frame.status.update(val); |
||||
} |
||||
|
||||
pub fn read(&mut self, rd: Rd) -> Result<Value, Fault> { |
||||
match rd.d() { |
||||
SrcDisp::Immediate(v) => Ok(v), |
||||
SrcDisp::Register(Register::Res(rn)) => { |
||||
if rn >= REG_COUNT as u8 { |
||||
Err(Fault::RegisterNotExist { reg: Register::Res(rn) }) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490
|
||||
} else { |
||||
trace!("Rd {:?} = {}", rd, self.frame.res[rn as usize]); |
||||
Ok(self.frame.res[rn as usize]) |
||||
} |
||||
} |
||||
SrcDisp::Register(Register::Arg(rn)) => { |
||||
if rn >= REG_COUNT as u8 { |
||||
Err(Fault::RegisterNotExist { reg: Register::Arg(rn) }) |
||||
} else { |
||||
trace!("Rd {:?} = {}", rd, self.frame.arg[rn as usize]); |
||||
Ok(self.frame.arg[rn as usize]) |
||||
} |
||||
} |
||||
SrcDisp::Register(Register::Gen(rn)) => { |
||||
if rn >= REG_COUNT as u8 { |
||||
Err(Fault::RegisterNotExist { reg: Register::Gen(rn) }) |
||||
} else { |
||||
trace!("Rd {:?} = {}", rd, self.frame.gen[rn as usize]); |
||||
Ok(self.frame.gen[rn as usize]) |
||||
} |
||||
} |
||||
SrcDisp::ObjectPtr(_) => { |
||||
unimplemented!("Read object ptr") |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub fn write(&mut self, wr: Wr, val: Value) -> Result<(), Fault> { |
||||
trace!("WR {:?} := {}", wr, val); |
||||
|
||||
match wr.d() { |
||||
DstDisp::Discard => { |
||||
/* Discard */ |
||||
Ok(()) |
||||
} |
||||
DstDisp::Register(Register::Res(rn)) => { |
||||
if rn >= REG_COUNT as u8 { |
||||
Err(Fault::RegisterNotExist { reg: Register::Res(rn) }) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490
|
||||
} else { |
||||
Err(Fault::RegisterNotWritable { reg: Register::Res(rn) }) |
||||
} |
||||
} |
||||
DstDisp::Register(Register::Arg(rn)) => { |
||||
if rn >= REG_COUNT as u8 { |
||||
Err(Fault::RegisterNotExist { reg: Register::Arg(rn) }) |
||||
} else { |
||||
Err(Fault::RegisterNotWritable { reg: Register::Res(rn) }) |
||||
} |
||||
} |
||||
DstDisp::Register(Register::Gen(rn)) => { |
||||
if rn >= REG_COUNT as u8 { |
||||
Err(Fault::RegisterNotExist { reg: Register::Gen(rn) }) |
||||
} else { |
||||
self.frame.gen[rn as usize] = val; |
||||
Ok(()) |
||||
} |
||||
} |
||||
DstDisp::ObjectPtr(_) => { |
||||
unimplemented!("Write object ptr") |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue