logicaffeine_jit/
image.rs1use logicaffeine_compile::optimization::Tier;
10use logicaffeine_compile::vm::{Compiler, NativeTier, Op, Vm};
11
12use crate::ForgeTier;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct ImageOutcome {
17 pub lines: Vec<String>,
19 pub error: Option<String>,
21}
22
23pub fn build(source: &str) -> Result<Vec<u8>, String> {
30 logicaffeine_compile::ui_bridge::with_optimized_program_tiered(
31 source,
32 Tier::T3,
33 |parsed, interner| {
34 let (stmts, types, _policies) = parsed?;
35 if logicaffeine_compile::interpreter::needs_async(stmts, interner)
36 || logicaffeine_compile::concurrency::uses_scheduler(stmts)
37 {
38 return Err("a JIT image is sync-only; this program requires the scheduler".into());
39 }
40 let oracle = logicaffeine_compile::optimize::oracle_analyze_with(stmts, interner);
41 let program =
42 Compiler::compile_with_oracle(stmts, interner, Some(types), Some(oracle))?;
43 if program
44 .code
45 .iter()
46 .any(|op| matches!(op, Op::CheckPolicy { .. }))
47 {
48 return Err(
49 "a JIT image cannot yet carry the policy registry; run from source instead"
50 .into(),
51 );
52 }
53 Ok(logicaffeine_compile::vm::binisa::encode_program(
54 &program, interner,
55 ))
56 },
57 )
58}
59
60pub fn run(
63 bytes: &[u8],
64 program_args: &[String],
65 tier: &ForgeTier,
66) -> Result<ImageOutcome, String> {
67 let mut interner = logicaffeine_compile::Interner::new();
68 let program = logicaffeine_compile::vm::binisa::decode_program(bytes, &mut interner)
69 .ok_or_else(|| "invalid or incompatible LOGOS bytecode image".to_string())?;
70 let mut vm = Vm::new(&program)
71 .with_program_args(program_args.to_vec())
72 .with_native_tier(tier as &dyn NativeTier);
73 let error = vm.run().err();
74 Ok(ImageOutcome {
75 lines: vm.into_lines(),
76 error,
77 })
78}