ocaml_sys/
memory.rs

1//! Defines types and macros primarily for interacting with the OCaml GC.
2//!
3//! # `CAMLParam` Macros
4//! The following macros are used to declare C local variables and
5//! function parameters of type `value`.
6//!
7//! The function body must start with one of the `CAMLparam` macros.
8//! If the function has no parameter of type `value], use [CAMLparam0`.
9//! If the function has 1 to 5 `value` parameters, use the corresponding
10//!
11//! `CAMLparam` with the parameters as arguments.
12//! If the function has more than 5 `value] parameters, use [CAMLparam5`
13//! for the first 5 parameters, and one or more calls to the `CAMLxparam`
14//! macros for the others.
15//!
16//! If the function takes an array of `value`s as argument, use
17//! `CAMLparamN] to declare it (or [CAMLxparamN` if you already have a
18//! call to `CAMLparam` for some other arguments).
19//!
20//! If you need local variables of type `value`, declare them with one
21//! or more calls to the `CAMLlocal` macros at the beginning of the
22//! function, after the call to CAMLparam.  Use `CAMLlocalN` (at the
23//! beginning of the function) to declare an array of `value`s.
24//!
25//! Your function may raise an exception or return a `value` with the
26//! `CAMLreturn] macro.  Its argument is simply the [value` returned by
27//! your function.  Do NOT directly return a `value] with the [return`
28//! keyword.  If your function returns void, use `CAMLreturn0`.
29//!
30//! All the identifiers beginning with "caml__" are reserved by OCaml.
31//! Do not use them for anything (local or global variables, struct or
32//! union tags, macros, etc.)
33//!
34
35use core::default::Default;
36use core::ptr;
37
38use crate::mlvalues::{field, Size, Value};
39
40#[repr(C)]
41#[derive(Debug, Clone)]
42pub struct CamlRootsBlock {
43    pub next: *mut CamlRootsBlock,
44    pub ntables: isize,
45    pub nitems: isize,
46    pub tables: [*mut Value; 5],
47}
48
49impl Default for CamlRootsBlock {
50    fn default() -> CamlRootsBlock {
51        CamlRootsBlock {
52            next: ptr::null_mut(),
53            ntables: 0,
54            nitems: 0,
55            tables: [ptr::null_mut(); 5],
56        }
57    }
58}
59
60extern "C" {
61    pub fn caml_modify(addr: *mut Value, value: Value);
62    pub fn caml_initialize(addr: *mut Value, value: Value);
63}
64
65/// Stores the `$val` at `$offset` in the `$block`.
66///
67/// # Original C code
68///
69/// ```c
70/// Store_field(block, offset, val) do{ \
71///   mlsize_t caml__temp_offset = (offset); \
72///   value caml__temp_val = (val); \
73///   caml_modify (&Field ((block), caml__temp_offset), caml__temp_val); \
74/// }while(0)
75/// ```
76///
77/// # Example
78/// ```rust,ignore
79/// // stores some_value in the first field in the given block
80/// store_field!(some_block, 1, some_value)
81/// ```
82macro_rules! store_field {
83    ($block:expr, $offset:expr, $val:expr) => {
84        let offset = $offset;
85        let val = $val;
86        let block = $block;
87        $crate::memory::caml_modify(field(block, offset), val);
88    };
89}
90
91/// Stores the `value` in the `block` at `offset`.
92///
93/// # Safety
94///
95/// No bounds checking or validation of the OCaml values is done in this function
96pub unsafe fn store_field(block: Value, offset: Size, value: Value) {
97    store_field!(block, offset, value);
98}
99
100extern "C" {
101    pub fn caml_register_global_root(value: *mut Value);
102    pub fn caml_remove_global_root(value: *mut Value);
103    pub fn caml_register_generational_global_root(value: *mut Value);
104    pub fn caml_remove_generational_global_root(value: *mut Value);
105    pub fn caml_modify_generational_global_root(value: *mut Value, newval: Value);
106}