@@ -84,15 +84,19 @@ let common_binaryen_options () =
8484 in
8585 if Config.Flag. pretty () then " -g" :: l else l
8686
87- let link runtime_files input_file output_file =
87+ let link ~ enable_source_maps runtime_files input_file output_file =
8888 command
8989 (" wasm-merge"
9090 :: (common_binaryen_options ()
9191 @ List. flatten
9292 (List. map
9393 ~f: (fun runtime_file -> [ Filename. quote runtime_file; " env" ])
9494 runtime_files)
95- @ [ Filename. quote input_file; " exec" ; " -o" ; Filename. quote output_file ]))
95+ @ [ Filename. quote input_file; " exec" ; " -o" ; Filename. quote output_file ]
96+ @
97+ if enable_source_maps
98+ then [ " --output-source-map" ; Filename. quote (output_file ^ " .map" ) ]
99+ else [] ))
96100
97101let generate_dependencies primitives =
98102 Yojson.Basic. to_string
@@ -120,7 +124,7 @@ let filter_unused_primitives primitives usage_file =
120124 with End_of_file -> () );
121125 ! s
122126
123- let dead_code_elimination in_file out_file =
127+ let dead_code_elimination ~ enable_source_maps in_file out_file =
124128 with_intermediate_file (Filename. temp_file " deps" " .json" )
125129 @@ fun deps_file ->
126130 with_intermediate_file (Filename. temp_file " usage" " .txt" )
@@ -130,14 +134,15 @@ let dead_code_elimination in_file out_file =
130134 command
131135 (" wasm-metadce"
132136 :: (common_binaryen_options ()
133- @ [ " --graph-file"
134- ; Filename. quote deps_file
135- ; Filename. quote in_file
136- ; " -o"
137- ; Filename. quote out_file
138- ; " >"
139- ; Filename. quote usage_file
140- ]));
137+ @ [ " --graph-file" ; Filename. quote deps_file; Filename. quote in_file ]
138+ @ (if enable_source_maps
139+ then [ " --input-source-map" ; Filename. quote (in_file ^ " .map" ) ]
140+ else [] )
141+ @ [ " -o" ; Filename. quote out_file ]
142+ @ (if enable_source_maps
143+ then [ " --output-source-map" ; Filename. quote (out_file ^ " .map" ) ]
144+ else [] )
145+ @ [ " >" ; Filename. quote usage_file ]));
141146 filter_unused_primitives primitives usage_file
142147
143148let optimization_options =
@@ -146,29 +151,62 @@ let optimization_options =
146151 ; [ " -O3" ; " --traps-never-happen" ]
147152 |]
148153
149- let optimize ~profile in_file out_file =
154+ let optimize ~profile ? sourcemap_file in_file out_file =
150155 let level =
151156 match profile with
152157 | None -> 1
153158 | Some p -> fst (List. find ~f: (fun (_ , p' ) -> Poly. equal p p') Driver. profiles)
154159 in
155160 command
156161 (" wasm-opt"
157- :: (common_binaryen_options ()
158- @ optimization_options.(level - 1 )
159- @ [ Filename. quote in_file; " -o" ; Filename. quote out_file ]))
162+ :: (common_binaryen_options ()
163+ @ optimization_options.(level - 1 )
164+ @ [ Filename. quote in_file; " -o" ; Filename. quote out_file ])
165+ @
166+ match sourcemap_file with
167+ | Some sourcemap_file ->
168+ [ " --input-source-map"
169+ ; Filename. quote (in_file ^ " .map" )
170+ ; " --output-source-map"
171+ ; Filename. quote sourcemap_file
172+ ; " --output-source-map-url"
173+ ; Filename. quote sourcemap_file
174+ ]
175+ | None -> [] )
160176
161- let link_and_optimize ~profile runtime_wasm_files wat_file output_file =
177+ let link_and_optimize ~profile ?sourcemap_file runtime_wasm_files wat_file output_file =
178+ let sourcemap_file =
179+ (* Check that Binaryen supports the necessary sourcemaps options (requires
180+ version >= 118) *)
181+ match sourcemap_file with
182+ | Some _ when Sys. command " wasm-merge -osm foo 2> /dev/null" <> 0 -> None
183+ | Some _ | None -> sourcemap_file
184+ in
185+ let enable_source_maps = Option. is_some sourcemap_file in
162186 with_intermediate_file (Filename. temp_file " runtime" " .wasm" )
163187 @@ fun runtime_file ->
164188 write_file runtime_file Wa_runtime. wasm_runtime;
165189 with_intermediate_file (Filename. temp_file " wasm-merged" " .wasm" )
166190 @@ fun temp_file ->
167- link (runtime_file :: runtime_wasm_files) wat_file temp_file;
191+ link ~enable_source_maps (runtime_file :: runtime_wasm_files) wat_file temp_file;
168192 with_intermediate_file (Filename. temp_file " wasm-dce" " .wasm" )
169193 @@ fun temp_file' ->
170- let primitives = dead_code_elimination temp_file temp_file' in
171- optimize ~profile temp_file' output_file;
194+ let primitives = dead_code_elimination ~enable_source_maps temp_file temp_file' in
195+ optimize ~profile ?sourcemap_file temp_file' output_file;
196+ (* Add source file contents to source map *)
197+ Option. iter sourcemap_file ~f: (fun sourcemap_file ->
198+ let open Source_map in
199+ let source_map, mappings = Source_map_io. of_file_no_mappings sourcemap_file in
200+ assert (List. is_empty (Option. value source_map.sources_content ~default: [] ));
201+ let sources_content =
202+ Some
203+ (List. map source_map.sources ~f: (fun file ->
204+ if Sys. file_exists file && not (Sys. is_directory file)
205+ then Some (Fs. read_file file)
206+ else None ))
207+ in
208+ let source_map = { source_map with sources_content } in
209+ Source_map_io. to_file ?mappings source_map ~file: sourcemap_file);
172210 primitives
173211
174212let escape_string s =
@@ -276,7 +314,15 @@ let build_js_runtime primitives (strings, fragments) wasm_file output_file =
276314 ^ trim_semi (Buffer. contents fragment_buffer)
277315 ^ String. sub s ~pos: (l + 9 ) ~len: (String. length s - l - 9 ))
278316
279- let run { Cmd_arg. common; profile; runtime_files; input_file; output_file; params } =
317+ let run
318+ { Cmd_arg. common
319+ ; profile
320+ ; runtime_files
321+ ; input_file
322+ ; output_file
323+ ; enable_source_maps
324+ ; params
325+ } =
280326 Jsoo_cmdline.Arg. eval common;
281327 Wa_generate. init () ;
282328 let output_file = fst output_file in
@@ -316,7 +362,7 @@ let run { Cmd_arg.common; profile; runtime_files; input_file; output_file; param
316362 let need_debug = Config.Flag. debuginfo () in
317363 let output (one : Parse_bytecode.one ) ~standalone ch =
318364 let code = one.code in
319- let live_vars, in_cps, p =
365+ let live_vars, in_cps, p, debug =
320366 Driver. f
321367 ~target: Wasm
322368 ~standalone
@@ -326,7 +372,7 @@ let run { Cmd_arg.common; profile; runtime_files; input_file; output_file; param
326372 one.debug
327373 code
328374 in
329- let strings = Wa_generate. f ch ~live_vars ~in_cps p in
375+ let strings = Wa_generate. f ch ~debug ~ live_vars ~in_cps p in
330376 if times () then Format. eprintf " compilation: %a@." Timer. print t;
331377 strings
332378 in
@@ -367,7 +413,13 @@ let run { Cmd_arg.common; profile; runtime_files; input_file; output_file; param
367413 @@ fun tmp_wasm_file ->
368414 let strings = output_gen wat_file (output code ~standalone: true ) in
369415 let primitives =
370- link_and_optimize ~profile runtime_wasm_files wat_file tmp_wasm_file
416+ link_and_optimize
417+ ~profile
418+ ?sourcemap_file:
419+ (if enable_source_maps then Some (wasm_file ^ " .map" ) else None )
420+ runtime_wasm_files
421+ wat_file
422+ tmp_wasm_file
371423 in
372424 build_js_runtime primitives strings wasm_file output_file
373425 | `Cmo _ | `Cma _ -> assert false );
0 commit comments