Skip to main content

logicaffeine_jit/
image.rs

1//! Precompiled bytecode images for the native JIT.
2//!
3//! The ordinary CLI path parses, optimizes and lowers source on every process
4//! launch. An image moves that deterministic work to the build phase while
5//! retaining the actual copy-and-patch tier-up at run time. The image is the
6//! existing versioned, checksummed LGB1 wire format; native machine code is
7//! never serialized.
8
9use logicaffeine_compile::optimization::Tier;
10use logicaffeine_compile::vm::{Compiler, NativeTier, Op, Vm};
11
12use crate::ForgeTier;
13
14/// One image execution's complete observable result.
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct ImageOutcome {
17    /// Lines printed by `Show`, without trailing newlines.
18    pub lines: Vec<String>,
19    /// Runtime failure, if execution did not complete.
20    pub error: Option<String>,
21}
22
23/// Compile source through the production eager run-path optimizer into a
24/// self-contained LGB1 bytecode image.
25///
26/// Policy checks are refused explicitly because their condition registry
27/// lives beside the parsed AST rather than in `CompiledProgram`; silently
28/// dropping that registry would change the program's security semantics.
29pub 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
60/// Decode and execute an image on the bytecode VM with the supplied private
61/// copy-and-patch tier. `program_args` is the full argv, including `argv[0]`.
62pub 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}