This reverts commit 709f292a694a7f634b807980c1c5b6e5ec81c429, reversing changes made to 50b3feaa86a10689cd7ff1c03714b901ab4091c2.
49 lines
2.0 KiB
OCaml
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 := []
|