Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source map improvements #1716

Merged
merged 35 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
cc24d3a
Document source maps
vouillon Oct 14, 2024
54ee079
JavaScript if statement simplification: use appropriate locations
vouillon Oct 18, 2024
38b132b
Do not emit unnecessary source mappings
vouillon Oct 16, 2024
228f2e0
Adjust source mapping location for variable declarations
vouillon Oct 16, 2024
2b09011
Put the function call location on the opening parenthesis as well
vouillon Oct 18, 2024
043ebc8
Add location after return statement
vouillon Oct 18, 2024
c3f179e
Add location on new expression
vouillon Oct 18, 2024
c3d5dfd
Change way of filtering out dummy locations
vouillon Oct 11, 2024
98bdcd4
Indicate the origin location of modules and exceptions as well
vouillon Oct 14, 2024
a48ae9a
Generate: put location on function calls
vouillon Oct 11, 2024
bbb3352
Add space to remove ambiguity
vouillon Oct 18, 2024
7e3c91b
Source map: only specify the names of bindings
vouillon Oct 14, 2024
7c58966
Debug info output improvements
vouillon Oct 14, 2024
2155f99
Add an `Event` instruction
vouillon Oct 14, 2024
4fd0880
Parse_bytecode: clean-up
vouillon Oct 14, 2024
4459bec
Propage locations across blocks
vouillon Oct 18, 2024
01a1c93
Make sure there is a location at the start of functions
vouillon Oct 18, 2024
42d949e
Compile exception handlers starting from an unkown location
vouillon Oct 18, 2024
6083873
Add appropriate events for partial application and over application
vouillon Oct 14, 2024
4df3933
Mutually recursive functions: add locations in wrapper
vouillon Oct 18, 2024
7067177
Refactor the generation of JavaScript expressions.
vouillon Oct 21, 2024
bf7fc83
Improved statement locations
vouillon Oct 16, 2024
1fa0156
Source maps: use ignoreList to hide runtime files
vouillon Oct 17, 2024
59c9878
Source map: repeat mappings over new lines
vouillon Oct 17, 2024
46686ba
Changes
vouillon Oct 18, 2024
720dff1
LWT toplevel example: do not generate a source map
vouillon Oct 18, 2024
a28fa70
Consider more precisely all debug event kinds
vouillon Oct 21, 2024
0277651
Handle the case where there there are several events at the same loca…
vouillon Oct 21, 2024
f2abe1b
Make the code to recognize the implementation of the `(^)` operator m…
vouillon Oct 21, 2024
7340d2b
Avoid additional block splitting during CPS transformation
vouillon Oct 21, 2024
189b231
Change strategy to avoid ambiguity after a return statement
vouillon Oct 22, 2024
1631718
Check additional code and source map invariants
vouillon Oct 22, 2024
d0ce5f0
No longer keep track of the location of identifiers
vouillon Oct 22, 2024
69ca702
Make sure that the name of an identifier does not bleed on another one
vouillon Oct 23, 2024
7cd112c
Compiler: more cleanup in parse_bytecode
hhugo Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* Compiler: warn on joo_global_object
* Compiler: revisit static env handling (#1708)
* Compiler: Emit index source_map to avoid changing mappings (#1714, #1715)
* Compiler: improved source map generation (#1716)
* Runtime: change Sys.os_type on windows (Cygwin -> Win32)
* Runtime: backtraces are really expensive, they need to be be explicitly
requested at compile time (--enable with-js-error) or at startup (OCAMLRUNPARAM=b=1)
Expand Down
15 changes: 13 additions & 2 deletions compiler/bin-js_of_ocaml/compile.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ let find_source file =
match Builtins.find file with
| Some f -> Some (Source_map.Source_content.create (Builtins.File.content f))
| None ->
if Sys.file_exists file && not (Sys.is_directory file)
if String.equal file Js_output.blackbox_filename
then Some (Source_map.Source_content.create "(* generated code *)")
else if Sys.file_exists file && not (Sys.is_directory file)
then
let content = Fs.read_file file in
Some (Source_map.Source_content.create content)
Expand All @@ -99,9 +101,18 @@ let sourcemap_section_of_info
| None -> filename
| Some _ -> Filename.concat "/builtin" filename)
in
let ignore_list =
List.filter sources ~f:(fun filename -> String.is_prefix ~prefix:"/builtin/" filename)
in
let offset, mappings = Source_map.Mappings.encode_with_offset mappings in
let map =
{ (base : Source_map.Standard.t) with sources; sources_content; names; mappings }
{ (base : Source_map.Standard.t) with
sources
; sources_content
; names
; mappings
; ignore_list
}
in
{ Source_map.Index.offset; map }

Expand Down
31 changes: 11 additions & 20 deletions compiler/lib/code.ml
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ module Var : sig

val compare : t -> t -> int

val get_loc : t -> Parse_info.t option

val loc : t -> Parse_info.t -> unit

val name : t -> string -> unit

val get_name : t -> string option
Expand Down Expand Up @@ -157,13 +153,10 @@ end = struct

let printer = Var_printer.create Var_printer.Alphabet.javascript

let locations = Hashtbl.create 17

let last_var = ref 0

let reset () =
last_var := 0;
Hashtbl.clear locations;
Var_printer.reset printer

let to_string ?origin i = Var_printer.to_string printer ?origin i
Expand All @@ -174,14 +167,6 @@ end = struct

let name i nm = Var_printer.name printer i nm

let loc i pi = Hashtbl.add locations i pi

(*;
Format.eprintf "loc for %d : %d-%d\n%!"
i pi.Parse_info.line pi.Parse_info.col
*)
let get_loc i = try Some (Hashtbl.find locations i) with Not_found -> None

let fresh () =
incr last_var;
!last_var
Expand All @@ -199,11 +184,7 @@ end = struct

let get_name i = Var_printer.get_name printer i

let propagate_name i j =
Var_printer.propagate_name printer i j;
match get_loc i with
| None -> ()
| Some l -> loc j l
let propagate_name i j = Var_printer.propagate_name printer i j

let set_pretty b = Var_printer.set_pretty printer b

Expand Down Expand Up @@ -446,6 +427,7 @@ type instr =
| Set_field of Var.t * int * field_type * Var.t
| Offset_ref of Var.t * int
| Array_set of Var.t * Var.t * Var.t
| Event of Parse_info.t

type last =
| Return of Var.t
Expand Down Expand Up @@ -604,6 +586,7 @@ module Print = struct
| Offset_ref (x, i) -> Format.fprintf f "%a[0] += %d" Var.print x i
| Array_set (x, y, z) ->
Format.fprintf f "%a[%a] = %a" Var.print x Var.print y Var.print z
| Event loc -> Format.fprintf f "event %s" (Parse_info.to_string loc)

let last f (l, _loc) =
match l with
Expand Down Expand Up @@ -905,6 +888,13 @@ let invariant { blocks; start; _ } =
| Set_field (_, _i, _, _) -> ()
| Offset_ref (_x, _i) -> ()
| Array_set (_x, _y, _z) -> ()
| Event _ -> ()
in
let rec check_events l =
match l with
| (Event _, _) :: (Event _, _) :: _ -> assert false
| _ :: r -> check_events r
| [] -> ()
in
let check_last (l, _loc) =
match l with
Expand All @@ -925,5 +915,6 @@ let invariant { blocks; start; _ } =
(fun _pc block ->
List.iter block.params ~f:define;
List.iter block.body ~f:check_instr;
check_events block.body;
check_last block.branch)
blocks)
5 changes: 1 addition & 4 deletions compiler/lib/code.mli
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ module Var : sig

val compare : t -> t -> int

val loc : t -> Parse_info.t -> unit

val get_loc : t -> Parse_info.t option

val get_name : t -> string option

val name : t -> string -> unit
Expand Down Expand Up @@ -229,6 +225,7 @@ type instr =
| Set_field of Var.t * int * field_type * Var.t
| Offset_ref of Var.t * int
| Array_set of Var.t * Var.t * Var.t
| Event of Parse_info.t

type last =
| Return of Var.t
Expand Down
21 changes: 14 additions & 7 deletions compiler/lib/deadcode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ and mark_reachable st pc =
List.iter block.body ~f:(fun (i, _loc) ->
match i with
| Let (_, e) -> if not (pure_expr st.pure_funs e) then mark_expr st e
| Assign _ -> ()
| Event _ | Assign _ -> ()
| Set_field (x, _, _, y) -> (
match st.defs.(Var.idx x) with
| [ Expr (Block _) ] when st.live.(Var.idx x) = 0 ->
Expand Down Expand Up @@ -125,7 +125,7 @@ let live_instr st i =
match i with
| Let (x, e) -> st.live.(Var.idx x) > 0 || not (pure_expr st.pure_funs e)
| Assign (x, _) | Set_field (x, _, _, _) -> st.live.(Var.idx x) > 0
| Offset_ref _ | Array_set _ -> true
| Event _ | Offset_ref _ | Array_set _ -> true

let rec filter_args st pl al =
match pl, al with
Expand Down Expand Up @@ -201,7 +201,8 @@ let f ({ blocks; _ } as p : Code.program) =
match i with
| Let (x, e) -> add_def defs x (Expr e)
| Assign (x, y) -> add_def defs x (Var y)
| Set_field (_, _, _, _) | Array_set (_, _, _) | Offset_ref (_, _) -> ());
| Event _ | Set_field (_, _, _, _) | Array_set (_, _, _) | Offset_ref (_, _) ->
());
match fst block.branch with
| Return _ | Raise _ | Stop -> ()
| Branch cont -> add_cont_dep blocks defs cont
Expand All @@ -228,10 +229,16 @@ let f ({ blocks; _ } as p : Code.program) =
pc
{ params = List.filter block.params ~f:(fun x -> st.live.(Var.idx x) > 0)
; body =
List.filter_map block.body ~f:(fun (i, loc) ->
if live_instr st i
then Some (filter_closure all_blocks st i, loc)
else None)
List.fold_left block.body ~init:[] ~f:(fun acc (i, loc) ->
match i, acc with
| Event _, (Event _, _) :: prev ->
(* Avoid consecutive events (keep just the last one) *)
(i, loc) :: prev
| _ ->
if live_instr st i
then (filter_closure all_blocks st i, loc) :: acc
else acc)
|> List.rev
; branch = filter_live_last all_blocks st block.branch
}
blocks)
Expand Down
1 change: 1 addition & 0 deletions compiler/lib/duplicate.ml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ let instr s i =
| Set_field (x, n, typ, y) -> Set_field (s x, n, typ, s y)
| Offset_ref (x, n) -> Offset_ref (s x, n)
| Array_set (x, y, z) -> Array_set (s x, s y, s z)
| Event _ -> i

let instrs s l = List.map l ~f:(fun (i, loc) -> instr s i, loc)

Expand Down
32 changes: 27 additions & 5 deletions compiler/lib/effects.ml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,28 @@ let dominance_frontier g idom =
g.preds;
frontiers

(* Last instruction of a block, ignoring events *)
let rec last_instr l =
match l with
| [] -> None
| [ i ] | [ i; (Event _, _) ] -> Some i
hhugo marked this conversation as resolved.
Show resolved Hide resolved
| _ :: rem -> last_instr rem

(* Split a block, separating the last instruction from the preceeding
ones, ignoring events *)
let block_split_last xs =
let rec aux acc = function
| [] -> None
| [ x ] | [ x; (Event _, _) ] -> Some (List.rev acc, x)
| x :: xs -> aux (x :: acc) xs
in
aux [] xs

let empty_body b =
match b with
| [] | [ (Event _, _) ] -> true
| _ -> false

(****)

(*
Expand Down Expand Up @@ -176,7 +198,7 @@ let compute_needed_transformations ~cfg ~idom ~cps_needed ~blocks ~start =
let block = Addr.Map.find pc blocks in
(match fst block.branch with
| Branch (dst, _) -> (
match List.last block.body with
match last_instr block.body with
| Some
( Let
(x, (Apply _ | Prim (Extern ("%resume" | "%perform" | "%reperform"), _)))
Expand Down Expand Up @@ -572,7 +594,7 @@ let cps_block ~st ~k pc block =
in

let rewritten_block =
match List.split_last block.body, block.branch with
match block_split_last block.body, block.branch with
| Some (body_prefix, (Let (x, e), loc)), (Return ret, _loc_ret) ->
Option.map (rewrite_instr x e loc) ~f:(fun f ->
assert (List.is_empty alloc_jump_closures);
Expand All @@ -593,7 +615,7 @@ let cps_block ~st ~k pc block =
in
let instrs, branch = f ~k:k' in
body_prefix, constr_cont @ instrs, branch)
| Some (_, ((Set_field _ | Offset_ref _ | Array_set _ | Assign _), _)), _
| Some (_, ((Event _ | Set_field _ | Offset_ref _ | Array_set _ | Assign _), _)), _
| Some _, ((Raise _ | Stop | Cond _ | Switch _ | Pushtrap _ | Poptrap _), _)
| None, _ -> None
in
Expand Down Expand Up @@ -847,7 +869,7 @@ let split_blocks ~cps_needed (p : Code.program) =
let is_split_point i r branch =
match i with
| Let (x, (Apply _ | Prim (Extern ("%resume" | "%perform" | "%reperform"), _))) ->
((not (List.is_empty r))
((not (empty_body r))
||
match fst branch with
| Branch _ -> false
Expand Down Expand Up @@ -904,7 +926,7 @@ let remove_empty_blocks ~live_vars (p : Code.program) : Code.program =
Addr.Map.iter
(fun pc block ->
match block with
| { params; body = []; branch = Branch cont, _; _ } ->
| { params; body; branch = Branch cont, _; _ } when empty_body body ->
let args =
List.fold_left
~f:(fun args x -> Var.Set.add x args)
Expand Down
7 changes: 5 additions & 2 deletions compiler/lib/eval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,11 @@ let rec do_not_raise pc visited blocks =
let b = Addr.Map.find pc blocks in
List.iter b.body ~f:(fun (i, _loc) ->
match i with
| Array_set (_, _, _) | Offset_ref (_, _) | Set_field (_, _, _, _) | Assign _ ->
()
| Event _
| Array_set (_, _, _)
| Offset_ref (_, _)
| Set_field (_, _, _, _)
| Assign _ -> ()
| Let (_, e) -> (
match e with
| Block (_, _, _, _) | Field (_, _, _) | Constant _ | Closure _ -> ()
Expand Down
4 changes: 2 additions & 2 deletions compiler/lib/flow.ml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ let program_deps { blocks; _ } =
| Assign (x, y) ->
add_dep deps x y;
add_assign_def vars defs x y
| Set_field _ | Array_set _ | Offset_ref _ -> ());
| Event _ | Set_field _ | Array_set _ | Offset_ref _ -> ());
match fst block.branch with
| Return _ | Raise _ | Stop -> ()
| Branch cont | Poptrap cont -> cont_deps blocks vars deps defs cont
Expand Down Expand Up @@ -256,7 +256,7 @@ let program_escape defs known_origins { blocks; _ } =
List.iter block.body ~f:(fun (i, _loc) ->
match i with
| Let (x, e) -> expr_escape st x e
| Assign _ -> ()
| Event _ | Assign _ -> ()
| Set_field (x, _, _, y) | Array_set (x, _, y) ->
Var.Set.iter
(fun y -> Var.ISet.add possibly_mutable y)
Expand Down
3 changes: 2 additions & 1 deletion compiler/lib/freevars.ml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ let iter_instr_free_vars f i =
f y;
f z
| Assign (_, y) -> f y
| Event _ -> ()

let iter_last_free_var f l =
match l with
Expand All @@ -79,7 +80,7 @@ let iter_block_free_vars f block =
let iter_instr_bound_vars f i =
match i with
| Let (x, _) -> f x
| Set_field _ | Offset_ref _ | Array_set _ | Assign _ -> ()
| Event _ | Set_field _ | Offset_ref _ | Array_set _ | Assign _ -> ()

let iter_last_bound_vars f l =
match l with
Expand Down
Loading