flan/lib/dynload.ml
Joseph Ferano d9fa0f2d35 Revert "The compiler's own dlopen, a macro thunk ABI, and Form as a union"
This reverts commit 709f292a694a7f634b807980c1c5b6e5ec81c429, reversing
changes made to 50b3feaa86a10689cd7ff1c03714b901ab4091c2.
2026-09-12 17:20:48 +07:00

49 lines
2.0 KiB
OCaml

(** The compiler's own dlopen, and raw memory to lay a [Form] out in.
Every function here is a stub in [dynload_stubs.c]; the comment at the top
of that file is the design. Addresses are [nativeint] because that is the
only OCaml type that is exactly a machine word and carries no tag bit. *)
type handle = nativeint
type addr = nativeint
external dl_open : string -> handle = "flan_dl_open"
external dl_sym : handle -> string -> addr = "flan_dl_sym"
external dl_close : handle -> unit = "flan_dl_close"
(** [call fn args n out] runs one macro: [args] is an array of [n] [Form]s,
[out] is room for the one it answers. *)
external call : addr -> addr -> int64 -> addr -> unit = "flan_macro_call"
external alloc : int -> addr = "flan_mem_alloc"
external free : addr -> unit = "flan_mem_free"
external poke_i32 : addr -> int -> int32 -> unit = "flan_poke_i32"
external poke_i64 : addr -> int -> int64 -> unit = "flan_poke_i64"
external poke_f64 : addr -> int -> float -> unit = "flan_poke_f64"
external poke_ptr : addr -> int -> addr -> unit = "flan_poke_ptr"
external poke_bytes : addr -> int -> string -> unit = "flan_poke_bytes"
external peek_i32 : addr -> int -> int32 = "flan_peek_i32"
external peek_i64 : addr -> int -> int64 = "flan_peek_i64"
external peek_f64 : addr -> int -> float = "flan_peek_f64"
external peek_ptr : addr -> int -> addr = "flan_peek_ptr"
external peek_bytes : addr -> int -> int -> string = "flan_peek_bytes"
(* Every allocation a macro call makes on this side, kept so the whole lot can
be released at once. A macro's *own* allocations are the macro process's --
which is this process -- and are leaked on purpose: a returned Form points
into them, and the compiler reads it after the call returns. An expansion is
bounded by the size of the program being compiled, so leaking it costs what
holding the program costs. *)
let owned : addr list ref = ref []
let take n =
let p = alloc n in
owned := p :: !owned;
p
let release () =
List.iter free !owned;
owned := []