Skip to content

Commit

Permalink
Compiler: minify labels
Browse files Browse the repository at this point in the history
  • Loading branch information
hhugo authored and OlivierNicole committed Sep 3, 2024
1 parent 3146b32 commit 0ef5c70
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 28 deletions.
6 changes: 1 addition & 5 deletions compiler/lib/generate.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1585,11 +1585,7 @@ and compile_block st queue (pc : Addr.t) loop_stack frontier interm =
| true ->
if debug () then Format.eprintf "@[<hv 2>for(;;) {@,";
let never_body, body =
let lab =
match loop_stack with
| (_, (l, _)) :: _ -> J.Label.succ l
| [] -> J.Label.zero
in
let lab = J.Label.fresh () in
let lab_used = ref false in
let loop_stack = (pc, (lab, lab_used)) :: loop_stack in
let never_body, body =
Expand Down
14 changes: 2 additions & 12 deletions compiler/lib/javascript.ml
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,10 @@ end

module Label = struct
type t =
| L of int
| L of Code.Var.t
| S of Utf8_string.t

let printer = Var_printer.create Var_printer.Alphabet.javascript

let zero = L 0

let succ = function
| L t -> L (succ t)
| S _ -> assert false

let to_string = function
| L t -> Utf8_string.of_string_exn (Var_printer.to_string printer t)
| S s -> s
let fresh () = L (Code.Var.fresh ())

let of_string s = S s
end
Expand Down
10 changes: 4 additions & 6 deletions compiler/lib/javascript.mli
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,11 @@ module Num : sig
end

module Label : sig
type t

val zero : t

val succ : t -> t
type t =
| L of Code.Var.t
| S of Utf8_string.t

val to_string : t -> Utf8_string.t
val fresh : unit -> t

val of_string : Utf8_string.t -> t
end
Expand Down
52 changes: 50 additions & 2 deletions compiler/lib/js_assign.ml
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,48 @@ class traverse record_block =
super#record_block b
end

class traverse_labels h =
object
inherit Js_traverse.iter as super

val ldepth = 0

method fun_decl (_k, _params, body, _loc) =
let m = {<ldepth = 0>} in
m#function_body body

method statement =
function
| Labelled_statement (L l, (s, _)) ->
let m = {<ldepth = ldepth + 1>} in
Hashtbl.add h l ldepth;
m#statement s
| s -> super#statement s
end

class name ident label =
object (m)
inherit Js_traverse.subst ident as super

method statement =
function
| Labelled_statement (l, (s, loc)) ->
Labelled_statement (label l, (m#statement s, loc))
| Break_statement (Some l) -> Break_statement (Some (label l))
| Continue_statement (Some l) -> Continue_statement (Some (label l))
| s -> super#statement s
end

let program' (module Strategy : Strategy) p =
let nv = Var.count () in
let state = Strategy.create nv in
let labels = Hashtbl.create 20 in
let mapper = new traverse (Strategy.record_block state) in
let p = mapper#program p in
let () =
let o = new traverse_labels labels in
o#program p
in
mapper#record_block Normal;
let free =
IdentSet.filter
Expand All @@ -350,7 +387,7 @@ let program' (module Strategy : Strategy) p =
| S _ -> ()
| V x -> names.(Var.idx x) <- "")
free;
let color = function
let ident = function
| V v -> (
let name = names.(Var.idx v) in
match name, has_free_var with
Expand All @@ -359,7 +396,18 @@ let program' (module Strategy : Strategy) p =
| _, (true | false) -> ident ~var:v (Utf8_string.of_string_exn name))
| x -> x
in
let p = (new Js_traverse.subst color)#program p in
let label_printer = Var_printer.create Var_printer.Alphabet.javascript in
let max_label_depth = Hashtbl.fold (fun _ d acc -> max d acc) labels 0 in
let lname_per_depth =
Array.init (max_label_depth + 1) ~f:(fun i -> Var_printer.to_string label_printer i)
in
let label = function
| Label.S _ as l -> l
| L v ->
let i = Hashtbl.find labels v in
S (Utf8_string.of_string_exn lname_per_depth.(i))
in
let p = (new name ident label)#program p in
(if has_free_var
then
let () =
Expand Down
10 changes: 7 additions & 3 deletions compiler/lib/js_output.ml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ end) =
struct
open D

let nane_of_label = function
| Javascript.Label.L _ -> assert false
| Javascript.Label.S n -> n

let debug_enabled = Config.Flag.debuginfo ()

let output_debug_info f loc =
Expand Down Expand Up @@ -1260,15 +1264,15 @@ struct
last_semi ()
| Continue_statement (Some s) ->
PP.string f "continue ";
let (Utf8 l) = Javascript.Label.to_string s in
let (Utf8 l) = nane_of_label s in
PP.string f l;
last_semi ()
| Break_statement None ->
PP.string f "break";
last_semi ()
| Break_statement (Some s) ->
PP.string f "break ";
let (Utf8 l) = Javascript.Label.to_string s in
let (Utf8 l) = nane_of_label s in
PP.string f l;
last_semi ()
| Return_statement e -> (
Expand Down Expand Up @@ -1309,7 +1313,7 @@ struct
(* There MUST be a space between the return and its
argument. A line return will not work *))
| Labelled_statement (i, s) ->
let (Utf8 l) = Javascript.Label.to_string i in
let (Utf8 l) = nane_of_label i in
PP.string f l;
PP.string f ":";
PP.space f;
Expand Down
26 changes: 26 additions & 0 deletions compiler/lib/js_traverse.ml
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,8 @@ class rename_variable =

val decl = StringSet.empty

val labels = StringMap.empty

method private update_state scope params iter_body =
let declared_names = declared scope params iter_body in
{<subst = StringSet.fold
Expand Down Expand Up @@ -1031,6 +1033,30 @@ class rename_variable =

method statement s =
match s with
| Labelled_statement (l, (s, loc)) ->
let l, m =
match l with
| L _ -> l, m
| S (Utf8 u) ->
let l = Label.fresh () in
let m = {<labels = StringMap.add u l labels>} in
l, m
in
Labelled_statement (l, (m#statement s, loc))
| Break_statement (Some l) -> (
match l with
| L _ -> s
| S (Utf8 l) -> (
match StringMap.find_opt l labels with
| None -> s
| Some l -> Break_statement (Some l)))
| Continue_statement (Some l) -> (
match l with
| L _ -> s
| S (Utf8 l) -> (
match StringMap.find_opt l labels with
| None -> s
| Some l -> Continue_statement (Some l)))
| Function_declaration (id, (k, params, body, nid)) ->
let ids = bound_idents_of_params params in
let m' = m#update_state (Fun_block None) ids body in
Expand Down

0 comments on commit 0ef5c70

Please sign in to comment.