1pub 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#[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#[cfg(feature = "async")]
34pub use async_runtime::AsyncRuntime;
35#[cfg(feature = "async")]
36pub use async_types::{AsyncState, AsyncValue, TaskId};
37
38pub const FZB_MAGIC: &[u8] = b"FZB\x01";
40pub const FZB_VERSION: u8 = 1;
42
43#[cfg(feature = "serde")]
44pub 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 bytes.extend_from_slice(FZB_MAGIC);
52
53 bytes.push(FZB_VERSION);
55
56 let chunk_bytes = bincode::serialize(chunk)?;
58 bytes.extend_from_slice(&chunk_bytes);
59
60 Ok(bytes)
61}
62
63#[cfg(feature = "serde")]
64pub 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 if &bytes[0..4] != FZB_MAGIC {
74 return Err("Invalid magic bytes".into());
75 }
76
77 if bytes[4] != FZB_VERSION {
79 return Err(format!("Unsupported version: {}", bytes[4]).into());
80 }
81
82 let chunk: Chunk = bincode::deserialize(&bytes[5..])?;
84 Ok(chunk)
85}