@@ -245,7 +245,15 @@ let generate_prelude ~out_file =
245
245
@@ fun ch ->
246
246
let code, uinfo = Parse_bytecode. predefined_exceptions () in
247
247
let profile = Profile. O1 in
248
- let Driver. { program; variable_uses; in_cps; deadcode_sentinal; _ }, global_flow_data =
248
+ let ( Driver.
249
+ { program
250
+ ; variable_uses
251
+ ; in_cps
252
+ ; deadcode_sentinal
253
+ ; shapes = _
254
+ ; trampolined_calls = _
255
+ }
256
+ , global_flow_data ) =
249
257
Driver. optimize_for_wasm ~profile ~shapes: false code
250
258
in
251
259
let context = Generate. start () in
@@ -328,6 +336,16 @@ let add_source_map sourcemap_don't_inline_content z opt_source_map =
328
336
~name: (Link. source_name i j file)
329
337
~contents: (Yojson.Basic. to_string (`String sm))))
330
338
339
+ let merge_shape a b =
340
+ StringMap. union (fun _name s1 s2 -> if Shape. equal s1 s2 then Some s1 else None ) a b
341
+
342
+ let sexp_of_shapes s =
343
+ StringMap. bindings s
344
+ |> List. map ~f: (fun (name , shape ) ->
345
+ Sexp. List [ Atom name; Atom (Shape. to_string shape) ])
346
+
347
+ let string_of_shapes s = Sexp. List (sexp_of_shapes s) |> Sexp. to_string
348
+
331
349
let run
332
350
{ Cmd_arg. common
333
351
; profile
@@ -341,11 +359,24 @@ let run
341
359
; sourcemap_root
342
360
; sourcemap_don't_inline_content
343
361
; effects
362
+ ; shape_files
344
363
} =
345
364
Config. set_target `Wasm ;
346
365
Jsoo_cmdline.Arg. eval common;
347
366
Config. set_effects_backend effects;
348
367
Generate. init () ;
368
+ List. iter shape_files ~f: (fun s ->
369
+ let z = Zip. open_in s in
370
+ if Zip. has_entry z ~name: " shapes.sexp"
371
+ then
372
+ let s = Zip. read_entry z ~name: " shapes.sexp" in
373
+ match Sexp. from_string s with
374
+ | List l ->
375
+ List. iter l ~f: (function
376
+ | Sexp. List [ Atom name; Atom shape ] ->
377
+ Shape.Store. set ~name (Shape. of_string shape)
378
+ | _ -> () )
379
+ | _ -> () );
349
380
let output_file = fst output_file in
350
381
if debug_mem () then Debug. start_profiling output_file;
351
382
List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
@@ -398,10 +429,18 @@ let run
398
429
check_debug one;
399
430
let code = one.code in
400
431
let standalone = Option. is_none unit_name in
401
- let Driver. { program; variable_uses; in_cps; deadcode_sentinal; _ }, global_flow_data
402
- =
403
- Driver. optimize_for_wasm ~profile ~shapes: false code
432
+ let ( Driver.
433
+ { program
434
+ ; variable_uses
435
+ ; in_cps
436
+ ; deadcode_sentinal
437
+ ; shapes
438
+ ; trampolined_calls = _
439
+ }
440
+ , global_flow_data ) =
441
+ Driver. optimize_for_wasm ~profile ~shapes: true code
404
442
in
443
+ StringMap. iter (fun name shape -> Shape.Store. set ~name shape) shapes;
405
444
let context = Generate. start () in
406
445
let toplevel_name, generated_js =
407
446
Generate. f
@@ -423,7 +462,7 @@ let run
423
462
Generate. output ch ~context ;
424
463
close_out ch);
425
464
if times () then Format. eprintf " compilation: %a@." Timer. print t;
426
- generated_js
465
+ generated_js, shapes
427
466
in
428
467
(if runtime_only
429
468
then (
@@ -479,7 +518,7 @@ let run
479
518
then Some (Filename. temp_file unit_name " .wasm.map" )
480
519
else None )
481
520
@@ fun opt_tmp_map_file ->
482
- let unit_data =
521
+ let unit_data, shapes =
483
522
Fs. with_intermediate_file (Filename. temp_file unit_name " .wasm" )
484
523
@@ fun input_file ->
485
524
opt_with
@@ -488,7 +527,7 @@ let run
488
527
then Some (Filename. temp_file unit_name " .wasm.map" )
489
528
else None )
490
529
@@ fun opt_input_sourcemap ->
491
- let fragments =
530
+ let fragments, shapes =
492
531
output
493
532
code
494
533
~wat_file:
@@ -504,9 +543,9 @@ let run
504
543
~input_file
505
544
~output_file: tmp_wasm_file
506
545
() ;
507
- { Link. unit_name; unit_info; fragments }
546
+ { Link. unit_name; unit_info; fragments }, shapes
508
547
in
509
- cont unit_data unit_name tmp_wasm_file opt_tmp_map_file
548
+ cont unit_data unit_name tmp_wasm_file opt_tmp_map_file shapes
510
549
in
511
550
(match kind with
512
551
| `Exe ->
@@ -537,7 +576,7 @@ let run
537
576
then Some (Filename. temp_file " code" " .wasm.map" )
538
577
else None
539
578
in
540
- let generated_js =
579
+ let generated_js, _shapes =
541
580
output
542
581
code
543
582
~unit_name: None
@@ -601,8 +640,9 @@ let run
601
640
@@ fun tmp_output_file ->
602
641
let z = Zip. open_out tmp_output_file in
603
642
let compile_cmo' z cmo =
604
- compile_cmo cmo (fun unit_data _ tmp_wasm_file opt_tmp_map_file ->
643
+ compile_cmo cmo (fun unit_data _ tmp_wasm_file opt_tmp_map_file shapes ->
605
644
Zip. add_file z ~name: " code.wasm" ~file: tmp_wasm_file;
645
+ Zip. add_entry z ~name: " shapes.sexp" ~contents: (string_of_shapes shapes);
606
646
add_source_map sourcemap_don't_inline_content z (`File opt_tmp_map_file);
607
647
unit_data)
608
648
in
@@ -618,8 +658,8 @@ let run
618
658
List. fold_right
619
659
~f: (fun cmo cont l ->
620
660
compile_cmo cmo
621
- @@ fun unit_data unit_name tmp_wasm_file opt_tmp_map_file ->
622
- cont ((unit_data, unit_name, tmp_wasm_file, opt_tmp_map_file) :: l))
661
+ @@ fun unit_data unit_name tmp_wasm_file opt_tmp_map_file shapes ->
662
+ cont ((unit_data, unit_name, tmp_wasm_file, opt_tmp_map_file, shapes ) :: l))
623
663
cma.lib_units
624
664
~init: (fun l ->
625
665
Fs. with_intermediate_file (Filename. temp_file " wasm" " .wasm" )
@@ -628,7 +668,7 @@ let run
628
668
let source_map =
629
669
Wasm_link. f
630
670
(List. map
631
- ~f: (fun (_ , _ , file , opt_source_map ) ->
671
+ ~f: (fun (_ , _ , file , opt_source_map , _ ) ->
632
672
{ Wasm_link. module_name = " OCaml"
633
673
; file
634
674
; code = None
@@ -641,10 +681,17 @@ let run
641
681
~output_file: tmp_wasm_file
642
682
in
643
683
Zip. add_file z ~name: " code.wasm" ~file: tmp_wasm_file;
684
+ let shapes =
685
+ List. fold_left
686
+ ~init: StringMap. empty
687
+ ~f: (fun acc (_ , _ , _ , _ , shapes ) -> merge_shape acc shapes)
688
+ l
689
+ in
690
+ Zip. add_entry z ~name: " shapes.sexp" ~contents: (string_of_shapes shapes);
644
691
if enable_source_maps
645
692
then
646
693
add_source_map sourcemap_don't_inline_content z (`Source_map source_map);
647
- List. map ~f: (fun (unit_data , _ , _ , _ ) -> unit_data) l)
694
+ List. map ~f: (fun (unit_data , _ , _ , _ , _ ) -> unit_data) l)
648
695
[]
649
696
in
650
697
Link. add_info z ~build_info: (Build_info. create `Cma ) ~unit_data () ;
0 commit comments