fusabi_vm/
lib.rs

1// Fusabi VM - Bytecode Virtual Machine Runtime
2
3pub mod chunk;
4pub mod closure;
5pub mod conversions;
6pub mod error_reporter;
7pub mod gc;
8pub mod host;
9pub mod instruction;
10pub mod optimized_vm;
11pub mod optimizer;
12pub mod stdlib;
13pub mod value;
14pub mod vm;
15
16// Async modules (feature-gated)
17#[cfg(feature = "async")]
18pub mod async_types;
19#[cfg(feature = "async")]
20pub mod async_runtime;
21
22pub use chunk::{Chunk, ChunkBuilder, SourceSpan};
23pub use closure::{Closure, Upvalue};
24pub use error_reporter::{format_error, RuntimeError};
25pub use gc::{GcHeap, GcStats, Trace, Tracer};
26pub use host::{HostFn, HostRegistry};
27pub use instruction::Instruction;
28pub use optimized_vm::FastVm;
29pub use value::{HostData, Value};
30pub use vm::{Frame, Vm, VmError};
31
32// Async re-exports (feature-gated)
33#[cfg(feature = "async")]
34pub use async_runtime::AsyncRuntime;
35#[cfg(feature = "async")]
36pub use async_types::{AsyncState, AsyncValue, TaskId};
37
38/// Magic bytes for Fusabi Bytecode files (.fzb)
39pub const FZB_MAGIC: &[u8] = b"FZB\x01";
40/// Version of the bytecode format
41pub const FZB_VERSION: u8 = 1;
42
43#[cfg(feature = "serde")]
44/// Serialize a chunk to bytes with magic header
45pub fn serialize_chunk(
46    chunk: &Chunk,
47) -> Result<Vec<u8>, Box<dyn std::error::Error + Send + Sync + 'static>> {
48    let mut bytes = Vec::new();
49
50    // Write magic bytes
51    bytes.extend_from_slice(FZB_MAGIC);
52
53    // Write version
54    bytes.push(FZB_VERSION);
55
56    // Serialize chunk with bincode
57    let chunk_bytes = bincode::serialize(chunk)?;
58    bytes.extend_from_slice(&chunk_bytes);
59
60    Ok(bytes)
61}
62
63#[cfg(feature = "serde")]
64/// Deserialize a chunk from bytes, checking magic header
65pub fn deserialize_chunk(
66    bytes: &[u8],
67) -> Result<Chunk, Box<dyn std::error::Error + Send + Sync + 'static>> {
68    if bytes.len() < 5 {
69        return Err("File too short".into());
70    }
71
72    // Check magic bytes
73    if &bytes[0..4] != FZB_MAGIC {
74        return Err("Invalid magic bytes".into());
75    }
76
77    // Check version
78    if bytes[4] != FZB_VERSION {
79        return Err(format!("Unsupported version: {}", bytes[4]).into());
80    }
81
82    // Deserialize chunk
83    let chunk: Chunk = bincode::deserialize(&bytes[5..])?;
84    Ok(chunk)
85}