use std::sync::{
atomic::{AtomicU32, Ordering},
Arc, RwLock,
};
use dashmap::DashMap;
use crate::{
emulation::{
capture::CaptureContext,
engine::SyntheticMethodBody,
fakeobjects::SharedFakeObjects,
filesystem::VirtualFs,
memory::{AddressSpace, ManagedHeap, StaticFieldStorage},
process::EmulationConfig,
runtime::RuntimeState,
tokens,
},
metadata::token::Token,
CilObject,
};
pub struct ThreadContext {
pub address_space: Arc<AddressSpace>,
pub runtime: Arc<RwLock<RuntimeState>>,
pub capture: Arc<CaptureContext>,
pub config: Arc<EmulationConfig>,
pub assembly: Option<Arc<CilObject>>,
pub fake_objects: SharedFakeObjects,
pub virtual_fs: Arc<VirtualFs>,
pub synthetic_methods: Arc<DashMap<Token, SyntheticMethodBody>>,
synthetic_method_counter: Arc<AtomicU32>,
}
impl ThreadContext {
pub fn new(
address_space: Arc<AddressSpace>,
runtime: Arc<RwLock<RuntimeState>>,
capture: Arc<CaptureContext>,
config: Arc<EmulationConfig>,
assembly: Option<Arc<CilObject>>,
fake_objects: SharedFakeObjects,
virtual_fs: Arc<VirtualFs>,
) -> Self {
Self {
address_space,
runtime,
capture,
config,
assembly,
fake_objects,
virtual_fs,
synthetic_methods: Arc::new(DashMap::new()),
synthetic_method_counter: Arc::new(AtomicU32::new(1)),
}
}
#[must_use]
pub fn heap(&self) -> &ManagedHeap {
self.address_space.managed_heap()
}
#[must_use]
pub fn statics(&self) -> &StaticFieldStorage {
self.address_space.statics()
}
pub fn register_synthetic_method(&self, body: SyntheticMethodBody) -> Token {
let id = self
.synthetic_method_counter
.fetch_add(1, Ordering::Relaxed);
let token = Token::new(tokens::ranges::SYNTHETIC_METHOD_BASE | id);
self.synthetic_methods.insert(token, body);
token
}
pub fn fork(&self) -> crate::Result<Self> {
let virtual_fs = match self.virtual_fs.fork() {
Ok(forked) => Arc::new(forked),
Err(_) => Arc::clone(&self.virtual_fs),
};
Ok(Self {
address_space: Arc::new(self.address_space.fork()?),
runtime: Arc::clone(&self.runtime),
capture: Arc::new(CaptureContext::with_config(self.capture.config().clone())),
config: Arc::clone(&self.config),
assembly: self.assembly.clone(),
fake_objects: self.fake_objects.clone(),
virtual_fs,
synthetic_methods: Arc::clone(&self.synthetic_methods),
synthetic_method_counter: Arc::clone(&self.synthetic_method_counter),
})
}
}