yanais/ocaml/lib/layout.ml
2024-02-09 22:19:55 +01:00

38 lines
1.1 KiB
OCaml

type t = {
size : int;
(* alignment = 1 << align_exp *)
align_exp : char;
}
open Int
let alignment_of_exp x = shift_left 1 (Char.code x)
let alignment x = alignment_of_exp x.align_exp
let max_size_for_align_exp x =
let y = alignment_of_exp x in
let isz_max_sc = shift_right max_int 1 |> succ in
isz_max_sc - y
(** appends a layout to this one, returns new layout and the offset **)
let push orig next =
let align_exp = max (Char.code orig.align_exp) (Char.code next.align_exp) |> Char.chr in
(* fill up ourselves so that the other element is correctly aligned *)
let smask_sh = alignment next in
let smask = pred smask_sh in
let smasked = logand orig.size smask in
(* align size *)
let size = if compare smasked zero == 0 then orig.size else (
add (sub orig.size smasked) smask_sh
) in
let offset = size in
let size = size + next.size in
if size <= max_size_for_align_exp align_exp
then Option.some ({ size; align_exp; }, offset)
else Option.none
let finish orig = push orig { size = 0; align_exp = orig.align_exp }