1#![allow(clippy::missing_safety_doc)]
19
20use std::ffi::{c_char, CStr};
21use std::panic::{catch_unwind, AssertUnwindSafe};
22use std::sync::Arc;
23
24use crate::context::Context;
25use crate::graph::GraphInner;
26use crate::kernel::Contract;
27use crate::kernel_runner::KernelRunner;
28use crate::runtime::last_error;
29use crate::status::{code, Error};
30
31pub const ABI_VERSION: u32 = 4;
32
33pub const INVALID_ID: usize = usize::MAX;
34pub const LMFLOW_POLLER_BLOCK: i32 = 0;
35pub const LMFLOW_POLLER_DROP_OLDEST: i32 = 1;
36pub const LMFLOW_POLLER_DROP_NEWEST: i32 = 2;
37pub const LMFLOW_POLLER_LATEST: i32 = 3;
38
39fn guard<F: FnOnce() -> i32>(f: F) -> i32 {
42 match catch_unwind(AssertUnwindSafe(f)) {
43 Ok(v) => v,
44 Err(_) => {
45 last_error::set("internal engine panic (caught at the FFI boundary)");
46 code::PANIC
47 }
48 }
49}
50
51fn guard_val<T, F: FnOnce() -> T>(default: T, f: F) -> T {
52 match catch_unwind(AssertUnwindSafe(f)) {
53 Ok(v) => v,
54 Err(_) => {
55 last_error::set("internal engine panic (caught at the FFI boundary)");
56 default
57 }
58 }
59}
60
61fn fail(e: Error) -> i32 {
62 last_error::set(&e.to_string());
63 e.code()
64}
65
66fn to_status(r: crate::status::Result<()>) -> i32 {
67 match r {
68 Ok(()) => code::OK,
69 Err(e) => fail(e),
70 }
71}
72
73unsafe fn cstr<'a>(p: *const c_char) -> Option<&'a str> {
74 if p.is_null() {
75 return None;
76 }
77 CStr::from_ptr(p).to_str().ok()
78}
79
80unsafe fn ctx_ref<'a>(c: *const LMFlowContext) -> Option<&'a Context> {
81 if c.is_null() {
82 None
83 } else {
84 Some(&*(c as *const Context))
85 }
86}
87
88unsafe fn ctx_mut<'a>(c: *mut LMFlowContext) -> Option<&'a mut Context> {
89 if c.is_null() {
90 None
91 } else {
92 Some(&mut *(c as *mut Context))
93 }
94}
95
96unsafe fn contract_mut<'a>(c: *mut LMFlowContract) -> Option<&'a mut Contract> {
97 if c.is_null() {
98 None
99 } else {
100 Some(&mut *(c as *mut Contract))
101 }
102}
103
104#[repr(C)]
107pub struct LMFlowGraph {
108 _private: [u8; 0],
109}
110#[repr(C)]
111pub struct LMFlowInput {
112 _private: [u8; 0],
113}
114#[repr(C)]
115pub struct LMFlowPoller {
116 _private: [u8; 0],
117}
118#[repr(C)]
119pub struct LMFlowKernelRunner {
120 _private: [u8; 0],
121}
122#[repr(C)]
123pub struct LMFlowContext {
124 _private: [u8; 0],
125}
126#[repr(C)]
127pub struct LMFlowContract {
128 _private: [u8; 0],
129}
130
131pub struct InputHandle {
133 graph: Arc<GraphInner>,
134 edge: usize,
135}
136
137pub struct KernelRunnerHandle {
138 pub runner: KernelRunner,
139}
140
141mod context;
143mod graph;
144mod kernel;
145mod kernel_runner;
146mod packet;
147
148pub use context::*;
149pub use graph::*;
150pub use kernel::*;
151pub use kernel_runner::*;
152pub use packet::*;