@@ -244,7 +244,14 @@ let generate_prelude ~out_file =
244244 @@ fun ch ->
245245 let code, uinfo = Parse_bytecode. predefined_exceptions () in
246246 let profile = Profile. O1 in
247- let Driver. { program; variable_uses; in_cps; deadcode_sentinal; _ } =
247+ let Driver.
248+ { program
249+ ; variable_uses
250+ ; in_cps
251+ ; deadcode_sentinal
252+ ; shapes = _
253+ ; trampolined_calls = _
254+ } =
248255 Driver. optimize ~profile ~shapes: false code
249256 in
250257 let context = Generate. start () in
@@ -326,6 +333,16 @@ let add_source_map sourcemap_don't_inline_content z opt_source_map =
326333 ~name: (Link. source_name i j file)
327334 ~contents: (Yojson.Basic. to_string (`String sm))))
328335
336+ let merge_shape a b =
337+ StringMap. union (fun _name s1 s2 -> if Shape. equal s1 s2 then Some s1 else None ) a b
338+
339+ let sexp_of_shapes s =
340+ StringMap. bindings s
341+ |> List. map ~f: (fun (name , shape ) ->
342+ Sexp. List [ Atom name; Atom (Shape. to_string shape) ])
343+
344+ let string_of_shapes s = Sexp. List (sexp_of_shapes s) |> Sexp. to_string
345+
329346let run
330347 { Cmd_arg. common
331348 ; profile
@@ -339,11 +356,24 @@ let run
339356 ; sourcemap_root
340357 ; sourcemap_don't_inline_content
341358 ; effects
359+ ; shape_files
342360 } =
343361 Config. set_target `Wasm ;
344362 Jsoo_cmdline.Arg. eval common;
345363 Config. set_effects_backend effects;
346364 Generate. init () ;
365+ List. iter shape_files ~f: (fun s ->
366+ let z = Zip. open_in s in
367+ if Zip. has_entry z ~name: " shapes.sexp"
368+ then
369+ let s = Zip. read_entry z ~name: " shapes.sexp" in
370+ match Sexp. from_string s with
371+ | List l ->
372+ List. iter l ~f: (function
373+ | Sexp. List [ Atom name; Atom shape ] ->
374+ Shape.Store. set ~name (Shape. of_string shape)
375+ | _ -> () )
376+ | _ -> () );
347377 let output_file = fst output_file in
348378 if debug_mem () then Debug. start_profiling output_file;
349379 List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
@@ -396,9 +426,17 @@ let run
396426 check_debug one;
397427 let code = one.code in
398428 let standalone = Option. is_none unit_name in
399- let Driver. { program; variable_uses; in_cps; deadcode_sentinal; _ } =
400- Driver. optimize ~profile ~shapes: false code
429+ let Driver.
430+ { program
431+ ; variable_uses
432+ ; in_cps
433+ ; deadcode_sentinal
434+ ; shapes
435+ ; trampolined_calls = _
436+ } =
437+ Driver. optimize ~profile ~shapes: true code
401438 in
439+ StringMap. iter (fun name shape -> Shape.Store. set ~name shape) shapes;
402440 let context = Generate. start () in
403441 let toplevel_name, generated_js =
404442 Generate. f
@@ -419,7 +457,7 @@ let run
419457 Generate. output ch ~context ;
420458 close_out ch);
421459 if times () then Format. eprintf " compilation: %a@." Timer. print t;
422- generated_js
460+ generated_js, shapes
423461 in
424462 (if runtime_only
425463 then (
@@ -475,7 +513,7 @@ let run
475513 then Some (Filename. temp_file unit_name " .wasm.map" )
476514 else None )
477515 @@ fun opt_tmp_map_file ->
478- let unit_data =
516+ let unit_data, shapes =
479517 Fs. with_intermediate_file (Filename. temp_file unit_name " .wasm" )
480518 @@ fun input_file ->
481519 opt_with
@@ -484,7 +522,7 @@ let run
484522 then Some (Filename. temp_file unit_name " .wasm.map" )
485523 else None )
486524 @@ fun opt_input_sourcemap ->
487- let fragments =
525+ let fragments, shapes =
488526 output
489527 code
490528 ~wat_file:
@@ -500,9 +538,9 @@ let run
500538 ~input_file
501539 ~output_file: tmp_wasm_file
502540 () ;
503- { Link. unit_name; unit_info; fragments }
541+ { Link. unit_name; unit_info; fragments }, shapes
504542 in
505- cont unit_data unit_name tmp_wasm_file opt_tmp_map_file
543+ cont unit_data unit_name tmp_wasm_file opt_tmp_map_file shapes
506544 in
507545 (match kind with
508546 | `Exe ->
@@ -533,7 +571,7 @@ let run
533571 then Some (Filename. temp_file " code" " .wasm.map" )
534572 else None
535573 in
536- let generated_js =
574+ let generated_js, _shapes =
537575 output
538576 code
539577 ~unit_name: None
@@ -597,8 +635,9 @@ let run
597635 @@ fun tmp_output_file ->
598636 let z = Zip. open_out tmp_output_file in
599637 let compile_cmo' z cmo =
600- compile_cmo cmo (fun unit_data _ tmp_wasm_file opt_tmp_map_file ->
638+ compile_cmo cmo (fun unit_data _ tmp_wasm_file opt_tmp_map_file shapes ->
601639 Zip. add_file z ~name: " code.wasm" ~file: tmp_wasm_file;
640+ Zip. add_entry z ~name: " shapes.sexp" ~contents: (string_of_shapes shapes);
602641 add_source_map sourcemap_don't_inline_content z (`File opt_tmp_map_file);
603642 unit_data)
604643 in
@@ -614,8 +653,8 @@ let run
614653 List. fold_right
615654 ~f: (fun cmo cont l ->
616655 compile_cmo cmo
617- @@ fun unit_data unit_name tmp_wasm_file opt_tmp_map_file ->
618- cont ((unit_data, unit_name, tmp_wasm_file, opt_tmp_map_file) :: l))
656+ @@ fun unit_data unit_name tmp_wasm_file opt_tmp_map_file shapes ->
657+ cont ((unit_data, unit_name, tmp_wasm_file, opt_tmp_map_file, shapes ) :: l))
619658 cma.lib_units
620659 ~init: (fun l ->
621660 Fs. with_intermediate_file (Filename. temp_file " wasm" " .wasm" )
@@ -624,7 +663,7 @@ let run
624663 let source_map =
625664 Wasm_link. f
626665 (List. map
627- ~f: (fun (_ , _ , file , opt_source_map ) ->
666+ ~f: (fun (_ , _ , file , opt_source_map , _ ) ->
628667 { Wasm_link. module_name = " OCaml"
629668 ; file
630669 ; code = None
@@ -637,10 +676,17 @@ let run
637676 ~output_file: tmp_wasm_file
638677 in
639678 Zip. add_file z ~name: " code.wasm" ~file: tmp_wasm_file;
679+ let shapes =
680+ List. fold_left
681+ ~init: StringMap. empty
682+ ~f: (fun acc (_ , _ , _ , _ , shapes ) -> merge_shape acc shapes)
683+ l
684+ in
685+ Zip. add_entry z ~name: " shapes.sexp" ~contents: (string_of_shapes shapes);
640686 if enable_source_maps
641687 then
642688 add_source_map sourcemap_don't_inline_content z (`Source_map source_map);
643- List. map ~f: (fun (unit_data , _ , _ , _ ) -> unit_data) l)
689+ List. map ~f: (fun (unit_data , _ , _ , _ , _ ) -> unit_data) l)
644690 []
645691 in
646692 Link. add_info z ~build_info: (Build_info. create `Cma ) ~unit_data () ;
0 commit comments