@@ -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
@@ -154,6 +173,8 @@ let run
154
173
; keep_unit_names
155
174
; include_runtime
156
175
; effects
176
+ ; shape_files
177
+ ; write_shape
157
178
} =
158
179
let source_map_base = Option. map ~f: snd source_map in
159
180
let source_map =
@@ -174,6 +195,7 @@ let run
174
195
| `Name _ , _ -> () );
175
196
List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
176
197
List. iter static_env ~f: (fun (s , v ) -> Eval. set_static_env s v);
198
+ List. iter shape_files ~f: (fun fn -> Shape.Store. load' fn);
177
199
let t = Timer. make () in
178
200
let include_dirs =
179
201
List. filter_map (include_dirs @ [ " +stdlib/" ]) ~f: (fun d -> Findlib. find [] d)
@@ -368,6 +390,7 @@ let run
368
390
}
369
391
in
370
392
output_gen
393
+ ~write_shape
371
394
~standalone: true
372
395
~custom_header
373
396
~build_info: (Build_info. create `Runtime )
@@ -383,7 +406,7 @@ let run
383
406
~standalone
384
407
~link: `All
385
408
output_file
386
- |> sourcemap_of_info ~base: source_map_base)
409
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
387
410
| (`Stdin | `File _ ) as bytecode ->
388
411
let kind, ic, close_ic, include_dirs =
389
412
match bytecode with
@@ -416,6 +439,7 @@ let run
416
439
in
417
440
if times () then Format. eprintf " parsing: %a@." Timer. print t1;
418
441
output_gen
442
+ ~write_shape
419
443
~standalone: true
420
444
~custom_header
421
445
~build_info: (Build_info. create `Exe )
@@ -429,7 +453,7 @@ let run
429
453
~source_map
430
454
~link: (if linkall then `All else `Needed )
431
455
output_file
432
- |> sourcemap_of_info ~base: source_map_base)
456
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
433
457
| `Cmo cmo ->
434
458
let output_file =
435
459
match output_file, keep_unit_names with
@@ -454,6 +478,7 @@ let run
454
478
in
455
479
if times () then Format. eprintf " parsing: %a@." Timer. print t1;
456
480
output_gen
481
+ ~write_shape
457
482
~standalone: false
458
483
~custom_header
459
484
~build_info: (Build_info. create `Cmo )
@@ -462,12 +487,13 @@ let run
462
487
(fun ~standalone ~source_map output ->
463
488
match include_runtime with
464
489
| true ->
465
- let sm1 = output_partial_runtime ~standalone ~source_map output in
466
- let sm2 = output_partial cmo code ~standalone ~source_map output in
467
- sourcemap_of_infos ~base: source_map_base [ sm1; sm2 ]
490
+ let sm1, sh1 = output_partial_runtime ~standalone ~source_map output in
491
+ let sm2, sh2 = output_partial cmo code ~standalone ~source_map output in
492
+ ( sourcemap_of_infos ~base: source_map_base [ sm1; sm2 ]
493
+ , merge_shape sh1 sh2 )
468
494
| false ->
469
495
output_partial cmo code ~standalone ~source_map output
470
- |> sourcemap_of_info ~base: source_map_base)
496
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) )
471
497
| `Cma cma when keep_unit_names ->
472
498
(if include_runtime
473
499
then
@@ -483,14 +509,15 @@ let run
483
509
failwith " use [-o dirname/] or remove [--keep-unit-names]"
484
510
in
485
511
output_gen
512
+ ~write_shape
486
513
~standalone: false
487
514
~custom_header
488
515
~build_info: (Build_info. create `Runtime )
489
516
~source_map
490
517
(`Name output_file)
491
518
(fun ~standalone ~source_map output ->
492
519
output_partial_runtime ~standalone ~source_map output
493
- |> sourcemap_of_info ~base: source_map_base));
520
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) ));
494
521
List. iter cma.lib_units ~f: (fun cmo ->
495
522
let output_file =
496
523
match output_file with
@@ -519,23 +546,24 @@ let run
519
546
t1
520
547
(Ocaml_compiler.Cmo_format. name cmo);
521
548
output_gen
549
+ ~write_shape
522
550
~standalone: false
523
551
~custom_header
524
552
~build_info: (Build_info. create `Cma )
525
553
~source_map
526
554
(`Name output_file)
527
555
(fun ~standalone ~source_map output ->
528
556
output_partial ~standalone ~source_map cmo code output
529
- |> sourcemap_of_info ~base: source_map_base))
557
+ |> map_fst ( sourcemap_of_info ~base: source_map_base) ))
530
558
| `Cma cma ->
531
559
let f ~standalone ~source_map output =
532
- let source_map_runtime =
560
+ let runtime =
533
561
if not include_runtime
534
562
then None
535
563
else Some (output_partial_runtime ~standalone ~source_map output)
536
564
in
537
565
538
- let source_map_units =
566
+ let units =
539
567
List. map cma.lib_units ~f: (fun cmo ->
540
568
let t1 = Timer. make () in
541
569
let code =
@@ -555,14 +583,20 @@ let run
555
583
(Ocaml_compiler.Cmo_format. name cmo);
556
584
output_partial ~standalone ~source_map cmo code output)
557
585
in
558
- let sm =
559
- match source_map_runtime with
560
- | None -> source_map_units
561
- | Some x -> x :: source_map_units
586
+ let sm_and_shapes =
587
+ match runtime with
588
+ | None -> units
589
+ | Some x -> x :: units
590
+ in
591
+ let shapes =
592
+ List. fold_left sm_and_shapes ~init: StringMap. empty ~f: (fun acc (_ , s ) ->
593
+ merge_shape s acc)
562
594
in
563
- sourcemap_of_infos ~base: source_map_base sm
595
+ ( sourcemap_of_infos ~base: source_map_base (List. map sm_and_shapes ~f: fst)
596
+ , shapes )
564
597
in
565
598
output_gen
599
+ ~write_shape
566
600
~standalone: false
567
601
~custom_header
568
602
~build_info: (Build_info. create `Cma )
0 commit comments