@@ -245,7 +245,14 @@ 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; _ } =
248+ let Driver.
249+ { program
250+ ; variable_uses
251+ ; in_cps
252+ ; deadcode_sentinal
253+ ; shapes = _
254+ ; trampolined_calls = _
255+ } =
249256 Driver. optimize ~profile ~shapes: false code
250257 in
251258 let context = Generate. start () in
@@ -327,6 +334,16 @@ let add_source_map sourcemap_don't_inline_content z opt_source_map =
327334 ~name: (Link. source_name i j file)
328335 ~contents: (Yojson.Basic. to_string (`String sm))))
329336
337+ let merge_shape a b =
338+ StringMap. union (fun _name s1 s2 -> if Shape. equal s1 s2 then Some s1 else None ) a b
339+
340+ let sexp_of_shapes s =
341+ StringMap. bindings s
342+ |> List. map ~f: (fun (name , shape ) ->
343+ Sexp. List [ Atom name; Atom (Shape. to_string shape) ])
344+
345+ let string_of_shapes s = Sexp. List (sexp_of_shapes s) |> Sexp. to_string
346+
330347let run
331348 { Cmd_arg. common
332349 ; profile
@@ -340,11 +357,24 @@ let run
340357 ; sourcemap_root
341358 ; sourcemap_don't_inline_content
342359 ; effects
360+ ; shape_files
343361 } =
344362 Config. set_target `Wasm ;
345363 Jsoo_cmdline.Arg. eval common;
346364 Config. set_effects_backend effects;
347365 Generate. init () ;
366+ List. iter shape_files ~f: (fun s ->
367+ let z = Zip. open_in s in
368+ if Zip. has_entry z ~name: " shapes.sexp"
369+ then
370+ let s = Zip. read_entry z ~name: " shapes.sexp" in
371+ match Sexp. from_string s with
372+ | List l ->
373+ List. iter l ~f: (function
374+ | Sexp. List [ Atom name; Atom shape ] ->
375+ Shape.Store. set ~name (Shape. of_string shape)
376+ | _ -> () )
377+ | _ -> () );
348378 let output_file = fst output_file in
349379 if debug_mem () then Debug. start_profiling output_file;
350380 List. iter params ~f: (fun (s , v ) -> Config.Param. set s v);
@@ -397,9 +427,17 @@ let run
397427 check_debug one;
398428 let code = one.code in
399429 let standalone = Option. is_none unit_name in
400- let Driver. { program; variable_uses; in_cps; deadcode_sentinal; _ } =
401- Driver. optimize ~profile ~shapes: false code
430+ let Driver.
431+ { program
432+ ; variable_uses
433+ ; in_cps
434+ ; deadcode_sentinal
435+ ; shapes
436+ ; trampolined_calls = _
437+ } =
438+ Driver. optimize ~profile ~shapes: true code
402439 in
440+ StringMap. iter (fun name shape -> Shape.Store. set ~name shape) shapes;
403441 let context = Generate. start () in
404442 let toplevel_name, generated_js =
405443 Generate. f
@@ -420,7 +458,7 @@ let run
420458 Generate. output ch ~context ;
421459 close_out ch);
422460 if times () then Format. eprintf " compilation: %a@." Timer. print t;
423- generated_js
461+ generated_js, shapes
424462 in
425463 (if runtime_only
426464 then (
@@ -476,7 +514,7 @@ let run
476514 then Some (Filename. temp_file unit_name " .wasm.map" )
477515 else None )
478516 @@ fun opt_tmp_map_file ->
479- let unit_data =
517+ let unit_data, shapes =
480518 Fs. with_intermediate_file (Filename. temp_file unit_name " .wasm" )
481519 @@ fun input_file ->
482520 opt_with
@@ -485,7 +523,7 @@ let run
485523 then Some (Filename. temp_file unit_name " .wasm.map" )
486524 else None )
487525 @@ fun opt_input_sourcemap ->
488- let fragments =
526+ let fragments, shapes =
489527 output
490528 code
491529 ~wat_file:
@@ -501,9 +539,9 @@ let run
501539 ~input_file
502540 ~output_file: tmp_wasm_file
503541 () ;
504- { Link. unit_name; unit_info; fragments }
542+ { Link. unit_name; unit_info; fragments }, shapes
505543 in
506- cont unit_data unit_name tmp_wasm_file opt_tmp_map_file
544+ cont unit_data unit_name tmp_wasm_file opt_tmp_map_file shapes
507545 in
508546 (match kind with
509547 | `Exe ->
@@ -534,7 +572,7 @@ let run
534572 then Some (Filename. temp_file " code" " .wasm.map" )
535573 else None
536574 in
537- let generated_js =
575+ let generated_js, _shapes =
538576 output
539577 code
540578 ~unit_name: None
@@ -598,8 +636,9 @@ let run
598636 @@ fun tmp_output_file ->
599637 let z = Zip. open_out tmp_output_file in
600638 let compile_cmo' z cmo =
601- compile_cmo cmo (fun unit_data _ tmp_wasm_file opt_tmp_map_file ->
639+ compile_cmo cmo (fun unit_data _ tmp_wasm_file opt_tmp_map_file shapes ->
602640 Zip. add_file z ~name: " code.wasm" ~file: tmp_wasm_file;
641+ Zip. add_entry z ~name: " shapes.sexp" ~contents: (string_of_shapes shapes);
603642 add_source_map sourcemap_don't_inline_content z (`File opt_tmp_map_file);
604643 unit_data)
605644 in
@@ -615,8 +654,8 @@ let run
615654 List. fold_right
616655 ~f: (fun cmo cont l ->
617656 compile_cmo cmo
618- @@ fun unit_data unit_name tmp_wasm_file opt_tmp_map_file ->
619- cont ((unit_data, unit_name, tmp_wasm_file, opt_tmp_map_file) :: l))
657+ @@ fun unit_data unit_name tmp_wasm_file opt_tmp_map_file shapes ->
658+ cont ((unit_data, unit_name, tmp_wasm_file, opt_tmp_map_file, shapes ) :: l))
620659 cma.lib_units
621660 ~init: (fun l ->
622661 Fs. with_intermediate_file (Filename. temp_file " wasm" " .wasm" )
@@ -625,7 +664,7 @@ let run
625664 let source_map =
626665 Wasm_link. f
627666 (List. map
628- ~f: (fun (_ , _ , file , opt_source_map ) ->
667+ ~f: (fun (_ , _ , file , opt_source_map , _ ) ->
629668 { Wasm_link. module_name = " OCaml"
630669 ; file
631670 ; code = None
@@ -638,10 +677,17 @@ let run
638677 ~output_file: tmp_wasm_file
639678 in
640679 Zip. add_file z ~name: " code.wasm" ~file: tmp_wasm_file;
680+ let shapes =
681+ List. fold_left
682+ ~init: StringMap. empty
683+ ~f: (fun acc (_ , _ , _ , _ , shapes ) -> merge_shape acc shapes)
684+ l
685+ in
686+ Zip. add_entry z ~name: " shapes.sexp" ~contents: (string_of_shapes shapes);
641687 if enable_source_maps
642688 then
643689 add_source_map sourcemap_don't_inline_content z (`Source_map source_map);
644- List. map ~f: (fun (unit_data , _ , _ , _ ) -> unit_data) l)
690+ List. map ~f: (fun (unit_data , _ , _ , _ , _ ) -> unit_data) l)
645691 []
646692 in
647693 Link. add_info z ~build_info: (Build_info. create `Cma ) ~unit_data () ;
0 commit comments