1
2extern crate typed_arena;
3
4pub mod caml_ffi_types;
5pub mod caml_opaque;
6
7mod caml_values;
8mod caml_ba;
9
10pub use caml_ffi_types::*;
11pub use caml_opaque::*;
12pub use caml_values::*;
13
14use typed_arena::Arena;
15use caml_ba::Bigarray;
16
17extern {
22 pub fn caml_ba_alloc_u8(data: *const Cvoid, ndims: Cint, dims: *const Clong) -> Value;
23
24 pub fn set_finalize(ops: *const CustomOperations, f: extern fn (Value));
26}
27
28pub fn ops(ops: &'static CustomOperations) -> *const CustomOperations {
33 ops as *const CustomOperations
34}
35
36pub fn caml_finalize(ops: &'static CustomOperations, f: extern fn (Value)) {
39 unsafe { set_finalize(ops as *const CustomOperations, f) }
40}
41
42pub fn caml_ba_data(value: Value) -> *mut Cvoid {
46 assert!(tag_of_value(value) == CUSTOM_TAG);
47 unsafe {
48 let ba_offset = (value as *mut Value).offset(1 as isize);
49 let ba = ba_offset as *const Bigarray;
50 (*ba).data as *mut Cvoid
51 }
52}
53
54pub fn caml_to_slice<T>(value: Value) -> &'static [T] {
55 assert!(tag_of_value(value) == CUSTOM_TAG);
56 unsafe {
57 let ba_offset = (value as *mut Value).offset(1 as isize);
58 let ba = ba_offset as *const Bigarray;
59 let len = (*ba).dim as usize;
60 std::slice::from_raw_parts((*ba).data as *const T, len)
61 }
62}
63
64pub fn acquire_external<T>(ba: Value) -> &'static T {
67 let data_ptr = caml_ba_data(ba) as *mut T;
68 unsafe { data_ptr.as_ref().unwrap() }
69}
70
71pub fn alloc_external<T>(ext: T) -> Value {
72 let ext_box = Box::new(ext);
73 let ext_ptr = Box::into_raw(ext_box);
74 let size = std::mem::size_of::<T>();
75 let dims = &[size as Clong];
76 unsafe { caml_ba_alloc_u8(ext_ptr as *const Cvoid, 1, dims.as_ptr()) }
77}
78
79pub fn free_external<T>(ba: Value) -> () {
80 let data_ptr = caml_ba_data(ba) as *mut T;
81 drop(unsafe { Box::from_raw(data_ptr) })
82}
83
84pub fn acquire_ba_arena(arena: Value) -> &'static Arena<Vec<u8>> {
87 acquire_external::<Arena<Vec<u8>>>(arena)
88}
89
90pub fn arena_alloc_ba(arena: &'static Arena<Vec<u8>>, msg: Vec<u8>) -> Value {
91 let size = std::mem::size_of::<u8>() * msg.len();
92 let dims = &[size as Clong];
93 let mem = arena.alloc(msg);
94 unsafe { caml_ba_alloc_u8(mem.as_ptr() as *const Cvoid, 1, dims.as_ptr()) }
95}
96
97#[no_mangle]
101pub extern fn arena_alloc(_unit: Value) -> Value {
102 alloc_external::<Arena<Vec<u8>>>(Arena::new())
103}
104
105#[no_mangle]
106pub extern fn arena_free(arena: Value) -> Value {
107 free_external::<Arena<Vec<u8>>>(arena);
108 caml_unit()
109}
110