(**************************************************************************)
(*                                                                        *)
(*                                 OCaml                                  *)
(*                                                                        *)
(*             Xavier Leroy, projet Cristal, INRIA Rocquencourt           *)
(*             Mark Shinwell and Leo White, Jane Street Europe            *)
(*                                                                        *)
(*   Copyright 1996 Institut National de Recherche en Informatique et     *)
(*     en Automatique.                                                    *)
(*   Copyright 2017--2018 Jane Street Group LLC                           *)
(*                                                                        *)
(*   All rights reserved.  This file is distributed under the terms of    *)
(*   the GNU Lesser General Public License version 2.1, with the          *)
(*   special exception on linking described in the file LICENSE.          *)
(*                                                                        *)
(**************************************************************************)

(** Interface for platform-specific dynlink providers.
    Note that this file needs to be a valid .mli file. *)

module type S = sig
  type handle

  module Unit_header : sig
    type t

    val name : t -> string
    val crc : t -> Digest.BLAKE128.t option

    val interface_imports : t -> (string * Digest.BLAKE128.t option) list
    val implementation_imports : t -> (string * Digest.BLAKE128.t option) list

    val defined_symbols : t -> string list
    val unsafe_module : t -> bool
  end

  val init : unit -> unit

  val is_native : bool

  val adapt_filename : Dynlink_types.filename -> Dynlink_types.filename

  val num_globals_inited : unit -> int

  val fold_initial_units
     : init:'a
    -> f:('a
      -> compunit:string
      -> interface:Digest.BLAKE128.t option
      -> implementation:
           (Digest.BLAKE128.t option * Dynlink_types.implem_state) option
      -> defined_symbols:string list
      -> 'a)
    -> 'a

  val load
     : filename:Dynlink_types.filename
    -> priv:bool
    -> handle * (Unit_header.t list)

  val run : Mutex.t -> handle -> unit_header:Unit_header.t -> priv:bool -> unit

  val unsafe_get_global_value : bytecode_or_asm_symbol:string -> Obj.t option

  val finish : handle -> unit
end
