pub(crate) mod emit;
use crate::backend::{Backend, CompileCtx, CompiledWhole, DispatchOutcome};
use crate::ir::{Event, ProtoStatement};
use std::sync::Arc;
pub struct AotCBackend {
async_mode: bool,
event_enabled: bool,
}
impl AotCBackend {
pub fn new(async_mode: bool, event_enabled: bool) -> Self {
Self {
async_mode,
event_enabled,
}
}
}
pub fn cc_available() -> bool {
let cc = std::env::var("VERYL_AOT_CC").unwrap_or_else(|_| "cc".to_string());
std::process::Command::new(cc)
.arg("--version")
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}
impl Backend for AotCBackend {
fn name(&self) -> &str {
"aot_c"
}
fn supports_4state(&self) -> bool {
false
}
fn compile_whole_comb(
&mut self,
ctx: &CompileCtx,
stmts: &[ProtoStatement],
) -> Option<Arc<dyn CompiledWhole>> {
if ctx.use_4state {
return None;
}
let cell = emit::prepare_comb(stmts, self.async_mode)?;
Some(Arc::new(AotCWhole { cell }))
}
fn compile_whole_event(
&mut self,
ctx: &CompileCtx,
_event: &Event,
stmts: &[ProtoStatement],
) -> Option<Arc<dyn CompiledWhole>> {
if ctx.use_4state || !self.event_enabled {
return None;
}
let cell = emit::prepare_event(stmts, self.async_mode)?;
Some(Arc::new(AotCWhole { cell }))
}
fn diagnose_whole_comb_fallback(&self, stmts: &[ProtoStatement]) -> Option<String> {
if !emit::diag_enabled() {
return None;
}
Some(emit::comb_fallback_reason(stmts))
}
}
struct AotCWhole {
cell: emit::AotCell,
}
impl CompiledWhole for AotCWhole {
fn try_dispatch(&self, ff: *const u8, comb: *mut u8, log: *mut u8) -> DispatchOutcome {
match self.cell.get() {
Some(m) => {
unsafe {
(m.func)(ff, comb as *const u8, log);
}
DispatchOutcome::Done
}
None => DispatchOutcome::NotReady,
}
}
}