Skip to content

Commit 65aeb1c

Browse files
committed
CR
1 parent 54bf201 commit 65aeb1c

File tree

7 files changed

+96
-69
lines changed

7 files changed

+96
-69
lines changed

compiler/bin-js_of_ocaml/compile.ml

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ let find_source file =
8484
Some (Source_map.Source_content.create content)
8585
else None
8686

87-
let build_source_map_with_offset
88-
(sm : Source_map.Standard.t)
87+
let sourcemap_section_of_info
88+
~base:(sm : Source_map.Standard.t)
8989
{ Source_map.sources; names; mappings } =
9090
let sources_content =
9191
match sm.sources_content with
@@ -98,27 +98,25 @@ let build_source_map_with_offset
9898
| None -> filename
9999
| Some _ -> Filename.concat "/builtin" filename)
100100
in
101-
let line_offset, mappings = Source_map.Mappings.encode_with_offset mappings in
102-
( line_offset
103-
, { (sm : Source_map.Standard.t) with sources; sources_content; names; mappings } )
101+
let offset, mappings = Source_map.Mappings.encode_with_offset mappings in
102+
let map =
103+
{ (sm : Source_map.Standard.t) with sources; sources_content; names; mappings }
104+
in
105+
{ Source_map.Index.offset; map }
104106

105-
let build_source_map_many base l =
107+
let sourcemap_of_infos ~base l =
106108
match base with
107109
| None -> None
108110
| Some (sm : Source_map.Standard.t) ->
109-
let sections =
110-
List.map l ~f:(fun info ->
111-
let line_offset, sm = build_source_map_with_offset sm info in
112-
{ Source_map.Index.gen_line = line_offset; gen_column = 0 }, `Map sm)
113-
in
111+
let sections = List.map l ~f:(sourcemap_section_of_info ~base:sm) in
114112
Some
115113
(Source_map.Index
116114
{ Source_map.Index.version = sm.Source_map.Standard.version
117115
; file = sm.file
118116
; sections
119117
})
120118

121-
let build_source_map_one base info = build_source_map_many base [ info ]
119+
let sourcemap_of_info ~base info = sourcemap_of_infos ~base [ info ]
122120

123121
let run
124122
{ Cmd_arg.common
@@ -373,7 +371,7 @@ let run
373371
~standalone
374372
~link:`All
375373
output_file
376-
|> build_source_map_one source_map_base)
374+
|> sourcemap_of_info ~base:source_map_base)
377375
| (`Stdin | `File _) as bytecode ->
378376
let kind, ic, close_ic, include_dirs =
379377
match bytecode with
@@ -419,7 +417,7 @@ let run
419417
~source_map
420418
~link:(if linkall then `All else `Needed)
421419
output_file
422-
|> build_source_map_one source_map_base)
420+
|> sourcemap_of_info ~base:source_map_base)
423421
| `Cmo cmo ->
424422
let output_file =
425423
match output_file, keep_unit_names with
@@ -454,10 +452,10 @@ let run
454452
| true ->
455453
let sm1 = output_partial_runtime ~standalone ~source_map output in
456454
let sm2 = output_partial cmo code ~standalone ~source_map output in
457-
build_source_map_many source_map_base [ sm1; sm2 ]
455+
sourcemap_of_infos ~base:source_map_base [ sm1; sm2 ]
458456
| false ->
459457
output_partial cmo code ~standalone ~source_map output
460-
|> build_source_map_one source_map_base)
458+
|> sourcemap_of_info ~base:source_map_base)
461459
| `Cma cma when keep_unit_names ->
462460
(if include_runtime
463461
then
@@ -480,7 +478,7 @@ let run
480478
(`Name output_file)
481479
(fun ~standalone ~source_map output ->
482480
output_partial_runtime ~standalone ~source_map output
483-
|> build_source_map_one source_map_base));
481+
|> sourcemap_of_info ~base:source_map_base));
484482
List.iter cma.lib_units ~f:(fun cmo ->
485483
let output_file =
486484
match output_file with
@@ -516,7 +514,7 @@ let run
516514
(`Name output_file)
517515
(fun ~standalone ~source_map output ->
518516
output_partial ~standalone ~source_map cmo code output
519-
|> build_source_map_one source_map_base))
517+
|> sourcemap_of_info ~base:source_map_base))
520518
| `Cma cma ->
521519
let f ~standalone ~source_map output =
522520
let source_map_runtime =
@@ -550,7 +548,7 @@ let run
550548
| None -> source_map_units
551549
| Some x -> x :: source_map_units
552550
in
553-
build_source_map_many source_map_base sm
551+
sourcemap_of_infos ~base:source_map_base sm
554552
in
555553
output_gen
556554
~standalone:false

compiler/lib/link_js.ml

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,9 @@ let action ~resolve_sourcemap_url ~drop_source_map file line =
162162
| `Build_info bi, _ -> Build_info bi
163163
| (`Json_base64 _ | `Url _), true -> Drop
164164
| `Json_base64 offset, false ->
165-
Source_map (Source_map.of_string (Base64.decode_exn ~off:offset line))
165+
let raw = Base64.decode_exn ~off:offset line in
166+
let sm = Source_map.of_string raw in
167+
Source_map sm
166168
| `Url _, false when not resolve_sourcemap_url -> Drop
167169
| `Url offset, false ->
168170
let url = String.sub line ~pos:offset ~len:(String.length line - offset) in
@@ -385,6 +387,7 @@ let link ~output ~linkall ~mklib ~toplevel ~files ~resolve_sourcemap_url ~source
385387
"Skip %s@."
386388
(String.concat ~sep:"," (StringSet.elements u.provides));
387389
let lnum = ref 0 in
390+
let read_loffset = Line_reader.lnum ic in
388391
while
389392
match Line_reader.peek ic with
390393
| None -> false
@@ -396,8 +399,8 @@ let link ~output ~linkall ~mklib ~toplevel ~files ~resolve_sourcemap_url ~source
396399
skip ic;
397400
incr lnum
398401
done;
399-
let data_r = Line_reader.lnum ic - !lnum in
400-
reloc := `Drop (data_r, !lnum) :: !reloc)
402+
assert (read_loffset + !lnum = Line_reader.lnum ic);
403+
reloc := `Drop (read_loffset, !lnum) :: !reloc)
401404
| Source_map x ->
402405
skip ic;
403406
sm_for_file := Some x);
@@ -456,12 +459,12 @@ let link ~output ~linkall ~mklib ~toplevel ~files ~resolve_sourcemap_url ~source
456459
| Index sm ->
457460
List.map
458461
sm.Source_map.Index.sections
459-
~f:(fun ({ gen_line; gen_column }, `Map sm) ->
460-
( gen_line + Source_map.Mappings.first_line sm.mappings
461-
, gen_line + Source_map.Mappings.number_of_lines sm.mappings
462+
~f:(fun { offset = { gen_line; gen_column }; map } ->
463+
( gen_line + Source_map.Mappings.first_line map.mappings
464+
, gen_line + Source_map.Mappings.number_of_lines map.mappings
462465
, gen_line
463466
, gen_column
464-
, sm ))
467+
, map ))
465468
in
466469
(* select sourcemaps that cover copied section *)
467470
let maps =
@@ -494,8 +497,9 @@ let link ~output ~linkall ~mklib ~toplevel ~files ~resolve_sourcemap_url ~source
494497
; sections =
495498
(* preserve some info from [init_sm] *)
496499
List.map sections ~f:(fun (_, _, gen_line, gen_column, sm) ->
497-
( { Source_map.Index.gen_line; gen_column }
498-
, `Map { sm with sourceroot = init_sm.sourceroot } ))
500+
{ Source_map.Index.offset = { gen_line; gen_column }
501+
; map = { sm with sourceroot = init_sm.sourceroot }
502+
})
499503
}
500504
in
501505
let sm = Source_map.Index sm in

compiler/lib/source_map.ml

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,21 @@ let gen_line = function
5757
let gen_col = function
5858
| Gen { gen_col; _ } | Gen_Ori { gen_col; _ } | Gen_Ori_Name { gen_col; _ } -> gen_col
5959

60+
module Offset = struct
61+
type t =
62+
{ gen_line : int
63+
; gen_column : int
64+
}
65+
end
66+
6067
module Mappings = struct
6168
type decoded = map list
6269

6370
type t = Uninterpreted of string [@@unboxed]
6471

6572
let empty = Uninterpreted ""
6673

67-
let of_string : string -> t = fun s -> Uninterpreted s
74+
let of_string_unsafe : string -> t = fun s -> Uninterpreted s
6875

6976
let to_string : t -> string = fun (Uninterpreted s) -> s
7077

@@ -185,13 +192,15 @@ module Mappings = struct
185192
offset, Uninterpreted (Buffer.contents buf)
186193

187194
let encode mapping =
188-
let offset, res = encode' ~offset:false mapping in
189-
assert (offset = 0);
195+
let gen_line, res = encode' ~offset:false mapping in
196+
assert (gen_line = 0);
190197
res
191198

192-
let encode_with_offset mapping = encode' ~offset:true mapping
199+
let encode_with_offset mapping =
200+
let gen_line, res = encode' ~offset:true mapping in
201+
{ Offset.gen_line; gen_column = 0 }, res
193202

194-
let decode (Uninterpreted str) =
203+
let decode_exn (Uninterpreted str) =
195204
let total_len = String.length str in
196205
let gen_col = ref 0 in
197206
let ori_source = ref 0 in
@@ -336,7 +345,7 @@ module Standard = struct
336345
Gen_Ori_Name { gen_line; gen_col; ori_source; ori_line; ori_col; ori_name }
337346

338347
let filter_map sm ~f =
339-
let a = Array.of_list (Mappings.decode sm.mappings) in
348+
let a = Array.of_list (Mappings.decode_exn sm.mappings) in
340349
Array.stable_sort
341350
~cmp:(fun t1 t2 ->
342351
match compare (gen_line t1) (gen_line t2) with
@@ -391,7 +400,7 @@ module Standard = struct
391400
}
392401
, List.rev_append_map
393402
~f:(maps ~sources_offset ~names_offset)
394-
(Mappings.decode sm.mappings)
403+
(Mappings.decode_exn sm.mappings)
395404
mappings_rev )
396405
in
397406
loop
@@ -477,7 +486,7 @@ module Standard = struct
477486
let mappings =
478487
match string "mappings" rest with
479488
| None -> Mappings.empty
480-
| Some s -> Mappings.of_string s
489+
| Some s -> Mappings.of_string_unsafe s
481490
in
482491
{ version = int_of_float (float_of_string version)
483492
; file
@@ -496,15 +505,15 @@ end
496505
(* IO *)
497506

498507
module Index = struct
499-
type offset =
500-
{ gen_line : int
501-
; gen_column : int
508+
type section =
509+
{ offset : Offset.t
510+
; map : Standard.t
502511
}
503512

504513
type t =
505514
{ version : int
506515
; file : string option
507-
; sections : (offset * [ `Map of Standard.t ]) list
516+
; sections : section list
508517
}
509518

510519
let json t =
@@ -524,14 +533,14 @@ module Index = struct
524533
, Some
525534
(`List
526535
(List.map
527-
~f:(fun ({ gen_line; gen_column }, `Map sm) ->
536+
~f:(fun { offset = { gen_line; gen_column }; map } ->
528537
`Assoc
529538
[ ( "offset"
530539
, `Assoc
531540
[ "line", `Intlit (string_of_int gen_line)
532541
; "column", `Intlit (string_of_int gen_column)
533542
] )
534-
; "map", Standard.json sm
543+
; "map", Standard.json map
535544
])
536545
t.sections)) )
537546
])
@@ -542,7 +551,7 @@ module Index = struct
542551
| _ -> invalid_arg errmsg
543552
| exception Not_found -> invalid_arg errmsg
544553

545-
let section_of_json : Yojson.Raw.t -> offset * [ `Map of Standard.t ] = function
554+
let section_of_json : Yojson.Raw.t -> section = function
546555
| `Assoc json ->
547556
let offset =
548557
match List.assoc "offset" json with
@@ -563,7 +572,7 @@ module Index = struct
563572
"Source_map_io.Index.of_json: field 'column' absent or invalid from \
564573
section"
565574
in
566-
{ gen_line; gen_column }
575+
{ Offset.gen_line; gen_column }
567576
| _ ->
568577
invalid_arg "Source_map_io.Index.of_json: 'offset' field of unexpected type"
569578
in
@@ -579,7 +588,7 @@ module Index = struct
579588
| Invalid_argument _ ->
580589
invalid_arg "Source_map_io.Index.of_json: invalid sub-map object"
581590
in
582-
offset, `Map map
591+
{ offset; map }
583592
| _ -> invalid_arg "Source_map_io.Index.of_json: section of unexpected type"
584593

585594
let of_json = function

compiler/lib/source_map.mli

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,35 +44,46 @@ type map =
4444
; ori_name : int
4545
}
4646

47+
module Offset : sig
48+
type t =
49+
{ gen_line : int
50+
; gen_column : int
51+
}
52+
end
53+
4754
module Mappings : sig
4855
type decoded = map list
4956

5057
type t
58+
(** Represent the a list of mapping in its encoded form. *)
5159

5260
val empty : t
53-
(** Represents the empty mapping. *)
61+
(** The empty mapping. *)
5462

55-
val of_string : string -> t
56-
(** By default, mappings are left uninterpreted, since many operations can be
57-
performed efficiently directly on the encoded form. Therefore this
58-
function is mostly a no-op and very cheap. It does not perform any
63+
val of_string_unsafe : string -> t
64+
(** [of_string_unsafe] does not perform any
5965
validation of its argument, unlike {!val:decode}. It is guaranteed that
60-
{!val:of_string} and {!val:to_string} are inverse functions. *)
66+
{!val:of_string_unsafe} and {!val:to_string} are inverse functions.
67+
Time complexity O(1) *)
6168

62-
val decode : t -> decoded
69+
val decode_exn : t -> decoded
6370
(** Parse the mappings. *)
6471

6572
val encode : decoded -> t
73+
(** Encode the mappings. *)
6674

67-
val encode_with_offset : decoded -> int * t
75+
val encode_with_offset : decoded -> Offset.t * t
76+
(** Encode the mappings shifted by the returned offset so that the
77+
encoded mapping is more compact. This is useful to combining
78+
multiple mappings into an [Index.t] *)
6879

6980
val number_of_lines : t -> int
7081

7182
val first_line : t -> int
7283

7384
val to_string : t -> string
74-
(** Returns the mappings as a string in the Source map v3 format. This
75-
function is mostly a no-op and is very cheap. *)
85+
(** Returns the mappings as a string in the Source map v3 format.
86+
Time complexity O(1) *)
7687
end
7788

7889
module Standard : sig
@@ -102,15 +113,15 @@ module Standard : sig
102113
end
103114

104115
module Index : sig
105-
type offset =
106-
{ gen_line : int
107-
; gen_column : int
116+
type section =
117+
{ offset : Offset.t
118+
; map : Standard.t
108119
}
109120

110-
type nonrec t =
121+
type t =
111122
{ version : int
112123
; file : string option
113-
; sections : (offset * [ `Map of Standard.t ]) list
124+
; sections : section list
114125
}
115126
end
116127

compiler/tests-compiler/build_path_prefix_map.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ let%expect_test _ =
3737
|> function
3838
| Some (Standard (sm : Js_of_ocaml_compiler.Source_map.Standard.t)) ->
3939
print_section sm
40-
| Some (Index i) -> List.iter i.sections ~f:(fun (_, `Map sm) -> print_section sm)
40+
| Some (Index i) ->
41+
List.iter
42+
i.sections
43+
~f:(fun { Js_of_ocaml_compiler.Source_map.Index.offset = _; map } ->
44+
print_section map)
4145
| None -> failwith "no sourcemap generated!");
4246
[%expect
4347
{|

0 commit comments

Comments
 (0)