1pub mod tiered;
7pub use tiered::{TieredAdapter, TieredBound};
8
9use std::sync::Arc;
10
11use beadie_core::{
12 Bead, Beadie, CoreHandle, HotnessPolicy, OsrCompileResult, OsrEntry, ReloadOutcome, SwapResult,
13 ThresholdPolicy,
14};
15
16#[derive(Debug)]
21pub struct CompileError {
22 pub message: String,
23}
24impl std::fmt::Display for CompileError {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.write_str(&self.message)
27 }
28}
29impl std::error::Error for CompileError {}
30impl CompileError {
31 pub fn new(msg: impl Into<String>) -> Self {
32 Self {
33 message: msg.into(),
34 }
35 }
36 pub fn from_err<E: std::error::Error>(e: E) -> Self {
37 Self {
38 message: e.to_string(),
39 }
40 }
41}
42
43pub trait JitBackend: Send + Sync + 'static {
55 type FunctionDef: Send + 'static;
56 type Error: std::error::Error + Send + Sync + 'static;
57
58 fn compile(&self, bead: &Arc<Bead>, def: Self::FunctionDef) -> Result<*mut (), Self::Error>;
61}
62
63pub struct OsrBuild<D> {
75 pub def: D,
76 pub osr: Vec<OsrEntry>,
77}
78
79#[derive(Clone)]
85pub struct BoundBead<B: JitBackend> {
86 pub(crate) bead: Arc<Bead>,
87 pub(crate) backend: Arc<B>,
88}
89
90impl<B: JitBackend> BoundBead<B> {
91 pub fn bead(&self) -> &Arc<Bead> {
92 &self.bead
93 }
94 pub fn backend(&self) -> &Arc<B> {
95 &self.backend
96 }
97
98 pub fn compile(&self, def: B::FunctionDef) -> Result<Arc<Bead>, B::Error> {
100 let ptr = self.backend.compile(&self.bead, def)?;
101 self.bead.eager_install(ptr);
102 Ok(Arc::clone(&self.bead))
103 }
104
105 pub fn reload(&self) -> ReloadOutcome {
106 self.bead.reload()
107 }
108
109 pub fn swap_compiled(&self, new_code: *mut ()) -> Option<SwapResult> {
110 self.bead.swap_compiled(new_code)
111 }
112
113 pub fn swap_compiled_with_osr(
116 &self,
117 new_code: *mut (),
118 osr: Vec<OsrEntry>,
119 ) -> Option<SwapResult> {
120 self.bead.swap_compiled_with_osr(new_code, osr)
121 }
122}
123
124pub struct BackendAdapter<B: JitBackend, P: HotnessPolicy = ThresholdPolicy> {
130 beadie: Beadie<P>,
131 backend: Arc<B>,
132}
133
134impl<B: JitBackend> BackendAdapter<B> {
135 pub fn new(backend: B) -> Self {
136 Self::with_policy(backend, ThresholdPolicy::default())
137 }
138}
139
140impl<B: JitBackend, P: HotnessPolicy> BackendAdapter<B, P> {
141 pub fn with_policy(backend: B, policy: P) -> Self {
142 Self {
143 beadie: Beadie::with_policy(policy),
144 backend: Arc::new(backend),
145 }
146 }
147
148 pub fn register(
149 &self,
150 core: CoreHandle,
151 on_invalidate: Option<Box<dyn Fn() + Send + Sync>>,
152 ) -> BoundBead<B> {
153 let bead = self.beadie.register(core, on_invalidate);
154 BoundBead {
155 bead,
156 backend: Arc::clone(&self.backend),
157 }
158 }
159
160 #[inline]
161 pub fn on_invoke<F>(&self, bound: &BoundBead<B>, factory: F) -> Option<*mut ()>
162 where
163 F: FnOnce(&Arc<Bead>) -> B::FunctionDef + Send + 'static,
164 {
165 let backend = Arc::clone(&bound.backend);
166 self.beadie.on_invoke(&bound.bead, move |bead| {
167 let def = factory(bead);
168 match backend.compile(bead, def) {
169 Ok(ptr) => ptr,
170 Err(e) => {
171 eprintln!("beadie: compile error: {e}");
172 core::ptr::null_mut()
173 }
174 }
175 })
176 }
177
178 #[inline]
188 pub fn on_invoke_osr<F>(&self, bound: &BoundBead<B>, factory: F) -> Option<*mut ()>
189 where
190 F: FnOnce(&Arc<Bead>) -> OsrBuild<B::FunctionDef> + Send + 'static,
191 {
192 let backend = Arc::clone(&bound.backend);
193 self.beadie.on_invoke_osr(&bound.bead, move |bead| {
194 let build = factory(bead);
195 let entry = match backend.compile(bead, build.def) {
196 Ok(ptr) => ptr,
197 Err(e) => {
198 eprintln!("beadie: compile error: {e}");
199 core::ptr::null_mut()
200 }
201 };
202 OsrCompileResult {
203 entry,
204 osr: build.osr,
205 }
206 })
207 }
208
209 pub fn prune(&self) {
210 self.beadie.prune();
211 }
212 pub fn reload_all(&self) -> usize {
213 self.beadie.reload_all()
214 }
215 pub fn reload_matching(&self, pred: impl Fn(&Arc<Bead>) -> bool) -> usize {
216 self.beadie.reload_matching(pred)
217 }
218 pub fn chain_len(&self) -> usize {
219 self.beadie.chain_len()
220 }
221 pub fn beadie(&self) -> &Beadie<P> {
222 &self.beadie
223 }
224 pub fn backend(&self) -> &Arc<B> {
225 &self.backend
226 }
227}