2016-01-26 07:43:24 -08:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
2016-02-18 07:11:59 -08:00
|
|
|
(* OCaml *)
|
2016-01-26 07:43:24 -08:00
|
|
|
(* *)
|
|
|
|
(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *)
|
|
|
|
(* Pierre Chambart, OCamlPro *)
|
|
|
|
(* Mark Shinwell and Leo White, Jane Street Europe *)
|
|
|
|
(* *)
|
|
|
|
(* Copyright 2010 Institut National de Recherche en Informatique et *)
|
|
|
|
(* en Automatique *)
|
|
|
|
(* Copyright 2013--2016 OCamlPro SAS *)
|
|
|
|
(* Copyright 2014--2016 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 *)
|
2016-02-18 07:11:59 -08:00
|
|
|
(* special exception on linking described in the file LICENSE. *)
|
2016-01-26 07:43:24 -08:00
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
1995-08-09 08:06:35 -07:00
|
|
|
|
1995-07-02 09:41:48 -07:00
|
|
|
(* Compilation environments for compilation units *)
|
|
|
|
|
2016-01-26 07:43:24 -08:00
|
|
|
[@@@ocaml.warning "+a-4-9-40-41-42"]
|
|
|
|
|
1995-07-02 09:41:48 -07:00
|
|
|
open Config
|
2010-05-19 04:29:38 -07:00
|
|
|
open Cmx_format
|
1995-07-02 09:41:48 -07:00
|
|
|
|
|
|
|
type error =
|
|
|
|
Not_a_unit_info of string
|
|
|
|
| Corrupted_unit_info of string
|
2013-04-29 07:57:38 -07:00
|
|
|
| Illegal_renaming of string * string * string
|
1995-07-02 09:41:48 -07:00
|
|
|
|
|
|
|
exception Error of error
|
|
|
|
|
2005-08-01 08:51:09 -07:00
|
|
|
let global_infos_table =
|
|
|
|
(Hashtbl.create 17 : (string, unit_infos option) Hashtbl.t)
|
2016-01-26 07:43:24 -08:00
|
|
|
let export_infos_table =
|
|
|
|
(Hashtbl.create 10 : (string, Export_info.t) Hashtbl.t)
|
1995-07-02 09:41:48 -07:00
|
|
|
|
2016-01-21 16:21:49 -08:00
|
|
|
let imported_sets_of_closures_table =
|
|
|
|
(Set_of_closures_id.Tbl.create 10
|
2018-04-06 06:26:43 -07:00
|
|
|
: Simple_value_approx.function_declarations option
|
|
|
|
Set_of_closures_id.Tbl.t)
|
2016-01-21 16:21:49 -08:00
|
|
|
|
2014-03-06 09:03:16 -08:00
|
|
|
module CstMap =
|
|
|
|
Map.Make(struct
|
|
|
|
type t = Clambda.ustructured_constant
|
2014-05-25 09:46:23 -07:00
|
|
|
let compare = Clambda.compare_structured_constants
|
2018-08-27 04:42:14 -07:00
|
|
|
(* PR#6442: it is incorrect to use Stdlib.compare on values of type t
|
2014-05-25 09:46:23 -07:00
|
|
|
because it compares "0.0" and "-0.0" equal. *)
|
2014-03-06 09:03:16 -08:00
|
|
|
end)
|
|
|
|
|
2019-09-17 01:22:08 -07:00
|
|
|
module SymMap = Misc.Stdlib.String.Map
|
|
|
|
|
2014-03-06 09:03:16 -08:00
|
|
|
type structured_constants =
|
|
|
|
{
|
|
|
|
strcst_shared: string CstMap.t;
|
2019-09-17 01:22:08 -07:00
|
|
|
strcst_all: Clambda.ustructured_constant SymMap.t;
|
2014-03-06 09:03:16 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
let structured_constants_empty =
|
|
|
|
{
|
|
|
|
strcst_shared = CstMap.empty;
|
2019-09-17 01:22:08 -07:00
|
|
|
strcst_all = SymMap.empty;
|
2014-03-06 09:03:16 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
let structured_constants = ref structured_constants_empty
|
|
|
|
|
|
|
|
|
|
|
|
let exported_constants = Hashtbl.create 17
|
2011-03-29 00:58:53 -07:00
|
|
|
|
2016-01-26 07:43:24 -08:00
|
|
|
let merged_environment = ref Export_info.empty
|
|
|
|
|
|
|
|
let default_ui_export_info =
|
|
|
|
if Config.flambda then
|
|
|
|
Cmx_format.Flambda Export_info.empty
|
|
|
|
else
|
|
|
|
Cmx_format.Clambda Value_unknown
|
|
|
|
|
1995-07-02 09:41:48 -07:00
|
|
|
let current_unit =
|
|
|
|
{ ui_name = "";
|
2005-08-01 08:51:09 -07:00
|
|
|
ui_symbol = "";
|
2002-02-08 08:55:44 -08:00
|
|
|
ui_defines = [];
|
1995-10-09 06:37:11 -07:00
|
|
|
ui_imports_cmi = [];
|
|
|
|
ui_imports_cmx = [];
|
1995-07-02 09:41:48 -07:00
|
|
|
ui_curry_fun = [];
|
1996-04-18 09:26:54 -07:00
|
|
|
ui_apply_fun = [];
|
2004-05-26 04:10:52 -07:00
|
|
|
ui_send_fun = [];
|
2016-01-26 07:43:24 -08:00
|
|
|
ui_force_link = false;
|
|
|
|
ui_export_info = default_ui_export_info }
|
1995-07-02 09:41:48 -07:00
|
|
|
|
2005-08-01 08:51:09 -07:00
|
|
|
let symbolname_for_pack pack name =
|
|
|
|
match pack with
|
|
|
|
| None -> name
|
|
|
|
| Some p ->
|
|
|
|
let b = Buffer.create 64 in
|
|
|
|
for i = 0 to String.length p - 1 do
|
|
|
|
match p.[i] with
|
|
|
|
| '.' -> Buffer.add_string b "__"
|
|
|
|
| c -> Buffer.add_char b c
|
|
|
|
done;
|
|
|
|
Buffer.add_string b "__";
|
|
|
|
Buffer.add_string b name;
|
|
|
|
Buffer.contents b
|
|
|
|
|
2016-01-26 07:43:24 -08:00
|
|
|
let unit_id_from_name name = Ident.create_persistent name
|
|
|
|
|
2016-01-21 16:21:49 -08:00
|
|
|
let concat_symbol unitname id =
|
|
|
|
unitname ^ "__" ^ id
|
|
|
|
|
|
|
|
let make_symbol ?(unitname = current_unit.ui_symbol) idopt =
|
|
|
|
let prefix = "caml" ^ unitname in
|
|
|
|
match idopt with
|
|
|
|
| None -> prefix
|
|
|
|
| Some id -> concat_symbol prefix id
|
|
|
|
|
|
|
|
let current_unit_linkage_name () =
|
|
|
|
Linkage_name.create (make_symbol ~unitname:current_unit.ui_symbol None)
|
2011-03-29 00:58:53 -07:00
|
|
|
|
2017-02-06 14:26:24 -08:00
|
|
|
let reset ?packname name =
|
2005-08-01 08:51:09 -07:00
|
|
|
Hashtbl.clear global_infos_table;
|
2016-01-21 16:21:49 -08:00
|
|
|
Set_of_closures_id.Tbl.clear imported_sets_of_closures_table;
|
2005-08-01 08:51:09 -07:00
|
|
|
let symbol = symbolname_for_pack packname name in
|
1995-07-02 09:41:48 -07:00
|
|
|
current_unit.ui_name <- name;
|
2005-08-01 08:51:09 -07:00
|
|
|
current_unit.ui_symbol <- symbol;
|
|
|
|
current_unit.ui_defines <- [symbol];
|
1995-10-09 06:37:11 -07:00
|
|
|
current_unit.ui_imports_cmi <- [];
|
|
|
|
current_unit.ui_imports_cmx <- [];
|
1995-07-02 09:41:48 -07:00
|
|
|
current_unit.ui_curry_fun <- [];
|
1996-04-18 09:26:54 -07:00
|
|
|
current_unit.ui_apply_fun <- [];
|
2004-05-26 04:10:52 -07:00
|
|
|
current_unit.ui_send_fun <- [];
|
2017-01-13 07:30:58 -08:00
|
|
|
current_unit.ui_force_link <- !Clflags.link_everything;
|
2014-03-06 09:03:16 -08:00
|
|
|
Hashtbl.clear exported_constants;
|
2016-01-21 16:21:49 -08:00
|
|
|
structured_constants := structured_constants_empty;
|
2016-01-26 07:43:24 -08:00
|
|
|
current_unit.ui_export_info <- default_ui_export_info;
|
|
|
|
merged_environment := Export_info.empty;
|
|
|
|
Hashtbl.clear export_infos_table;
|
2016-01-21 16:21:49 -08:00
|
|
|
let compilation_unit =
|
|
|
|
Compilation_unit.create
|
|
|
|
(Ident.create_persistent name)
|
|
|
|
(current_unit_linkage_name ())
|
|
|
|
in
|
|
|
|
Compilation_unit.set_current compilation_unit
|
1995-07-02 09:41:48 -07:00
|
|
|
|
2005-08-01 08:51:09 -07:00
|
|
|
let current_unit_infos () =
|
|
|
|
current_unit
|
|
|
|
|
1995-07-02 09:41:48 -07:00
|
|
|
let current_unit_name () =
|
2004-01-05 12:26:19 -08:00
|
|
|
current_unit.ui_name
|
|
|
|
|
2013-07-18 09:09:20 -07:00
|
|
|
let symbol_in_current_unit name =
|
|
|
|
let prefix = "caml" ^ current_unit.ui_symbol in
|
2014-04-12 03:17:02 -07:00
|
|
|
name = prefix ||
|
2013-07-18 09:09:20 -07:00
|
|
|
(let lp = String.length prefix in
|
|
|
|
String.length name >= 2 + lp
|
|
|
|
&& String.sub name 0 lp = prefix
|
|
|
|
&& name.[lp] = '_'
|
|
|
|
&& name.[lp + 1] = '_')
|
|
|
|
|
1995-07-11 11:03:29 -07:00
|
|
|
let read_unit_info filename =
|
1995-07-02 09:41:48 -07:00
|
|
|
let ic = open_in_bin filename in
|
|
|
|
try
|
2014-04-29 04:56:17 -07:00
|
|
|
let buffer = really_input_string ic (String.length cmx_magic_number) in
|
1995-07-02 09:41:48 -07:00
|
|
|
if buffer <> cmx_magic_number then begin
|
|
|
|
close_in ic;
|
|
|
|
raise(Error(Not_a_unit_info filename))
|
|
|
|
end;
|
|
|
|
let ui = (input_value ic : unit_infos) in
|
1995-10-09 06:37:11 -07:00
|
|
|
let crc = Digest.input ic in
|
1995-07-02 09:41:48 -07:00
|
|
|
close_in ic;
|
1995-07-11 11:03:29 -07:00
|
|
|
(ui, crc)
|
1995-07-02 09:41:48 -07:00
|
|
|
with End_of_file | Failure _ ->
|
|
|
|
close_in ic;
|
|
|
|
raise(Error(Corrupted_unit_info(filename)))
|
|
|
|
|
2007-11-06 07:16:56 -08:00
|
|
|
let read_library_info filename =
|
|
|
|
let ic = open_in_bin filename in
|
2014-04-29 04:56:17 -07:00
|
|
|
let buffer = really_input_string ic (String.length cmxa_magic_number) in
|
2007-11-06 07:16:56 -08:00
|
|
|
if buffer <> cmxa_magic_number then
|
|
|
|
raise(Error(Not_a_unit_info filename));
|
|
|
|
let infos = (input_value ic : library_infos) in
|
|
|
|
close_in ic;
|
|
|
|
infos
|
|
|
|
|
|
|
|
|
2005-08-01 08:51:09 -07:00
|
|
|
(* Read and cache info on global identifiers *)
|
1995-07-02 09:41:48 -07:00
|
|
|
|
2013-04-29 07:57:38 -07:00
|
|
|
let get_global_info global_ident = (
|
1995-07-02 09:41:48 -07:00
|
|
|
let modname = Ident.name global_ident in
|
2015-12-16 04:35:12 -08:00
|
|
|
if modname = current_unit.ui_name then
|
2005-08-01 08:51:09 -07:00
|
|
|
Some current_unit
|
1999-02-04 02:31:16 -08:00
|
|
|
else begin
|
|
|
|
try
|
2005-08-01 08:51:09 -07:00
|
|
|
Hashtbl.find global_infos_table modname
|
1999-02-04 02:31:16 -08:00
|
|
|
with Not_found ->
|
2005-08-01 08:51:09 -07:00
|
|
|
let (infos, crc) =
|
2015-11-29 08:23:38 -08:00
|
|
|
if Env.is_imported_opaque modname then (None, None)
|
|
|
|
else begin
|
|
|
|
try
|
|
|
|
let filename =
|
2018-09-18 06:49:18 -07:00
|
|
|
Load_path.find_uncap (modname ^ ".cmx") in
|
2015-11-29 08:23:38 -08:00
|
|
|
let (ui, crc) = read_unit_info filename in
|
|
|
|
if ui.ui_name <> modname then
|
|
|
|
raise(Error(Illegal_renaming(modname, ui.ui_name, filename)));
|
|
|
|
(Some ui, Some crc)
|
|
|
|
with Not_found ->
|
|
|
|
let warn = Warnings.No_cmx_file modname in
|
|
|
|
Location.prerr_warning Location.none warn;
|
|
|
|
(None, None)
|
|
|
|
end
|
|
|
|
in
|
1999-02-04 02:31:16 -08:00
|
|
|
current_unit.ui_imports_cmx <-
|
|
|
|
(modname, crc) :: current_unit.ui_imports_cmx;
|
2005-08-01 08:51:09 -07:00
|
|
|
Hashtbl.add global_infos_table modname infos;
|
|
|
|
infos
|
|
|
|
end
|
2013-04-29 07:57:38 -07:00
|
|
|
)
|
2005-08-01 08:51:09 -07:00
|
|
|
|
2006-10-17 05:33:58 -07:00
|
|
|
let cache_unit_info ui =
|
|
|
|
Hashtbl.add global_infos_table ui.ui_name (Some ui)
|
|
|
|
|
2005-08-01 08:51:09 -07:00
|
|
|
(* Return the approximation of a global identifier *)
|
|
|
|
|
2016-01-26 07:43:24 -08:00
|
|
|
let get_clambda_approx ui =
|
|
|
|
assert(not Config.flambda);
|
|
|
|
match ui.ui_export_info with
|
|
|
|
| Flambda _ -> assert false
|
|
|
|
| Clambda approx -> approx
|
2007-11-06 07:16:56 -08:00
|
|
|
|
2016-01-26 07:43:24 -08:00
|
|
|
let toplevel_approx :
|
|
|
|
(string, Clambda.value_approximation) Hashtbl.t = Hashtbl.create 16
|
|
|
|
|
|
|
|
let record_global_approx_toplevel () =
|
|
|
|
Hashtbl.add toplevel_approx current_unit.ui_name
|
|
|
|
(get_clambda_approx current_unit)
|
2007-11-06 07:16:56 -08:00
|
|
|
|
2005-08-01 08:51:09 -07:00
|
|
|
let global_approx id =
|
2018-08-28 09:07:11 -07:00
|
|
|
if Ident.is_predef id then Clambda.Value_unknown
|
2007-11-06 07:16:56 -08:00
|
|
|
else try Hashtbl.find toplevel_approx (Ident.name id)
|
2010-01-22 04:48:24 -08:00
|
|
|
with Not_found ->
|
2007-11-06 07:16:56 -08:00
|
|
|
match get_global_info id with
|
2016-01-26 07:43:24 -08:00
|
|
|
| None -> Clambda.Value_unknown
|
|
|
|
| Some ui -> get_clambda_approx ui
|
2005-08-01 08:51:09 -07:00
|
|
|
|
|
|
|
(* Return the symbol used to refer to a global identifier *)
|
|
|
|
|
|
|
|
let symbol_for_global id =
|
2018-08-28 09:07:11 -07:00
|
|
|
if Ident.is_predef id then
|
2005-08-01 08:51:09 -07:00
|
|
|
"caml_exn_" ^ Ident.name id
|
|
|
|
else begin
|
2015-12-31 02:03:48 -08:00
|
|
|
let unitname = Ident.name id in
|
|
|
|
match
|
|
|
|
try ignore (Hashtbl.find toplevel_approx unitname); None
|
|
|
|
with Not_found -> get_global_info id
|
|
|
|
with
|
2005-08-01 08:51:09 -07:00
|
|
|
| None -> make_symbol ~unitname:(Ident.name id) None
|
|
|
|
| Some ui -> make_symbol ~unitname:ui.ui_symbol None
|
1999-02-04 02:31:16 -08:00
|
|
|
end
|
1995-07-02 09:41:48 -07:00
|
|
|
|
|
|
|
(* Register the approximation of the module being compiled *)
|
|
|
|
|
2016-01-21 16:21:49 -08:00
|
|
|
let unit_for_global id =
|
|
|
|
let sym_label = Linkage_name.create (symbol_for_global id) in
|
|
|
|
Compilation_unit.create id sym_label
|
|
|
|
|
|
|
|
let predefined_exception_compilation_unit =
|
|
|
|
Compilation_unit.create (Ident.create_persistent "__dummy__")
|
|
|
|
(Linkage_name.create "__dummy__")
|
|
|
|
|
|
|
|
let is_predefined_exception sym =
|
|
|
|
Compilation_unit.equal
|
|
|
|
predefined_exception_compilation_unit
|
|
|
|
(Symbol.compilation_unit sym)
|
|
|
|
|
|
|
|
let symbol_for_global' id =
|
|
|
|
let sym_label = Linkage_name.create (symbol_for_global id) in
|
2018-08-28 09:07:11 -07:00
|
|
|
if Ident.is_predef id then
|
2018-04-09 00:43:47 -07:00
|
|
|
Symbol.of_global_linkage predefined_exception_compilation_unit sym_label
|
2016-01-21 16:21:49 -08:00
|
|
|
else
|
2018-04-09 00:43:47 -07:00
|
|
|
Symbol.of_global_linkage (unit_for_global id) sym_label
|
2016-01-21 16:21:49 -08:00
|
|
|
|
1995-07-02 09:41:48 -07:00
|
|
|
let set_global_approx approx =
|
2016-01-26 07:43:24 -08:00
|
|
|
assert(not Config.flambda);
|
|
|
|
current_unit.ui_export_info <- Clambda approx
|
|
|
|
|
|
|
|
(* Exporting and importing cross module information *)
|
|
|
|
|
|
|
|
let get_flambda_export_info ui =
|
|
|
|
assert(Config.flambda);
|
|
|
|
match ui.ui_export_info with
|
|
|
|
| Clambda _ -> assert false
|
|
|
|
| Flambda ei -> ei
|
|
|
|
|
|
|
|
let set_export_info export_info =
|
|
|
|
assert(Config.flambda);
|
|
|
|
current_unit.ui_export_info <- Flambda export_info
|
|
|
|
|
|
|
|
let approx_for_global comp_unit =
|
|
|
|
let id = Compilation_unit.get_persistent_ident comp_unit in
|
|
|
|
if (Compilation_unit.equal
|
|
|
|
predefined_exception_compilation_unit
|
|
|
|
comp_unit)
|
2018-08-28 09:07:11 -07:00
|
|
|
|| Ident.is_predef id
|
2016-01-26 07:43:24 -08:00
|
|
|
|| not (Ident.global id)
|
|
|
|
then invalid_arg (Format.asprintf "approx_for_global %a" Ident.print id);
|
|
|
|
let modname = Ident.name id in
|
2018-04-08 23:46:50 -07:00
|
|
|
match Hashtbl.find export_infos_table modname with
|
|
|
|
| otherwise -> Some otherwise
|
|
|
|
| exception Not_found ->
|
|
|
|
match get_global_info id with
|
|
|
|
| None -> None
|
|
|
|
| Some ui ->
|
|
|
|
let exported = get_flambda_export_info ui in
|
|
|
|
Hashtbl.add export_infos_table modname exported;
|
|
|
|
merged_environment := Export_info.merge !merged_environment exported;
|
|
|
|
Some exported
|
2016-01-26 07:43:24 -08:00
|
|
|
|
|
|
|
let approx_env () = !merged_environment
|
2016-01-21 16:21:49 -08:00
|
|
|
|
1995-07-02 09:41:48 -07:00
|
|
|
(* Record that a currying function or application function is needed *)
|
|
|
|
|
|
|
|
let need_curry_fun n =
|
|
|
|
if not (List.mem n current_unit.ui_curry_fun) then
|
|
|
|
current_unit.ui_curry_fun <- n :: current_unit.ui_curry_fun
|
|
|
|
|
|
|
|
let need_apply_fun n =
|
2016-01-26 07:43:24 -08:00
|
|
|
assert(n > 0);
|
1995-07-02 09:41:48 -07:00
|
|
|
if not (List.mem n current_unit.ui_apply_fun) then
|
|
|
|
current_unit.ui_apply_fun <- n :: current_unit.ui_apply_fun
|
|
|
|
|
2004-05-26 04:10:52 -07:00
|
|
|
let need_send_fun n =
|
|
|
|
if not (List.mem n current_unit.ui_send_fun) then
|
|
|
|
current_unit.ui_send_fun <- n :: current_unit.ui_send_fun
|
|
|
|
|
1995-07-02 09:41:48 -07:00
|
|
|
(* Write the description of the current unit *)
|
|
|
|
|
2002-02-08 08:55:44 -08:00
|
|
|
let write_unit_info info filename =
|
1995-07-02 09:41:48 -07:00
|
|
|
let oc = open_out_bin filename in
|
|
|
|
output_string oc cmx_magic_number;
|
2002-02-08 08:55:44 -08:00
|
|
|
output_value oc info;
|
1995-07-02 09:41:48 -07:00
|
|
|
flush oc;
|
1995-10-09 06:37:11 -07:00
|
|
|
let crc = Digest.file filename in
|
|
|
|
Digest.output oc crc;
|
1995-07-02 09:41:48 -07:00
|
|
|
close_out oc
|
|
|
|
|
2002-02-08 08:55:44 -08:00
|
|
|
let save_unit_info filename =
|
2014-05-06 17:34:20 -07:00
|
|
|
current_unit.ui_imports_cmi <- Env.imports();
|
2002-02-08 08:55:44 -08:00
|
|
|
write_unit_info current_unit filename
|
|
|
|
|
2016-01-21 16:21:49 -08:00
|
|
|
let current_unit () =
|
|
|
|
match Compilation_unit.get_current () with
|
|
|
|
| Some current_unit -> current_unit
|
|
|
|
| None -> Misc.fatal_error "Compilenv.current_unit"
|
|
|
|
|
|
|
|
let current_unit_symbol () =
|
2018-04-09 00:43:47 -07:00
|
|
|
Symbol.of_global_linkage (current_unit ()) (current_unit_linkage_name ())
|
2011-03-29 00:58:53 -07:00
|
|
|
|
|
|
|
let const_label = ref 0
|
|
|
|
|
|
|
|
let new_const_symbol () =
|
|
|
|
incr const_label;
|
2018-08-30 10:15:32 -07:00
|
|
|
make_symbol (Some (Int.to_string !const_label))
|
2011-03-29 00:58:53 -07:00
|
|
|
|
2014-03-06 09:03:16 -08:00
|
|
|
let snapshot () = !structured_constants
|
|
|
|
let backtrack s = structured_constants := s
|
2011-03-29 00:58:53 -07:00
|
|
|
|
2014-03-06 09:03:16 -08:00
|
|
|
let new_structured_constant cst ~shared =
|
|
|
|
let {strcst_shared; strcst_all} = !structured_constants in
|
|
|
|
if shared then
|
|
|
|
try
|
|
|
|
CstMap.find cst strcst_shared
|
|
|
|
with Not_found ->
|
|
|
|
let lbl = new_const_symbol() in
|
|
|
|
structured_constants :=
|
|
|
|
{
|
|
|
|
strcst_shared = CstMap.add cst lbl strcst_shared;
|
2019-09-17 01:22:08 -07:00
|
|
|
strcst_all = SymMap.add lbl cst strcst_all;
|
2014-03-06 09:03:16 -08:00
|
|
|
};
|
|
|
|
lbl
|
|
|
|
else
|
|
|
|
let lbl = new_const_symbol() in
|
|
|
|
structured_constants :=
|
|
|
|
{
|
|
|
|
strcst_shared;
|
2019-09-17 01:22:08 -07:00
|
|
|
strcst_all = SymMap.add lbl cst strcst_all;
|
2014-03-06 09:03:16 -08:00
|
|
|
};
|
|
|
|
lbl
|
|
|
|
|
|
|
|
let add_exported_constant s =
|
|
|
|
Hashtbl.replace exported_constants s ()
|
|
|
|
|
2016-01-06 09:35:27 -08:00
|
|
|
let clear_structured_constants () =
|
|
|
|
structured_constants := structured_constants_empty
|
|
|
|
|
2019-09-17 01:22:08 -07:00
|
|
|
let structured_constant_of_symbol s =
|
|
|
|
SymMap.find_opt s (!structured_constants).strcst_all
|
|
|
|
|
2014-03-06 09:03:16 -08:00
|
|
|
let structured_constants () =
|
2018-10-03 08:09:46 -07:00
|
|
|
let provenance : Clambda.usymbol_provenance =
|
|
|
|
{ original_idents = [];
|
|
|
|
module_path =
|
|
|
|
Path.Pident (Ident.create_persistent (current_unit_name ()));
|
|
|
|
}
|
|
|
|
in
|
2019-09-17 01:22:08 -07:00
|
|
|
SymMap.bindings (!structured_constants).strcst_all
|
|
|
|
|> List.map
|
2016-01-13 09:05:35 -08:00
|
|
|
(fun (symbol, definition) ->
|
2016-01-14 04:36:41 -08:00
|
|
|
{
|
|
|
|
Clambda.symbol;
|
2016-01-13 09:05:35 -08:00
|
|
|
exported = Hashtbl.mem exported_constants symbol;
|
|
|
|
definition;
|
2018-10-03 08:09:46 -07:00
|
|
|
provenance = Some provenance;
|
2016-01-13 09:05:35 -08:00
|
|
|
})
|
2011-03-29 00:58:53 -07:00
|
|
|
|
2016-01-21 16:21:49 -08:00
|
|
|
let closure_symbol fv =
|
|
|
|
let compilation_unit = Closure_id.get_compilation_unit fv in
|
|
|
|
let unitname =
|
|
|
|
Linkage_name.to_string (Compilation_unit.get_linkage_name compilation_unit)
|
|
|
|
in
|
|
|
|
let linkage_name =
|
|
|
|
concat_symbol unitname ((Closure_id.unique_name fv) ^ "_closure")
|
|
|
|
in
|
2018-04-09 00:43:47 -07:00
|
|
|
Symbol.of_global_linkage compilation_unit (Linkage_name.create linkage_name)
|
2016-01-21 16:21:49 -08:00
|
|
|
|
|
|
|
let function_label fv =
|
|
|
|
let compilation_unit = Closure_id.get_compilation_unit fv in
|
|
|
|
let unitname =
|
|
|
|
Linkage_name.to_string
|
|
|
|
(Compilation_unit.get_linkage_name compilation_unit)
|
|
|
|
in
|
|
|
|
(concat_symbol unitname (Closure_id.unique_name fv))
|
|
|
|
|
2016-06-02 05:38:33 -07:00
|
|
|
let require_global global_ident =
|
2018-08-28 09:07:11 -07:00
|
|
|
if not (Ident.is_predef global_ident) then
|
2016-06-02 05:38:33 -07:00
|
|
|
ignore (get_global_info global_ident : Cmx_format.unit_infos option)
|
|
|
|
|
1995-07-02 09:41:48 -07:00
|
|
|
(* Error report *)
|
|
|
|
|
2000-04-21 01:13:22 -07:00
|
|
|
open Format
|
1995-07-02 09:41:48 -07:00
|
|
|
|
2000-04-21 01:13:22 -07:00
|
|
|
let report_error ppf = function
|
|
|
|
| Not_a_unit_info filename ->
|
2012-03-07 09:50:17 -08:00
|
|
|
fprintf ppf "%a@ is not a compilation unit description."
|
|
|
|
Location.print_filename filename
|
1995-07-02 09:41:48 -07:00
|
|
|
| Corrupted_unit_info filename ->
|
2012-03-07 09:50:17 -08:00
|
|
|
fprintf ppf "Corrupted compilation unit description@ %a"
|
|
|
|
Location.print_filename filename
|
2013-04-29 07:57:38 -07:00
|
|
|
| Illegal_renaming(name, modname, filename) ->
|
2013-09-04 08:12:37 -07:00
|
|
|
fprintf ppf "%a@ contains the description for unit\
|
|
|
|
@ %s when %s was expected"
|
2013-04-29 07:57:38 -07:00
|
|
|
Location.print_filename filename name modname
|
2013-09-12 08:50:47 -07:00
|
|
|
|
|
|
|
let () =
|
|
|
|
Location.register_error_of_exn
|
|
|
|
(function
|
|
|
|
| Error err -> Some (Location.error_of_printer_file report_error err)
|
|
|
|
| _ -> None
|
|
|
|
)
|