@@ -42,6 +42,7 @@ let source_map_enabled : Source_map.Encoding_spec.t option -> bool = function
4242 | Some _ -> true
4343
4444let output_gen
45+ ~write_shape
4546 ~standalone
4647 ~custom_header
4748 ~build_info
@@ -53,7 +54,15 @@ let output_gen
5354 Driver. configure fmt;
5455 if standalone then header ~custom_header fmt;
5556 if Config.Flag. header () then jsoo_header fmt build_info;
56- let sm = f ~standalone ~source_map (k, fmt) in
57+ let sm, shapes = f ~standalone ~source_map (k, fmt) in
58+ (if write_shape
59+ then
60+ match output_file with
61+ | `Stdout -> ()
62+ | `Name name ->
63+ Shape.Store. save'
64+ (Filename. remove_extension name ^ Shape.Store. ext)
65+ (StringMap. bindings shapes));
5766 match source_map, sm with
5867 | None , _ | _ , None -> ()
5968 | Some { output_file = output ; source_map; keep_empty } , Some sm ->
@@ -71,7 +80,6 @@ let output_gen
7180 Pretty_print. newline fmt;
7281 Pretty_print. string fmt (Printf. sprintf " //# sourceMappingURL=%s\n " urlData)
7382 in
74-
7583 match output_file with
7684 | `Stdout -> f stdout `Stdout
7785 | `Name name -> Filename. gen_file name (fun chan -> f chan `File )
@@ -132,6 +140,11 @@ let sourcemap_of_infos ~base l =
132140
133141let sourcemap_of_info ~base info = sourcemap_of_infos ~base [ info ]
134142
143+ let map_fst f (x , y ) = f x, y
144+
145+ let merge_shape a b =
146+ StringMap. union (fun _name s1 s2 -> if Shape. equal s1 s2 then Some s1 else None ) a b
147+
135148let run
136149 { Cmd_arg. common
137150 ; profile
@@ -156,6 +169,8 @@ let run
156169 ; keep_unit_names
157170 ; include_runtime
158171 ; effects
172+ ; shape_files
173+ ; write_shape
159174 } =
160175 let source_map_base =
161176 Option. map ~f: (fun spec -> spec.Source_map.Encoding_spec. source_map) source_map
@@ -172,6 +187,7 @@ let run
172187 | `Name _ , _ -> () );
173188 List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
174189 List. iter static_env ~f: (fun (s , v ) -> Eval. set_static_env s v);
190+ List. iter shape_files ~f: (fun fn -> Shape.Store. load' fn);
175191 let t = Timer. make () in
176192 let include_dirs =
177193 List. filter_map (include_dirs @ [ " +stdlib/" ]) ~f: (fun d -> Findlib. find [] d)
@@ -371,6 +387,7 @@ let run
371387 { code; cmis = StringSet. empty; debug = Parse_bytecode.Debug. default_summary }
372388 in
373389 output_gen
390+ ~write_shape
374391 ~standalone: true
375392 ~custom_header
376393 ~build_info: (Build_info. create `Runtime )
@@ -386,7 +403,7 @@ let run
386403 ~standalone
387404 ~link: `All
388405 output_file
389- |> sourcemap_of_info ~base: source_map_base)
406+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
390407 | (`Stdin | `File _ ) as bytecode ->
391408 let kind, ic, close_ic, include_dirs =
392409 match bytecode with
@@ -419,6 +436,7 @@ let run
419436 in
420437 if times () then Format. eprintf " parsing: %a@." Timer. print t1;
421438 output_gen
439+ ~write_shape
422440 ~standalone: true
423441 ~custom_header
424442 ~build_info: (Build_info. create `Exe )
@@ -432,7 +450,7 @@ let run
432450 ~source_map
433451 ~link: (if linkall then `All else `Needed )
434452 output_file
435- |> sourcemap_of_info ~base: source_map_base)
453+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
436454 | `Cmo cmo ->
437455 let output_file =
438456 match output_file, keep_unit_names with
@@ -457,6 +475,7 @@ let run
457475 in
458476 if times () then Format. eprintf " parsing: %a@." Timer. print t1;
459477 output_gen
478+ ~write_shape
460479 ~standalone: false
461480 ~custom_header
462481 ~build_info: (Build_info. create `Cmo )
@@ -465,12 +484,13 @@ let run
465484 (fun ~standalone ~source_map output ->
466485 match include_runtime with
467486 | true ->
468- let sm1 = output_partial_runtime ~standalone ~source_map output in
469- let sm2 = output_partial cmo code ~standalone ~source_map output in
470- sourcemap_of_infos ~base: source_map_base [ sm1; sm2 ]
487+ let sm1, sh1 = output_partial_runtime ~standalone ~source_map output in
488+ let sm2, sh2 = output_partial cmo code ~standalone ~source_map output in
489+ ( sourcemap_of_infos ~base: source_map_base [ sm1; sm2 ]
490+ , merge_shape sh1 sh2 )
471491 | false ->
472492 output_partial cmo code ~standalone ~source_map output
473- |> sourcemap_of_info ~base: source_map_base)
493+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
474494 | `Cma cma when keep_unit_names ->
475495 (if include_runtime
476496 then
@@ -486,14 +506,15 @@ let run
486506 failwith " use [-o dirname/] or remove [--keep-unit-names]"
487507 in
488508 output_gen
509+ ~write_shape
489510 ~standalone: false
490511 ~custom_header
491512 ~build_info: (Build_info. create `Runtime )
492513 ~source_map
493514 (`Name output_file)
494515 (fun ~standalone ~source_map output ->
495516 output_partial_runtime ~standalone ~source_map output
496- |> sourcemap_of_info ~base: source_map_base));
517+ |> map_fst ( sourcemap_of_info ~base: source_map_base) ));
497518 List. iter cma.lib_units ~f: (fun cmo ->
498519 let output_file =
499520 match output_file with
@@ -522,23 +543,24 @@ let run
522543 t1
523544 (Ocaml_compiler.Cmo_format. name cmo);
524545 output_gen
546+ ~write_shape
525547 ~standalone: false
526548 ~custom_header
527549 ~build_info: (Build_info. create `Cma )
528550 ~source_map
529551 (`Name output_file)
530552 (fun ~standalone ~source_map output ->
531553 output_partial ~standalone ~source_map cmo code output
532- |> sourcemap_of_info ~base: source_map_base))
554+ |> map_fst ( sourcemap_of_info ~base: source_map_base) ))
533555 | `Cma cma ->
534556 let f ~standalone ~source_map output =
535- let source_map_runtime =
557+ let runtime =
536558 if not include_runtime
537559 then None
538560 else Some (output_partial_runtime ~standalone ~source_map output)
539561 in
540562
541- let source_map_units =
563+ let units =
542564 List. map cma.lib_units ~f: (fun cmo ->
543565 let t1 = Timer. make () in
544566 let code =
@@ -558,14 +580,20 @@ let run
558580 (Ocaml_compiler.Cmo_format. name cmo);
559581 output_partial ~standalone ~source_map cmo code output)
560582 in
561- let sm =
562- match source_map_runtime with
563- | None -> source_map_units
564- | Some x -> x :: source_map_units
583+ let sm_and_shapes =
584+ match runtime with
585+ | None -> units
586+ | Some x -> x :: units
587+ in
588+ let shapes =
589+ List. fold_left sm_and_shapes ~init: StringMap. empty ~f: (fun acc (_ , s ) ->
590+ merge_shape s acc)
565591 in
566- sourcemap_of_infos ~base: source_map_base sm
592+ ( sourcemap_of_infos ~base: source_map_base (List. map sm_and_shapes ~f: fst)
593+ , shapes )
567594 in
568595 output_gen
596+ ~write_shape
569597 ~standalone: false
570598 ~custom_header
571599 ~build_info: (Build_info. create `Cma )
0 commit comments