Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
ob_run.ml1 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 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360[@@@ocaml.warning "-32"] (* Runtime library *) open Printf exception Error of string (* Error messages *) let error s = raise (Error s) let read_error () = error "Read error" let read_error_at ib = error (sprintf "Read error (%i)" ib.Bi_inbuf.i_pos) let tag_error tag s = error (sprintf "Found wrong tag %i for %s" tag s) let unsupported_variant h has_arg = error (sprintf "Unsupported variant (hash=%i, arg=%B)" h has_arg) let missing_tuple_fields len req_fields = let missing = List.fold_right ( fun i acc -> if i >= len then i :: acc else acc ) req_fields [] in error (sprintf "Missing tuple field%s %s" (if List.length missing > 1 then "s" else "") (String.concat ", " (List.map string_of_int missing))) let missing_fields bit_fields field_names = let acc = ref [] in for z = Array.length field_names - 1 downto 0 do let i = z / 31 in let j = z mod 31 in if bit_fields.(i) land (1 lsl j) = 0 then acc := field_names.(z) :: !acc done; error (sprintf "Missing record field%s %s" (if List.length !acc > 1 then "s" else "") (String.concat ", " !acc)) (* Readers *) let get_unit_reader tag = if tag = Bi_io.unit_tag then Bi_io.read_untagged_unit else tag_error tag "unit" let read_unit ib = if Bi_io.read_tag ib = Bi_io.unit_tag then Bi_io.read_untagged_unit ib else read_error_at ib let get_bool_reader tag = if tag = Bi_io.bool_tag then Bi_io.read_untagged_bool else tag_error tag "bool" let read_bool ib = if Bi_io.read_tag ib = Bi_io.bool_tag then Bi_io.read_untagged_bool ib else read_error_at ib let get_int_reader tag = match tag with 1 -> Bi_io.read_untagged_int8 | 2 -> Bi_io.read_untagged_int16 | 16 -> Bi_io.read_untagged_uvint | 17 -> Bi_io.read_untagged_svint | _ -> tag_error tag "int" let read_int ib = match Bi_io.read_tag ib with 1 -> Bi_io.read_untagged_int8 ib | 2 -> Bi_io.read_untagged_int16 ib | 16 -> Bi_io.read_untagged_uvint ib | 17 -> Bi_io.read_untagged_svint ib | _ -> read_error_at ib let get_char_reader tag = if tag = Bi_io.int8_tag then Bi_io.read_untagged_char else tag_error tag "char" let read_char ib = if Bi_io.read_tag ib = Bi_io.int8_tag then Bi_io.read_untagged_char ib else read_error_at ib let get_int16_reader tag = if tag = Bi_io.int16_tag then Bi_io.read_untagged_int16 else tag_error tag "int16" let read_int16 ib = if Bi_io.read_tag ib = Bi_io.int16_tag then Bi_io.read_untagged_int16 ib else read_error_at ib let get_int32_reader tag = if tag = Bi_io.int32_tag then Bi_io.read_untagged_int32 else tag_error tag "int32" let read_int32 ib = if Bi_io.read_tag ib = Bi_io.int32_tag then Bi_io.read_untagged_int32 ib else read_error_at ib let get_int64_reader tag = if tag = Bi_io.int64_tag then Bi_io.read_untagged_int64 else tag_error tag "int64" let read_int64 ib = if Bi_io.read_tag ib = Bi_io.int64_tag then Bi_io.read_untagged_int64 ib else read_error_at ib let get_float32_reader tag = if tag = Bi_io.float32_tag then Bi_io.read_untagged_float32 else tag_error tag "float32" let get_float64_reader tag = if tag = Bi_io.float64_tag then Bi_io.read_untagged_float64 else tag_error tag "float64" let get_float_reader = get_float64_reader let read_float32 ib = if Bi_io.read_tag ib = Bi_io.float32_tag then Bi_io.read_untagged_float32 ib else read_error_at ib let read_float64 ib = if Bi_io.read_tag ib = Bi_io.float64_tag then Bi_io.read_untagged_float64 ib else read_error_at ib let read_float = read_float64 let get_string_reader tag = if tag = Bi_io.string_tag then Bi_io.read_untagged_string else tag_error tag "string" let read_string ib = if Bi_io.read_tag ib = Bi_io.string_tag then Bi_io.read_untagged_string ib else read_error_at ib let read_array_value get_reader ib = let len = Bi_vint.read_uvint ib in if len = 0 then [| |] else let reader = get_reader (Bi_io.read_tag ib) in let a = Array.make len (reader ib) in for i = 1 to len - 1 do Array.unsafe_set a i (reader ib) done; a let read_list_value get_reader ib = Array.to_list (read_array_value get_reader ib) let get_array_reader get_reader tag = if tag = Bi_io.array_tag then read_array_value get_reader else tag_error tag "array" let get_list_reader get_reader tag = if tag = Bi_io.array_tag then fun ib -> Array.to_list (read_array_value get_reader ib) else tag_error tag "list" let read_array get_reader ib = if Bi_io.read_tag ib = Bi_io.array_tag then read_array_value get_reader ib else read_error_at ib let read_list read ib = Array.to_list (read_array read ib) (* Writers *) let write_tagged tag write buf x = Bi_io.write_tag buf tag; write buf x let write_untagged_option write buf x = match x with None -> Bi_io.write_numtag buf 0 false | Some x -> Bi_io.write_numtag buf 0 true; write buf x let write_option write buf x = Bi_io.write_tag buf Bi_io.num_variant_tag; write_untagged_option write buf x let array_init2 len x f = if len = 0 then [| |] else let a = Array.make len (f 0 x) in for i = 1 to len - 1 do Array.unsafe_set a i (f i x) done; a let array_init3 len x y f = if len = 0 then [| |] else let a = Array.make len (f 0 x y) in for i = 1 to len - 1 do Array.unsafe_set a i (f i x y) done; a let array_iter2 f x a = for i = 0 to Array.length a - 1 do f x (Array.unsafe_get a i) done let array_iter3 f x y a = for i = 0 to Array.length a - 1 do f x y (Array.unsafe_get a i) done let rec list_iter2 f x = function [] -> () | y :: l -> f x y; list_iter2 f x l let rec list_iter3 f x y = function [] -> () | z :: l -> f x y z; list_iter3 f x y l let write_untagged_array cell_tag write buf a = let len = Array.length a in Bi_vint.write_uvint buf len; if len > 0 then ( Bi_io.write_tag buf cell_tag; array_iter2 write buf a ) let write_array cell_tag write buf a = Bi_io.write_tag buf Bi_io.array_tag; write_untagged_array cell_tag write buf a let write_untagged_list cell_tag write buf l = let len = List.length l in Bi_vint.write_uvint buf len; if len > 0 then ( Bi_io.write_tag buf cell_tag; list_iter2 write buf l ) let write_list cell_tag write buf l = Bi_io.write_tag buf Bi_io.array_tag; write_untagged_list cell_tag write buf l (* shortcut for getting the tag of a polymorphic variant since biniou uses the same representation (usefulness?) *) let get_poly_tag (x : [> ]) = let r = Obj.repr x in if Obj.is_block r then (Obj.obj (Obj.field r 0) : int) else (Obj.obj r : int) (* We want an identity function that is not inlined *) type identity_t = { mutable _identity : 'a. 'a -> 'a } let identity_ref = { _identity = (fun x -> x) } let identity x = identity_ref._identity x (* Checking at runtime that our assumptions on unspecified compiler behavior still hold. *) type t = { _a : int option; _b : int; } let create () = { { _a = None; _b = Array.length Sys.argv } with _a = None } (* This is a runtime test that checks whether our assumptions about the compiler still hold. We get the following warning when using an OCaml compiler built with the flambda optimization. This is probably a good warning and shouldn't be ignored if the OCaml/biniou is to be used. This won't affect the OCaml/JSON backend. > Warning 59 [flambda-assignment-to-non-mutable-value]: A potential > assignment to a non-mutable value was detected in this source file. > Such assignments may generate incorrect code when using Flambda. *) let test () = let r = create () in let v = Some 17 in Obj.set_field (Obj.repr r) 0 (Obj.repr v); let safe_r = identity r in (* r._a is inlined by ocamlopt and equals None because the field is supposed to be immutable. *) assert (safe_r._a = v) let () = test () (************************************)