1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
//! Contains OCaml types and conversion functions from runtime representations. //! #[allow(non_camel_case_types)] pub type Value = usize; pub type Uintnat = usize; #[allow(non_camel_case_types)] pub type Mlsize_t = Uintnat; #[allow(non_camel_case_types)] pub type Tag_t = u8; //typedef unsigned int tag_t; // Actually, an unsigned char #[allow(non_camel_case_types)] pub type Color_t = Uintnat; #[allow(non_camel_case_types)] pub type Mark_t = Uintnat; /// An OCaml heap-allocated block header. **NB**: this is currently unimplemented. /// /// Structure of the header: /// /// For 16-bit and 32-bit architectures: /// ///```text /// +--------+-------+-----+ /// | wosize | color | tag | /// +--------+-------+-----+ /// bits 31 10 9 8 7 0 ///``` /// /// For 64-bit architectures: /// ///```text /// +--------+-------+-----+ /// | wosize | color | tag | /// +--------+-------+-----+ /// bits 63 10 9 8 7 0 ///``` /// pub struct Header {} #[macro_export] /// `(((intnat)(x) << 1) + 1)` macro_rules! val_long { ($x:expr) => ((($x as usize) << 1) + 1); ($x:ident) => ((($x as usize) << 1) + 1); } #[macro_export] /// `Long_val(x) ((x) >> 1)` macro_rules! long_val { ($x:ident) => ($x as usize >> 1); ($x:expr) => ($x as usize >> 1); } #[macro_export] /// Converts a machine `usize` into an OCaml `int` /// /// `Val_int(x) Val_long(x)` macro_rules! val_int { ($x:expr) => ( val_long!($x) ); ($x:ident) => ( val_long!($x) ); } #[macro_export] /// Converts an OCaml `int` into a `usize` /// /// `Int_val(x) ((int) Long_val(x))` macro_rules! int_val { ($x:ident) => (long_val!($x)); ($x:expr) => (long_val!($x)); } // #define Max_long (((intnat)1 << (8 * sizeof(value) - 2)) - 1) // #define Min_long (-((intnat)1 << (8 * sizeof(value) - 2))) #[macro_export] /// Extracts from the `$block` an OCaml value at the `$ith`-field macro_rules! field { ($block:ident, $i:expr) => ( unsafe { (block as *mut Value).offset(i)} ); } /// The OCaml `()` (`unit`) value - rien. pub const UNIT: Value = val_int!(0); /* pub const Num_tags: ::std::os::raw::c_ushort = 256; pub const No_scan_tag: ::std::os::raw::c_uchar = 251; pub const Forward_tag: ::std::os::raw::c_uchar = 250; pub const Infix_tag: ::std::os::raw::c_uchar = 249; pub const Object_tag: ::std::os::raw::c_uchar = 248; pub const Closure_tag: ::std::os::raw::c_uchar = 247; pub const Lazy_tag: ::std::os::raw::c_uchar = 246; pub const Abstract_tag: ::std::os::raw::c_uchar = 251; pub const String_tag: ::std::os::raw::c_uchar = 252; pub const Double_tag: ::std::os::raw::c_uchar = 253; pub const Double_array_tag: ::std::os::raw::c_uchar = 254; pub const Custom_tag: ::std::os::raw::c_uchar = 255; pub const Tag_cons: ::std::os::raw::c_uchar = 0; */ // Strings /// The OCaml GC tag for a `string` pub const STRING_TAG: u8 = 252; /// Pointer to the first byte #[macro_export] macro_rules! bp_val { ($v: ident) => { $v as *const u8 } } #[macro_export] /// Extracts a machine `ptr` to the bytes making up an OCaml `string` macro_rules! string_val { ($v:ident) => { bp_val!($v) } } extern "C" { /// Returns size of the string in `value` in bytes pub fn caml_string_length(value: Value) -> Mlsize_t; }