@@ -231,7 +231,7 @@ let init_shape id modl =
231
231
and init_shape_struct env sg =
232
232
match sg with
233
233
[] -> []
234
- | Sig_value (subid , {val_kind =Val_reg ; val_type =ty ; val_loc =loc } ) :: rem ->
234
+ | Sig_value (subid , {val_kind =Val_reg ; val_type =ty ; val_loc =loc } , _ ) :: rem ->
235
235
let init_v =
236
236
match Ctype. expand_head env ty with
237
237
{desc = Tarrow (_ ,_ ,_ ,_ )} ->
@@ -242,23 +242,23 @@ let init_shape id modl =
242
242
let not_a_function = {reason= Unsafe_non_function ; loc; subid } in
243
243
raise (Initialization_failure not_a_function) in
244
244
init_v :: init_shape_struct env rem
245
- | Sig_value (_ , {val_kind =Val_prim _ } ) :: rem ->
245
+ | Sig_value (_ , {val_kind =Val_prim _ } , _ ) :: rem ->
246
246
init_shape_struct env rem
247
247
| Sig_value _ :: _rem ->
248
248
assert false
249
- | Sig_type (id , tdecl , _ ) :: rem ->
249
+ | Sig_type (id , tdecl , _ , _ ) :: rem ->
250
250
init_shape_struct (Env. add_type ~check: false id tdecl env) rem
251
- | Sig_typext (subid , {ext_loc =loc } ,_ ) :: _ ->
251
+ | Sig_typext (subid , {ext_loc =loc } ,_ , _ ) :: _ ->
252
252
raise (Initialization_failure {reason= Unsafe_typext ; loc; subid})
253
- | Sig_module (id , Mp_present, md , _ ) :: rem ->
253
+ | Sig_module (id , Mp_present, md , _ , _ ) :: rem ->
254
254
init_shape_mod id md.md_loc env md.md_type ::
255
255
init_shape_struct (Env. add_module_declaration ~check: false
256
256
id Mp_present md env) rem
257
- | Sig_module (id , Mp_absent, md , _ ) :: rem ->
257
+ | Sig_module (id , Mp_absent, md , _ , _ ) :: rem ->
258
258
init_shape_struct
259
259
(Env. add_module_declaration ~check: false
260
260
id Mp_absent md env) rem
261
- | Sig_modtype (id , minfo ) :: rem ->
261
+ | Sig_modtype (id , minfo , _ ) :: rem ->
262
262
init_shape_struct (Env. add_modtype id minfo env) rem
263
263
| Sig_class _ :: rem ->
264
264
Const_pointer 2 (* camlinternalMod.Class *)
@@ -376,22 +376,6 @@ let compile_recmodule compile_rhs bindings cont =
376
376
bindings))
377
377
cont
378
378
379
- (* Extract the list of "value" identifiers bound by a signature.
380
- "Value" identifiers are identifiers for signature components that
381
- correspond to a run-time value: values, extensions, modules, classes.
382
- Note: manifest primitives do not correspond to a run-time value! *)
383
-
384
- let rec bound_value_identifiers = function
385
- [] -> []
386
- | Sig_value (id , {val_kind = Val_reg } ) :: rem ->
387
- id :: bound_value_identifiers rem
388
- | Sig_typext (id , _ , _ ) :: rem -> id :: bound_value_identifiers rem
389
- | Sig_module (id , Mp_present, _ , _ ) :: rem ->
390
- id :: bound_value_identifiers rem
391
- | Sig_class (id , _ , _ ) :: rem -> id :: bound_value_identifiers rem
392
- | _ :: rem -> bound_value_identifiers rem
393
-
394
-
395
379
(* Code to translate class entries in a structure *)
396
380
397
381
let transl_class_bindings cl_list =
@@ -673,18 +657,38 @@ and transl_structure loc fields cc rootpath final_env = function
673
657
transl_module Tcoerce_none None modl, body),
674
658
size
675
659
660
+ | Tstr_open od ->
661
+ let pure = pure_module od.open_expr in
662
+ (* this optimization shouldn't be needed because Simplif would
663
+ actually remove the [Llet] when it's not used.
664
+ But since [scan_used_globals] runs before Simplif, we need to do
665
+ it. *)
666
+ begin match od.open_bound_items with
667
+ | [] when pure = Alias ->
668
+ transl_structure loc fields cc rootpath final_env rem
669
+ | _ ->
670
+ let ids = bound_value_identifiers od.open_bound_items in
671
+ let mid = Ident. create_local " open" in
672
+ let rec rebind_idents pos newfields = function
673
+ [] ->
674
+ transl_structure loc newfields cc rootpath final_env rem
675
+ | id :: ids ->
676
+ let body, size =
677
+ rebind_idents (pos + 1 ) (id :: newfields) ids
678
+ in
679
+ Llet (Alias , Pgenval , id,
680
+ Lprim (Pfield pos, [Lvar mid], od.open_loc), body),
681
+ size
682
+ in
683
+ let body, size = rebind_idents 0 fields ids in
684
+ Llet (pure, Pgenval , mid,
685
+ transl_module Tcoerce_none None od.open_expr, body), size
686
+ end
676
687
| Tstr_modtype _
677
- | Tstr_open _
678
688
| Tstr_class_type _
679
689
| Tstr_attribute _ ->
680
690
transl_structure loc fields cc rootpath final_env rem
681
691
682
- and pure_module m =
683
- match m.mod_desc with
684
- Tmod_ident _ -> Alias
685
- | Tmod_constraint (m ,_ ,_ ,_ ) -> pure_module m
686
- | _ -> Strict
687
-
688
692
(* Update forward declaration in Translcore *)
689
693
let _ =
690
694
Translcore. transl_module := transl_module
@@ -771,7 +775,8 @@ let rec defined_idents = function
771
775
| Tstr_recmodule decls ->
772
776
List. map (fun mb -> mb.mb_id) decls @ defined_idents rem
773
777
| Tstr_modtype _ -> defined_idents rem
774
- | Tstr_open _ -> defined_idents rem
778
+ | Tstr_open od ->
779
+ bound_value_identifiers od.open_bound_items @ defined_idents rem
775
780
| Tstr_class cl_list ->
776
781
List. map (fun (ci , _ ) -> ci.ci_id_class) cl_list @ defined_idents rem
777
782
| Tstr_class_type _ -> defined_idents rem
@@ -793,7 +798,12 @@ let rec more_idents = function
793
798
| Tstr_exception _ -> more_idents rem
794
799
| Tstr_recmodule _ -> more_idents rem
795
800
| Tstr_modtype _ -> more_idents rem
796
- | Tstr_open _ -> more_idents rem
801
+ | Tstr_open od ->
802
+ let rest = more_idents rem in
803
+ begin match od.open_expr.mod_desc with
804
+ | Tmod_structure str -> all_idents str.str_items @ rest
805
+ | _ -> rest
806
+ end
797
807
| Tstr_class _ -> more_idents rem
798
808
| Tstr_class_type _ -> more_idents rem
799
809
| Tstr_include {incl_mod= {mod_desc =
@@ -827,7 +837,15 @@ and all_idents = function
827
837
| Tstr_recmodule decls ->
828
838
List. map (fun mb -> mb.mb_id) decls @ all_idents rem
829
839
| Tstr_modtype _ -> all_idents rem
830
- | Tstr_open _ -> all_idents rem
840
+ | Tstr_open od ->
841
+ let rest = all_idents rem in
842
+ begin match od.open_expr.mod_desc with
843
+ | Tmod_structure str ->
844
+ bound_value_identifiers od.open_bound_items
845
+ @ all_idents str.str_items
846
+ @ rest
847
+ | _ -> bound_value_identifiers od.open_bound_items @ rest
848
+ end
831
849
| Tstr_class cl_list ->
832
850
List. map (fun (ci , _ ) -> ci.ci_id_class) cl_list @ all_idents rem
833
851
| Tstr_class_type _ -> all_idents rem
@@ -1076,8 +1094,52 @@ let transl_store_structure glob map prims aliases str =
1076
1094
Lambda. subst no_env_update subst
1077
1095
(transl_module Tcoerce_none None modl),
1078
1096
store_idents 0 ids)
1097
+ | Tstr_open od ->
1098
+ begin match od.open_expr.mod_desc with
1099
+ | Tmod_structure str ->
1100
+ let lam =
1101
+ transl_store rootpath subst lambda_unit str.str_items
1102
+ in
1103
+ let ids = Array. of_list (defined_idents str.str_items) in
1104
+ let ids0 = bound_value_identifiers od.open_bound_items in
1105
+ let subst = ! transl_store_subst in
1106
+ let rec store_idents pos = function
1107
+ | [] -> transl_store rootpath subst cont rem
1108
+ | id :: idl ->
1109
+ Llet (Alias , Pgenval , id, Lvar ids.(pos),
1110
+ Lsequence (store_ident od.open_loc id,
1111
+ store_idents (pos + 1 ) idl))
1112
+ in
1113
+ Lsequence (lam, Lambda. subst no_env_update subst
1114
+ (store_idents 0 ids0))
1115
+ | _ ->
1116
+ let pure = pure_module od.open_expr in
1117
+ (* this optimization shouldn't be needed because Simplif would
1118
+ actually remove the [Llet] when it's not used.
1119
+ But since [scan_used_globals] runs before Simplif, we need to
1120
+ do it. *)
1121
+ match od.open_bound_items with
1122
+ | [] when pure = Alias -> transl_store rootpath subst cont rem
1123
+ | _ ->
1124
+ let ids = bound_value_identifiers od.open_bound_items in
1125
+ let mid = Ident. create_local " open" in
1126
+ let loc = od.open_loc in
1127
+ let rec store_idents pos = function
1128
+ [] ->
1129
+ transl_store rootpath (add_idents true ids subst) cont
1130
+ rem
1131
+ | id :: idl ->
1132
+ Llet (Alias , Pgenval , id, Lprim (Pfield pos, [Lvar mid],
1133
+ loc),
1134
+ Lsequence (store_ident loc id,
1135
+ store_idents (pos + 1 ) idl))
1136
+ in
1137
+ Llet (pure, Pgenval , mid,
1138
+ Lambda. subst no_env_update subst
1139
+ (transl_module Tcoerce_none None od.open_expr),
1140
+ store_idents 0 ids)
1141
+ end
1079
1142
| Tstr_modtype _
1080
- | Tstr_open _
1081
1143
| Tstr_class_type _
1082
1144
| Tstr_attribute _ ->
1083
1145
transl_store rootpath subst cont rem
@@ -1319,8 +1381,29 @@ let transl_toplevel_item item =
1319
1381
| Tstr_primitive descr ->
1320
1382
record_primitive descr.val_val;
1321
1383
lambda_unit
1384
+ | Tstr_open od ->
1385
+ let pure = pure_module od.open_expr in
1386
+ (* this optimization shouldn't be needed because Simplif would
1387
+ actually remove the [Llet] when it's not used.
1388
+ But since [scan_used_globals] runs before Simplif, we need to do
1389
+ it. *)
1390
+ begin match od.open_bound_items with
1391
+ | [] when pure = Alias -> lambda_unit
1392
+ | _ ->
1393
+ let ids = bound_value_identifiers od.open_bound_items in
1394
+ let mid = Ident. create_local " open" in
1395
+ let rec set_idents pos = function
1396
+ [] ->
1397
+ lambda_unit
1398
+ | id :: ids ->
1399
+ Lsequence (toploop_setvalue id
1400
+ (Lprim (Pfield pos, [Lvar mid], Location. none)),
1401
+ set_idents (pos + 1 ) ids)
1402
+ in
1403
+ Llet (pure, Pgenval , mid,
1404
+ transl_module Tcoerce_none None od.open_expr, set_idents 0 ids)
1405
+ end
1322
1406
| Tstr_modtype _
1323
- | Tstr_open _
1324
1407
| Tstr_module {mb_presence= Mp_absent }
1325
1408
| Tstr_type _
1326
1409
| Tstr_class_type _
0 commit comments