@@ -46,13 +46,28 @@ let source_map_enabled = function
46
46
| No_sourcemap -> false
47
47
| Inline | File _ -> true
48
48
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 =
50
57
let f chan k =
51
58
let fmt = Pretty_print. to_out_channel chan in
52
59
Driver. configure fmt;
53
60
if standalone then header ~custom_header fmt;
54
61
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));
56
71
match source_map, sm with
57
72
| No_sourcemap , _ | _ , None -> ()
58
73
| ((Inline | File _ ) as output ), Some sm ->
@@ -70,7 +85,6 @@ let output_gen ~standalone ~custom_header ~build_info ~source_map output_file f
70
85
Pretty_print. newline fmt;
71
86
Pretty_print. string fmt (Printf. sprintf " //# sourceMappingURL=%s\n " urlData)
72
87
in
73
-
74
88
match output_file with
75
89
| `Stdout -> f stdout `Stdout
76
90
| `Name name -> Filename. gen_file name (fun chan -> f chan `File )
@@ -130,6 +144,11 @@ let sourcemap_of_infos ~base l =
130
144
131
145
let sourcemap_of_info ~base info = sourcemap_of_infos ~base [ info ]
132
146
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
+
133
152
let run
134
153
{ Cmd_arg. common
135
154
; profile
@@ -153,6 +172,8 @@ let run
153
172
; export_file
154
173
; keep_unit_names
155
174
; include_runtime
175
+ ; shape_files
176
+ ; write_shape
156
177
} =
157
178
let source_map_base = Option. map ~f: snd source_map in
158
179
let source_map =
@@ -172,6 +193,7 @@ let run
172
193
| `Name _ , _ -> () );
173
194
List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
174
195
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);
175
197
let t = Timer. make () in
176
198
let include_dirs =
177
199
List. filter_map (include_dirs @ [ " +stdlib/" ]) ~f: (fun d -> Findlib. find [] d)
@@ -366,6 +388,7 @@ let run
366
388
}
367
389
in
368
390
output_gen
391
+ ~write_shape
369
392
~standalone: true
370
393
~custom_header
371
394
~build_info: (Build_info. create `Runtime )
@@ -381,7 +404,7 @@ let run
381
404
~standalone
382
405
~link: `All
383
406
output_file
384
- |> sourcemap_of_info ~base: source_map_base)
407
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
385
408
| (`Stdin | `File _ ) as bytecode ->
386
409
let kind, ic, close_ic, include_dirs =
387
410
match bytecode with
@@ -414,6 +437,7 @@ let run
414
437
in
415
438
if times () then Format. eprintf " parsing: %a@." Timer. print t1;
416
439
output_gen
440
+ ~write_shape
417
441
~standalone: true
418
442
~custom_header
419
443
~build_info: (Build_info. create `Exe )
@@ -427,7 +451,7 @@ let run
427
451
~source_map
428
452
~link: (if linkall then `All else `Needed )
429
453
output_file
430
- |> sourcemap_of_info ~base: source_map_base)
454
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
431
455
| `Cmo cmo ->
432
456
let output_file =
433
457
match output_file, keep_unit_names with
@@ -452,6 +476,7 @@ let run
452
476
in
453
477
if times () then Format. eprintf " parsing: %a@." Timer. print t1;
454
478
output_gen
479
+ ~write_shape
455
480
~standalone: false
456
481
~custom_header
457
482
~build_info: (Build_info. create `Cmo )
@@ -460,12 +485,13 @@ let run
460
485
(fun ~standalone ~source_map output ->
461
486
match include_runtime with
462
487
| 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 )
466
492
| false ->
467
493
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) )
469
495
| `Cma cma when keep_unit_names ->
470
496
(if include_runtime
471
497
then
@@ -481,14 +507,15 @@ let run
481
507
failwith " use [-o dirname/] or remove [--keep-unit-names]"
482
508
in
483
509
output_gen
510
+ ~write_shape
484
511
~standalone: false
485
512
~custom_header
486
513
~build_info: (Build_info. create `Runtime )
487
514
~source_map
488
515
(`Name output_file)
489
516
(fun ~standalone ~source_map output ->
490
517
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) ));
492
519
List. iter cma.lib_units ~f: (fun cmo ->
493
520
let output_file =
494
521
match output_file with
@@ -517,23 +544,24 @@ let run
517
544
t1
518
545
(Ocaml_compiler.Cmo_format. name cmo);
519
546
output_gen
547
+ ~write_shape
520
548
~standalone: false
521
549
~custom_header
522
550
~build_info: (Build_info. create `Cma )
523
551
~source_map
524
552
(`Name output_file)
525
553
(fun ~standalone ~source_map output ->
526
554
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) ))
528
556
| `Cma cma ->
529
557
let f ~standalone ~source_map output =
530
- let source_map_runtime =
558
+ let runtime =
531
559
if not include_runtime
532
560
then None
533
561
else Some (output_partial_runtime ~standalone ~source_map output)
534
562
in
535
563
536
- let source_map_units =
564
+ let units =
537
565
List. map cma.lib_units ~f: (fun cmo ->
538
566
let t1 = Timer. make () in
539
567
let code =
@@ -553,14 +581,20 @@ let run
553
581
(Ocaml_compiler.Cmo_format. name cmo);
554
582
output_partial ~standalone ~source_map cmo code output)
555
583
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)
560
592
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 )
562
595
in
563
596
output_gen
597
+ ~write_shape
564
598
~standalone: false
565
599
~custom_header
566
600
~build_info: (Build_info. create `Cma )
0 commit comments