@@ -245,7 +245,15 @@ let generate_prelude ~out_file =
245245 @@ fun ch ->
246246 let code, uinfo = Parse_bytecode. predefined_exceptions () in
247247 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 ) =
249257 Driver. optimize_for_wasm ~profile ~shapes: false code
250258 in
251259 let context = Generate. start () in
@@ -328,6 +336,16 @@ let add_source_map sourcemap_don't_inline_content z opt_source_map =
328336 ~name: (Link. source_name i j file)
329337 ~contents: (Yojson.Basic. to_string (`String sm))))
330338
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+
331349let run
332350 { Cmd_arg. common
333351 ; profile
@@ -341,11 +359,24 @@ let run
341359 ; sourcemap_root
342360 ; sourcemap_don't_inline_content
343361 ; effects
362+ ; shape_files
344363 } =
345364 Config. set_target `Wasm ;
346365 Jsoo_cmdline.Arg. eval common;
347366 Config. set_effects_backend effects;
348367 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+ | _ -> () );
349380 let output_file = fst output_file in
350381 if debug_mem () then Debug. start_profiling output_file;
351382 List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
@@ -398,10 +429,18 @@ let run
398429 check_debug one;
399430 let code = one.code in
400431 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
404442 in
443+ StringMap. iter (fun name shape -> Shape.Store. set ~name shape) shapes;
405444 let context = Generate. start () in
406445 let toplevel_name, generated_js =
407446 Generate. f
@@ -423,7 +462,7 @@ let run
423462 Generate. output ch ~context ;
424463 close_out ch);
425464 if times () then Format. eprintf " compilation: %a@." Timer. print t;
426- generated_js
465+ generated_js, shapes
427466 in
428467 (if runtime_only
429468 then (
@@ -479,7 +518,7 @@ let run
479518 then Some (Filename. temp_file unit_name " .wasm.map" )
480519 else None )
481520 @@ fun opt_tmp_map_file ->
482- let unit_data =
521+ let unit_data, shapes =
483522 Fs. with_intermediate_file (Filename. temp_file unit_name " .wasm" )
484523 @@ fun input_file ->
485524 opt_with
@@ -488,7 +527,7 @@ let run
488527 then Some (Filename. temp_file unit_name " .wasm.map" )
489528 else None )
490529 @@ fun opt_input_sourcemap ->
491- let fragments =
530+ let fragments, shapes =
492531 output
493532 code
494533 ~wat_file:
@@ -504,9 +543,9 @@ let run
504543 ~input_file
505544 ~output_file: tmp_wasm_file
506545 () ;
507- { Link. unit_name; unit_info; fragments }
546+ { Link. unit_name; unit_info; fragments }, shapes
508547 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
510549 in
511550 (match kind with
512551 | `Exe ->
@@ -537,7 +576,7 @@ let run
537576 then Some (Filename. temp_file " code" " .wasm.map" )
538577 else None
539578 in
540- let generated_js =
579+ let generated_js, _shapes =
541580 output
542581 code
543582 ~unit_name: None
@@ -601,8 +640,9 @@ let run
601640 @@ fun tmp_output_file ->
602641 let z = Zip. open_out tmp_output_file in
603642 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 ->
605644 Zip. add_file z ~name: " code.wasm" ~file: tmp_wasm_file;
645+ Zip. add_entry z ~name: " shapes.sexp" ~contents: (string_of_shapes shapes);
606646 add_source_map sourcemap_don't_inline_content z (`File opt_tmp_map_file);
607647 unit_data)
608648 in
@@ -618,8 +658,8 @@ let run
618658 List. fold_right
619659 ~f: (fun cmo cont l ->
620660 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))
623663 cma.lib_units
624664 ~init: (fun l ->
625665 Fs. with_intermediate_file (Filename. temp_file " wasm" " .wasm" )
@@ -628,7 +668,7 @@ let run
628668 let source_map =
629669 Wasm_link. f
630670 (List. map
631- ~f: (fun (_ , _ , file , opt_source_map ) ->
671+ ~f: (fun (_ , _ , file , opt_source_map , _ ) ->
632672 { Wasm_link. module_name = " OCaml"
633673 ; file
634674 ; code = None
@@ -641,10 +681,17 @@ let run
641681 ~output_file: tmp_wasm_file
642682 in
643683 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);
644691 if enable_source_maps
645692 then
646693 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)
648695 []
649696 in
650697 Link. add_info z ~build_info: (Build_info. create `Cma ) ~unit_data () ;
0 commit comments