1pub mod config;
40pub mod backend;
41pub mod executor;
42pub mod value_store;
43pub mod tuning;
44pub mod speculation;
45
46#[cfg(feature = "cpu")]
47pub mod backends;
48
49pub use config::RuntimeConfig;
50pub use backend::Backend;
51pub use executor::Executor;
52pub use value_store::ValueStore;
53pub use speculation::{SpeculationCoordinator, SpeculationConfig, AgentState, BarrierCoordinator};
54
55use rustd_core::{RustDCrate, Value, Result};
56use std::cell::{Cell, RefCell};
57use std::sync::Arc;
58
59thread_local! {
60 static SPECULATION_DISABLED: Cell<bool> = Cell::new(false);
62
63 static BARRIER_COORDINATOR: RefCell<Option<Arc<BarrierCoordinator>>> = RefCell::new(None);
65
66 static AGENT_ID: Cell<Option<usize>> = Cell::new(None);
68}
69
70pub(crate) fn is_speculation_disabled() -> bool {
72 SPECULATION_DISABLED.with(|d| d.get())
73}
74
75pub(crate) fn disable_speculation() {
77 SPECULATION_DISABLED.with(|d| d.set(true));
78}
79
80pub(crate) fn set_barrier_coordinator(coordinator: Option<Arc<BarrierCoordinator>>, agent_id: Option<usize>) {
82 BARRIER_COORDINATOR.with(|c| *c.borrow_mut() = coordinator);
83 AGENT_ID.with(|id| id.set(agent_id));
84}
85
86pub(crate) fn get_barrier_coordinator() -> Option<Arc<BarrierCoordinator>> {
88 BARRIER_COORDINATOR.with(|c| c.borrow().clone())
89}
90
91pub(crate) fn get_agent_id() -> Option<usize> {
93 AGENT_ID.with(|id| id.get())
94}
95
96pub fn execute(krate: &RustDCrate) -> Result<Value> {
98 let config = RuntimeConfig::default();
99 execute_with_config(krate, &config)
100}
101
102pub fn execute_with_config(krate: &RustDCrate, config: &RuntimeConfig) -> Result<Value> {
104 let mut executor = Executor::new(config)?;
105 executor.run(krate)
106}
107
108#[cfg(test)]
110mod smoke_tests {
111 use super::*;
112 use rustd_core::{RustDCrate, Instruction, Value};
113
114 #[test]
115 fn test_basic_addition() {
116 let krate = RustDCrate::new(vec![
118 Instruction::Constant { out: 0, val: Value::Integer(5) },
119 Instruction::Constant { out: 1, val: Value::Integer(3) },
120 Instruction::Add { out: 2, lhs: 0, rhs: 1 },
121 Instruction::Return { val: 2 },
122 ]);
123
124 let result = execute(&krate).unwrap();
125 assert_eq!(result, Value::Integer(8));
126 }
127
128 #[test]
129 fn test_determinism() {
130 let krate = RustDCrate::new(vec![
131 Instruction::Constant { out: 0, val: Value::Integer(42) },
132 Instruction::Constant { out: 1, val: Value::Integer(10) },
133 Instruction::Mul { out: 2, lhs: 0, rhs: 1 },
134 Instruction::Return { val: 2 },
135 ]);
136
137 let results: Vec<_> = (0..100)
139 .map(|_| execute(&krate).unwrap())
140 .collect();
141
142 assert!(results.iter().all(|r| *r == Value::Integer(420)));
144 }
145
146 #[test]
147 fn test_crate_validation() {
148 let mut krate = RustDCrate::new(vec![
149 Instruction::Constant { out: 0, val: Value::Integer(1) },
150 ]);
151
152 krate.hash[0] ^= 0xFF;
154
155 assert!(execute(&krate).is_err());
157 }
158}