Skip to content

Commit 2188bb4

Browse files
committed
Compiler: minify labels
1 parent 25fbbf7 commit 2188bb4

File tree

7 files changed

+358
-297
lines changed

7 files changed

+358
-297
lines changed

compiler/lib/generate.ml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,11 +1014,6 @@ let throw_statement ctx cx k loc =
10141014
, loc )
10151015
]
10161016

1017-
let next_label scope_stack =
1018-
match scope_stack with
1019-
| (_, (l, _, _)) :: _ -> J.Label.succ l
1020-
| [] -> J.Label.zero
1021-
10221017
let rec translate_expr ctx queue loc x e level : _ * J.statement_list =
10231018
match e with
10241019
| Apply { f; args; exact } ->
@@ -1400,7 +1395,7 @@ and compile_block st queue (pc : Addr.t) scope_stack ~fall_through =
14001395
| true ->
14011396
if debug () then Format.eprintf "@[<hv 2>for(;;) {@,";
14021397
let never_body, body =
1403-
let lab = next_label scope_stack in
1398+
let lab = J.Label.fresh () in
14041399
let lab_used = ref false in
14051400
let exit_branch_used = ref false in
14061401
let scope_stack = (pc, (lab, lab_used, Loop)) :: scope_stack in
@@ -1463,7 +1458,7 @@ and compile_block_no_loop st queue (pc : Addr.t) ~fall_through scope_stack =
14631458
match l with
14641459
| [] -> compile_conditional st queue ~fall_through block.branch scope_stack
14651460
| x :: xs -> (
1466-
let l = next_label scope_stack in
1461+
let l = J.Label.fresh () in
14671462
let used = ref false in
14681463
let scope_stack = (x, (l, used, Forward)) :: scope_stack in
14691464
let _never_inner, inner = loop ~scope_stack ~fall_through:(Block x) xs in
@@ -1515,7 +1510,7 @@ and compile_decision_tree kind st scope_stack loc cx dtree ~fall_through =
15151510
let all_never = ref true in
15161511
let len = Array.length a in
15171512
let last_index = len - 1 in
1518-
let lab = next_label scope_stack in
1513+
let lab = J.Label.fresh () in
15191514
let label_used = ref false in
15201515
let exit_branch_used = ref false in
15211516
let scope_stack =

compiler/lib/javascript.ml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -143,20 +143,10 @@ end
143143

144144
module Label = struct
145145
type t =
146-
| L of int
146+
| L of Code.Var.t
147147
| S of Utf8_string.t
148148

149-
let printer = Var_printer.create Var_printer.Alphabet.javascript
150-
151-
let zero = L 0
152-
153-
let succ = function
154-
| L t -> L (succ t)
155-
| S _ -> assert false
156-
157-
let to_string = function
158-
| L t -> Utf8_string.of_string_exn (Var_printer.to_string printer t)
159-
| S s -> s
149+
let fresh () = L (Code.Var.fresh ())
160150

161151
let of_string s = S s
162152
end

compiler/lib/javascript.mli

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,11 @@ module Num : sig
5151
end
5252

5353
module Label : sig
54-
type t
55-
56-
val zero : t
57-
58-
val succ : t -> t
54+
type t =
55+
| L of Code.Var.t
56+
| S of Utf8_string.t
5957

60-
val to_string : t -> Utf8_string.t
58+
val fresh : unit -> t
6159

6260
val of_string : Utf8_string.t -> t
6361
end

compiler/lib/js_assign.ml

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,48 @@ class traverse record_block =
329329
super#record_block b
330330
end
331331

332+
class traverse_labels h =
333+
object
334+
inherit Js_traverse.iter as super
335+
336+
val ldepth = 0
337+
338+
method fun_decl (_k, _params, body, _loc) =
339+
let m = {<ldepth = 0>} in
340+
m#function_body body
341+
342+
method statement =
343+
function
344+
| Labelled_statement (L l, (s, _)) ->
345+
let m = {<ldepth = ldepth + 1>} in
346+
Hashtbl.add h l ldepth;
347+
m#statement s
348+
| s -> super#statement s
349+
end
350+
351+
class name ident label =
352+
object (m)
353+
inherit Js_traverse.subst ident as super
354+
355+
method statement =
356+
function
357+
| Labelled_statement (l, (s, loc)) ->
358+
Labelled_statement (label l, (m#statement s, loc))
359+
| Break_statement (Some l) -> Break_statement (Some (label l))
360+
| Continue_statement (Some l) -> Continue_statement (Some (label l))
361+
| s -> super#statement s
362+
end
363+
332364
let program' (module Strategy : Strategy) p =
333365
let nv = Var.count () in
334366
let state = Strategy.create nv in
367+
let labels = Hashtbl.create 20 in
335368
let mapper = new traverse (Strategy.record_block state) in
336369
let p = mapper#program p in
370+
let () =
371+
let o = new traverse_labels labels in
372+
o#program p
373+
in
337374
mapper#record_block Normal;
338375
let free =
339376
IdentSet.filter
@@ -350,7 +387,7 @@ let program' (module Strategy : Strategy) p =
350387
| S _ -> ()
351388
| V x -> names.(Var.idx x) <- "")
352389
free;
353-
let color = function
390+
let ident = function
354391
| V v -> (
355392
let name = names.(Var.idx v) in
356393
match name, has_free_var with
@@ -359,7 +396,18 @@ let program' (module Strategy : Strategy) p =
359396
| _, (true | false) -> ident ~var:v (Utf8_string.of_string_exn name))
360397
| x -> x
361398
in
362-
let p = (new Js_traverse.subst color)#program p in
399+
let label_printer = Var_printer.create Var_printer.Alphabet.javascript in
400+
let max_label_depth = Hashtbl.fold (fun _ d acc -> max d acc) labels 0 in
401+
let lname_per_depth =
402+
Array.init (max_label_depth + 1) ~f:(fun i -> Var_printer.to_string label_printer i)
403+
in
404+
let label = function
405+
| Label.S _ as l -> l
406+
| L v ->
407+
let i = Hashtbl.find labels v in
408+
S (Utf8_string.of_string_exn lname_per_depth.(i))
409+
in
410+
let p = (new name ident label)#program p in
363411
(if has_free_var
364412
then
365413
let () =

compiler/lib/js_output.ml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ end) =
6060
struct
6161
open D
6262

63+
let nane_of_label = function
64+
| Javascript.Label.L _ -> assert false
65+
| Javascript.Label.S n -> n
66+
6367
let debug_enabled = Config.Flag.debuginfo ()
6468

6569
let output_debug_info f loc =
@@ -1260,15 +1264,15 @@ struct
12601264
last_semi ()
12611265
| Continue_statement (Some s) ->
12621266
PP.string f "continue ";
1263-
let (Utf8 l) = Javascript.Label.to_string s in
1267+
let (Utf8 l) = nane_of_label s in
12641268
PP.string f l;
12651269
last_semi ()
12661270
| Break_statement None ->
12671271
PP.string f "break";
12681272
last_semi ()
12691273
| Break_statement (Some s) ->
12701274
PP.string f "break ";
1271-
let (Utf8 l) = Javascript.Label.to_string s in
1275+
let (Utf8 l) = nane_of_label s in
12721276
PP.string f l;
12731277
last_semi ()
12741278
| Return_statement e -> (
@@ -1309,7 +1313,7 @@ struct
13091313
(* There MUST be a space between the return and its
13101314
argument. A line return will not work *))
13111315
| Labelled_statement (i, s) ->
1312-
let (Utf8 l) = Javascript.Label.to_string i in
1316+
let (Utf8 l) = nane_of_label i in
13131317
PP.string f l;
13141318
PP.string f ":";
13151319
PP.space f;

compiler/lib/js_traverse.ml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,8 @@ class rename_variable =
976976

977977
val decl = StringSet.empty
978978

979+
val labels = StringMap.empty
980+
979981
method private update_state scope params iter_body =
980982
let declared_names = declared scope params iter_body in
981983
{<subst = StringSet.fold
@@ -1011,6 +1013,30 @@ class rename_variable =
10111013

10121014
method statement s =
10131015
match s with
1016+
| Labelled_statement (l, (s, loc)) ->
1017+
let l, m =
1018+
match l with
1019+
| L _ -> l, m
1020+
| S (Utf8 u) ->
1021+
let l = Label.fresh () in
1022+
let m = {<labels = StringMap.add u l labels>} in
1023+
l, m
1024+
in
1025+
Labelled_statement (l, (m#statement s, loc))
1026+
| Break_statement (Some l) -> (
1027+
match l with
1028+
| L _ -> s
1029+
| S (Utf8 l) -> (
1030+
match StringMap.find_opt l labels with
1031+
| None -> s
1032+
| Some l -> Break_statement (Some l)))
1033+
| Continue_statement (Some l) -> (
1034+
match l with
1035+
| L _ -> s
1036+
| S (Utf8 l) -> (
1037+
match StringMap.find_opt l labels with
1038+
| None -> s
1039+
| Some l -> Continue_statement (Some l)))
10141040
| Function_declaration (id, (k, params, body, nid)) ->
10151041
let ids = bound_idents_of_params params in
10161042
let m' = m#update_state (Fun_block None) ids body in

0 commit comments

Comments
 (0)