@@ -42,6 +42,7 @@ let source_map_enabled : Source_map.Encoding_spec.t option -> bool = function
42
42
| Some _ -> true
43
43
44
44
let output_gen
45
+ ~write_shape
45
46
~standalone
46
47
~custom_header
47
48
~build_info
@@ -53,7 +54,15 @@ let output_gen
53
54
Driver. configure fmt;
54
55
if standalone then header ~custom_header fmt;
55
56
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));
57
66
match source_map, sm with
58
67
| None , _ | _ , None -> ()
59
68
| Some { output_file = output ; source_map; keep_empty } , Some sm ->
@@ -71,7 +80,6 @@ let output_gen
71
80
Pretty_print. newline fmt;
72
81
Pretty_print. string fmt (Printf. sprintf " //# sourceMappingURL=%s\n " urlData)
73
82
in
74
-
75
83
match output_file with
76
84
| `Stdout -> f stdout `Stdout
77
85
| `Name name -> Filename. gen_file name (fun chan -> f chan `File )
@@ -132,6 +140,11 @@ let sourcemap_of_infos ~base l =
132
140
133
141
let sourcemap_of_info ~base info = sourcemap_of_infos ~base [ info ]
134
142
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
+
135
148
let run
136
149
{ Cmd_arg. common
137
150
; profile
@@ -156,6 +169,8 @@ let run
156
169
; keep_unit_names
157
170
; include_runtime
158
171
; effects
172
+ ; shape_files
173
+ ; write_shape
159
174
} =
160
175
let source_map_base =
161
176
Option. map ~f: (fun spec -> spec.Source_map.Encoding_spec. source_map) source_map
@@ -172,6 +187,7 @@ let run
172
187
| `Name _ , _ -> () );
173
188
List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
174
189
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);
175
191
let t = Timer. make () in
176
192
let include_dirs =
177
193
List. filter_map (include_dirs @ [ " +stdlib/" ]) ~f: (fun d -> Findlib. find [] d)
@@ -371,6 +387,7 @@ let run
371
387
{ code; cmis = StringSet. empty; debug = Parse_bytecode.Debug. default_summary }
372
388
in
373
389
output_gen
390
+ ~write_shape
374
391
~standalone: true
375
392
~custom_header
376
393
~build_info: (Build_info. create `Runtime )
@@ -386,7 +403,7 @@ let run
386
403
~standalone
387
404
~link: `All
388
405
output_file
389
- |> sourcemap_of_info ~base: source_map_base)
406
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
390
407
| (`Stdin | `File _ ) as bytecode ->
391
408
let kind, ic, close_ic, include_dirs =
392
409
match bytecode with
@@ -419,6 +436,7 @@ let run
419
436
in
420
437
if times () then Format. eprintf " parsing: %a@." Timer. print t1;
421
438
output_gen
439
+ ~write_shape
422
440
~standalone: true
423
441
~custom_header
424
442
~build_info: (Build_info. create `Exe )
@@ -432,7 +450,7 @@ let run
432
450
~source_map
433
451
~link: (if linkall then `All else `Needed )
434
452
output_file
435
- |> sourcemap_of_info ~base: source_map_base)
453
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
436
454
| `Cmo cmo ->
437
455
let output_file =
438
456
match output_file, keep_unit_names with
@@ -457,6 +475,7 @@ let run
457
475
in
458
476
if times () then Format. eprintf " parsing: %a@." Timer. print t1;
459
477
output_gen
478
+ ~write_shape
460
479
~standalone: false
461
480
~custom_header
462
481
~build_info: (Build_info. create `Cmo )
@@ -465,12 +484,13 @@ let run
465
484
(fun ~standalone ~source_map output ->
466
485
match include_runtime with
467
486
| 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 )
471
491
| false ->
472
492
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) )
474
494
| `Cma cma when keep_unit_names ->
475
495
(if include_runtime
476
496
then
@@ -486,14 +506,15 @@ let run
486
506
failwith " use [-o dirname/] or remove [--keep-unit-names]"
487
507
in
488
508
output_gen
509
+ ~write_shape
489
510
~standalone: false
490
511
~custom_header
491
512
~build_info: (Build_info. create `Runtime )
492
513
~source_map
493
514
(`Name output_file)
494
515
(fun ~standalone ~source_map output ->
495
516
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) ));
497
518
List. iter cma.lib_units ~f: (fun cmo ->
498
519
let output_file =
499
520
match output_file with
@@ -522,23 +543,24 @@ let run
522
543
t1
523
544
(Ocaml_compiler.Cmo_format. name cmo);
524
545
output_gen
546
+ ~write_shape
525
547
~standalone: false
526
548
~custom_header
527
549
~build_info: (Build_info. create `Cma )
528
550
~source_map
529
551
(`Name output_file)
530
552
(fun ~standalone ~source_map output ->
531
553
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) ))
533
555
| `Cma cma ->
534
556
let f ~standalone ~source_map output =
535
- let source_map_runtime =
557
+ let runtime =
536
558
if not include_runtime
537
559
then None
538
560
else Some (output_partial_runtime ~standalone ~source_map output)
539
561
in
540
562
541
- let source_map_units =
563
+ let units =
542
564
List. map cma.lib_units ~f: (fun cmo ->
543
565
let t1 = Timer. make () in
544
566
let code =
@@ -558,14 +580,20 @@ let run
558
580
(Ocaml_compiler.Cmo_format. name cmo);
559
581
output_partial ~standalone ~source_map cmo code output)
560
582
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)
565
591
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 )
567
594
in
568
595
output_gen
596
+ ~write_shape
569
597
~standalone: false
570
598
~custom_header
571
599
~build_info: (Build_info. create `Cma )
0 commit comments