@@ -46,13 +46,28 @@ let source_map_enabled = function
4646 | No_sourcemap -> false
4747 | Inline | File _ -> true
4848
49- let output_gen ~standalone ~custom_header ~build_info ~source_map output_file f =
49+ let output_gen
50+ ~write_shape
51+ ~standalone
52+ ~custom_header
53+ ~build_info
54+ ~source_map
55+ output_file
56+ f =
5057 let f chan k =
5158 let fmt = Pretty_print. to_out_channel chan in
5259 Driver. configure fmt;
5360 if standalone then header ~custom_header fmt;
5461 if Config.Flag. header () then jsoo_header fmt build_info;
55- let sm = f ~standalone ~source_map (k, fmt) in
62+ let sm, shapes = f ~standalone ~source_map (k, fmt) in
63+ (if write_shape
64+ then
65+ match output_file with
66+ | `Stdout -> ()
67+ | `Name name ->
68+ Shape.Store. save'
69+ (Filename. remove_extension name ^ Shape.Store. ext)
70+ (StringMap. bindings shapes));
5671 match source_map, sm with
5772 | No_sourcemap , _ | _ , None -> ()
5873 | ((Inline | File _ ) as output ), Some sm ->
@@ -70,7 +85,6 @@ let output_gen ~standalone ~custom_header ~build_info ~source_map output_file f
7085 Pretty_print. newline fmt;
7186 Pretty_print. string fmt (Printf. sprintf " //# sourceMappingURL=%s\n " urlData)
7287 in
73-
7488 match output_file with
7589 | `Stdout -> f stdout `Stdout
7690 | `Name name -> Filename. gen_file name (fun chan -> f chan `File )
@@ -130,6 +144,11 @@ let sourcemap_of_infos ~base l =
130144
131145let sourcemap_of_info ~base info = sourcemap_of_infos ~base [ info ]
132146
147+ let map_fst f (x , y ) = f x, y
148+
149+ let merge_shape a b =
150+ StringMap. union (fun _name s1 s2 -> if Shape. equal s1 s2 then Some s1 else None ) a b
151+
133152let run
134153 { Cmd_arg. common
135154 ; profile
@@ -153,6 +172,8 @@ let run
153172 ; export_file
154173 ; keep_unit_names
155174 ; include_runtime
175+ ; shape_files
176+ ; write_shape
156177 } =
157178 let source_map_base = Option. map ~f: snd source_map in
158179 let source_map =
@@ -172,6 +193,7 @@ let run
172193 | `Name _ , _ -> () );
173194 List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
174195 List. iter static_env ~f: (fun (s , v ) -> Eval. set_static_env s v);
196+ List. iter shape_files ~f: (fun fn -> Shape.Store. load' fn);
175197 let t = Timer. make () in
176198 let include_dirs =
177199 List. filter_map (include_dirs @ [ " +stdlib/" ]) ~f: (fun d -> Findlib. find [] d)
@@ -366,6 +388,7 @@ let run
366388 }
367389 in
368390 output_gen
391+ ~write_shape
369392 ~standalone: true
370393 ~custom_header
371394 ~build_info: (Build_info. create `Runtime )
@@ -381,7 +404,7 @@ let run
381404 ~standalone
382405 ~link: `All
383406 output_file
384- |> sourcemap_of_info ~base: source_map_base)
407+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
385408 | (`Stdin | `File _ ) as bytecode ->
386409 let kind, ic, close_ic, include_dirs =
387410 match bytecode with
@@ -414,6 +437,7 @@ let run
414437 in
415438 if times () then Format. eprintf " parsing: %a@." Timer. print t1;
416439 output_gen
440+ ~write_shape
417441 ~standalone: true
418442 ~custom_header
419443 ~build_info: (Build_info. create `Exe )
@@ -427,7 +451,7 @@ let run
427451 ~source_map
428452 ~link: (if linkall then `All else `Needed )
429453 output_file
430- |> sourcemap_of_info ~base: source_map_base)
454+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
431455 | `Cmo cmo ->
432456 let output_file =
433457 match output_file, keep_unit_names with
@@ -452,6 +476,7 @@ let run
452476 in
453477 if times () then Format. eprintf " parsing: %a@." Timer. print t1;
454478 output_gen
479+ ~write_shape
455480 ~standalone: false
456481 ~custom_header
457482 ~build_info: (Build_info. create `Cmo )
@@ -460,12 +485,13 @@ let run
460485 (fun ~standalone ~source_map output ->
461486 match include_runtime with
462487 | true ->
463- let sm1 = output_partial_runtime ~standalone ~source_map output in
464- let sm2 = output_partial cmo code ~standalone ~source_map output in
465- sourcemap_of_infos ~base: source_map_base [ sm1; sm2 ]
488+ let sm1, sh1 = output_partial_runtime ~standalone ~source_map output in
489+ let sm2, sh2 = output_partial cmo code ~standalone ~source_map output in
490+ ( sourcemap_of_infos ~base: source_map_base [ sm1; sm2 ]
491+ , merge_shape sh1 sh2 )
466492 | false ->
467493 output_partial cmo code ~standalone ~source_map output
468- |> sourcemap_of_info ~base: source_map_base)
494+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
469495 | `Cma cma when keep_unit_names ->
470496 (if include_runtime
471497 then
@@ -481,14 +507,15 @@ let run
481507 failwith " use [-o dirname/] or remove [--keep-unit-names]"
482508 in
483509 output_gen
510+ ~write_shape
484511 ~standalone: false
485512 ~custom_header
486513 ~build_info: (Build_info. create `Runtime )
487514 ~source_map
488515 (`Name output_file)
489516 (fun ~standalone ~source_map output ->
490517 output_partial_runtime ~standalone ~source_map output
491- |> sourcemap_of_info ~base: source_map_base));
518+ |> map_fst ( sourcemap_of_info ~base: source_map_base) ));
492519 List. iter cma.lib_units ~f: (fun cmo ->
493520 let output_file =
494521 match output_file with
@@ -517,23 +544,24 @@ let run
517544 t1
518545 (Ocaml_compiler.Cmo_format. name cmo);
519546 output_gen
547+ ~write_shape
520548 ~standalone: false
521549 ~custom_header
522550 ~build_info: (Build_info. create `Cma )
523551 ~source_map
524552 (`Name output_file)
525553 (fun ~standalone ~source_map output ->
526554 output_partial ~standalone ~source_map cmo code output
527- |> sourcemap_of_info ~base: source_map_base))
555+ |> map_fst ( sourcemap_of_info ~base: source_map_base) ))
528556 | `Cma cma ->
529557 let f ~standalone ~source_map output =
530- let source_map_runtime =
558+ let runtime =
531559 if not include_runtime
532560 then None
533561 else Some (output_partial_runtime ~standalone ~source_map output)
534562 in
535563
536- let source_map_units =
564+ let units =
537565 List. map cma.lib_units ~f: (fun cmo ->
538566 let t1 = Timer. make () in
539567 let code =
@@ -553,14 +581,20 @@ let run
553581 (Ocaml_compiler.Cmo_format. name cmo);
554582 output_partial ~standalone ~source_map cmo code output)
555583 in
556- let sm =
557- match source_map_runtime with
558- | None -> source_map_units
559- | Some x -> x :: source_map_units
584+ let sm_and_shapes =
585+ match runtime with
586+ | None -> units
587+ | Some x -> x :: units
588+ in
589+ let shapes =
590+ List. fold_left sm_and_shapes ~init: StringMap. empty ~f: (fun acc (_ , s ) ->
591+ merge_shape s acc)
560592 in
561- sourcemap_of_infos ~base: source_map_base sm
593+ ( sourcemap_of_infos ~base: source_map_base (List. map sm_and_shapes ~f: fst)
594+ , shapes )
562595 in
563596 output_gen
597+ ~write_shape
564598 ~standalone: false
565599 ~custom_header
566600 ~build_info: (Build_info. create `Cma )
0 commit comments