Skip to content

Commit f4a03b9

Browse files
committed
finally fix #2413
1 parent cbeaced commit f4a03b9

22 files changed

+124
-432
lines changed

jscomp/core/lam_compile.ml

+21-11
Original file line numberDiff line numberDiff line change
@@ -488,21 +488,31 @@ and compile_general_cases
488488
(fun group ->
489489
Ext_list.map_last
490490
(fun last (switch_case,lam) ->
491-
(* let switch_block, should_break =
492-
Js_output.to_break_block (compile_lambda cxt lam) in
493-
let should_break =
494-
match cxt.should_return with
495-
| ReturnFalse -> should_break
496-
| ReturnTrue _ -> false
497-
in *)
498-
499491
if last
500492
then
501493
(* merge and shared *)
502-
let switch_body = Js_output.to_break_block (compile_lambda cxt lam) in
494+
let switch_block, should_break =
495+
Js_output.to_break_block (compile_lambda cxt lam)
496+
in
497+
let should_break =
498+
match cxt.should_return with
499+
| ReturnFalse -> should_break
500+
| ReturnTrue _ ->
501+
(** see #2413
502+
In general, we know it is last call,
503+
there is no need to print [break];
504+
there is an exception when two conditions meet:
505+
- should_break does not imply
506+
There is one case (tailcall)
507+
where [should_break] inferred false while our
508+
exit engine could not infer
509+
- has_exit
510+
*)
511+
should_break && (Lam_exit_code.has_exit lam)
512+
in
503513
{J.switch_case ;
504-
switch_body
505-
}
514+
switch_body = switch_block, should_break
515+
}
506516
else
507517
{ switch_case; switch_body = [],false }
508518
)

jscomp/core/lam_exit_code.ml

+34-30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
2-
*
2+
*
33
* This program is free software: you can redistribute it and/or modify
44
* it under the terms of the GNU Lesser General Public License as published by
55
* the Free Software Foundation, either version 3 of the License, or
@@ -17,7 +17,7 @@
1717
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1818
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1919
* GNU Lesser General Public License for more details.
20-
*
20+
*
2121
* You should have received a copy of the GNU Lesser General Public License
2222
* along with this program; if not, write to the Free Software
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
@@ -27,71 +27,75 @@
2727

2828

2929

30-
let rec has_exit_code exits (lam : Lam.t) : bool =
30+
let rec has_exit_code exits (lam : Lam.t) : bool =
3131
match lam with
3232
| Lvar _
33-
| Lconst _
33+
| Lconst _
3434
| Lfunction _ (* static exit can not across function boundary *)
3535
-> false
36-
| Lapply {fn = l; args; _ }
37-
-> has_exit_code exits l || List.exists (fun x -> has_exit_code exits x ) args
36+
| Lapply {fn = l; args; _ }
37+
-> has_exit_code exits l || List.exists (fun x -> has_exit_code exits x ) args
3838

39-
| Llet (_kind,_id,v,body)
39+
| Llet (_kind,_id,v,body)
4040
-> has_exit_code exits v || has_exit_code exits body
4141
| Lletrec (binding,body) ->
4242
List.exists (fun (_, l) -> has_exit_code exits l ) binding ||
43-
has_exit_code exits body
43+
has_exit_code exits body
4444
| Lam.Lglobal_module _ -> false
45-
| Lprim {args; _}
45+
| Lprim {args; _}
4646
-> List.exists (fun x -> has_exit_code exits x) args
47-
| Lswitch (l,lam_switch)
47+
| Lswitch (l,lam_switch)
4848
-> has_exit_code exits l || has_exit_code_lam_switch exits lam_switch
4949

50-
| Lstringswitch (l,ls,opt) ->
50+
| Lstringswitch (l,ls,opt) ->
5151
has_exit_code exits l ||
5252
List.exists (fun (_,l) -> has_exit_code exits l) ls ||
53-
(match opt with
53+
(match opt with
5454
| None -> false
5555
| Some x -> has_exit_code exits l )
5656
| Lstaticraise (v,ls) ->
57-
exits v ||
57+
exits v ||
5858
List.exists (has_exit_code exits) ls
59-
| Lstaticcatch (l,_,handler)
59+
| Lstaticcatch (l,_,handler)
6060
->
6161
has_exit_code exits l || has_exit_code exits handler
62-
| Ltrywith (l,_, handler)
62+
| Ltrywith (l,_, handler)
6363
->
6464
has_exit_code exits l || has_exit_code exits handler
65-
| Lifthenelse (a,b,c)
66-
->
65+
| Lifthenelse (a,b,c)
66+
->
6767
has_exit_code exits a || has_exit_code exits b || has_exit_code exits c
68-
| Lsequence (a,b)
68+
| Lsequence (a,b)
6969
->
7070
has_exit_code exits a || has_exit_code exits b
71-
| Lwhile (a,b)
71+
| Lwhile (a,b)
7272
->
7373
has_exit_code exits a || has_exit_code exits b
74-
| Lfor (_,a,b,_dir,body) ->
75-
has_exit_code exits a
74+
| Lfor (_,a,b,_dir,body) ->
75+
has_exit_code exits a
7676
|| has_exit_code exits b
7777
|| has_exit_code exits body
78-
79-
| Lassign (_,a)
80-
->
78+
79+
| Lassign (_,a)
80+
->
8181
has_exit_code exits a
82-
| Lsend (_,obj,l,ls,_loc)
83-
->
82+
| Lsend (_,obj,l,ls,_loc)
83+
->
8484
has_exit_code exits obj ||
8585
has_exit_code exits l ||
8686
List.exists (has_exit_code exits) ls
87-
| Lifused (_,b)
87+
| Lifused (_,b)
8888
-> has_exit_code exits b
8989

90-
and has_exit_code_lam_switch exits (lam_switch : Lam.switch) =
90+
and has_exit_code_lam_switch exits (lam_switch : Lam.switch) =
9191
match lam_switch with
9292
| { sw_numconsts = _; sw_consts; sw_numblocks = _ ; sw_blocks; sw_failaction } ->
9393
List.exists (fun (_,l) -> has_exit_code exits l) sw_consts ||
9494
List.exists (fun (_,l) -> has_exit_code exits l) sw_blocks ||
95-
(match sw_failaction with
96-
| None -> false
95+
(match sw_failaction with
96+
| None -> false
9797
| Some x -> has_exit_code exits x)
98+
99+
100+
let has_exit lam =
101+
has_exit_code (fun _ -> true) lam

jscomp/core/lam_exit_code.mli

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(* Copyright (C) 2015-2016 Bloomberg Finance L.P.
2-
*
2+
*
33
* This program is free software: you can redistribute it and/or modify
44
* it under the terms of the GNU Lesser General Public License as published by
55
* the Free Software Foundation, either version 3 of the License, or
@@ -17,7 +17,7 @@
1717
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1818
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1919
* GNU Lesser General Public License for more details.
20-
*
20+
*
2121
* You should have received a copy of the GNU Lesser General Public License
2222
* along with this program; if not, write to the Free Software
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
@@ -28,4 +28,7 @@
2828

2929

3030

31-
val has_exit_code : (int -> bool ) -> Lam.t -> bool
31+
val has_exit_code : (int -> bool ) -> Lam.t -> bool
32+
33+
34+
val has_exit : Lam.t -> bool

jscomp/test/flow_parser_reg_test.js

-11
Original file line numberDiff line numberDiff line change
@@ -1837,7 +1837,6 @@ function token(env, lexbuf) {
18371837
var env$6 = save_comment(match$1[0], start$1, match$1[1], buf$1, /* true */1);
18381838
return token(env$6, lexbuf$1);
18391839
}
1840-
break;
18411840
case 5 :
18421841
if (env$1[/* lex_in_comment_syntax */2]) {
18431842
var env$7 = in_comment_syntax(/* false */0, env$1);
@@ -1849,7 +1848,6 @@ function token(env, lexbuf) {
18491848
/* T_MULT */97
18501849
];
18511850
}
1852-
break;
18531851
case 6 :
18541852
var start$2 = loc_of_lexbuf(env$1, lexbuf$1);
18551853
var buf$2 = Buffer.create(127);
@@ -1866,7 +1864,6 @@ function token(env, lexbuf) {
18661864
/* T_ERROR */104
18671865
];
18681866
}
1869-
break;
18701867
case 8 :
18711868
var quote = Caml_bytes.get(lexbuf$1[/* lex_buffer */1], lexbuf$1[/* lex_start_pos */4]);
18721869
var start$3 = loc_of_lexbuf(env$1, lexbuf$1);
@@ -1957,7 +1954,6 @@ function token(env, lexbuf) {
19571954
throw exn;
19581955
}
19591956
}
1960-
break;
19611957
case 23 :
19621958
return /* tuple */[
19631959
env$1,
@@ -3792,7 +3788,6 @@ function type_token(env, lexbuf) {
37923788
var env$5 = save_comment(match$1[0], start$1, match$1[1], buf$1, /* true */1);
37933789
return type_token(env$5, lexbuf$1);
37943790
}
3795-
break;
37963791
case 4 :
37973792
if (env$1[/* lex_in_comment_syntax */2]) {
37983793
var env$6 = in_comment_syntax(/* false */0, env$1);
@@ -3804,7 +3799,6 @@ function type_token(env, lexbuf) {
38043799
/* T_MULT */97
38053800
];
38063801
}
3807-
break;
38083802
case 5 :
38093803
var start$2 = loc_of_lexbuf(env$1, lexbuf$1);
38103804
var buf$2 = Buffer.create(127);
@@ -3914,7 +3908,6 @@ function type_token(env, lexbuf) {
39143908
throw exn$1;
39153909
}
39163910
}
3917-
break;
39183911
case 15 :
39193912
var neg$8 = Lexing.sub_lexeme(lexbuf$1, lexbuf$1[/* lex_start_pos */4], Caml_array.caml_array_get(lexbuf$1[/* lex_mem */9], 0));
39203913
var num$8 = Lexing.sub_lexeme(lexbuf$1, Caml_array.caml_array_get(lexbuf$1[/* lex_mem */9], 0), Caml_array.caml_array_get(lexbuf$1[/* lex_mem */9], 1));
@@ -3958,7 +3951,6 @@ function type_token(env, lexbuf) {
39583951
throw exn$2;
39593952
}
39603953
}
3961-
break;
39623954
case 22 :
39633955
return /* tuple */[
39643956
env$1,
@@ -7575,7 +7567,6 @@ function call(env, _left) {
75757567
continue ;
75767568

75777569
}
7578-
break;
75797570
case 5 :
75807571
token$4(env, /* T_LBRACKET */5);
75817572
var expr = Curry._1(Parse[/* expression */6], env);
@@ -8036,7 +8027,6 @@ function primary$1(env) {
80368027
]])
80378028
];
80388029
}
8039-
break;
80408030
case 2 :
80418031
var raw$4 = Curry._2(Parser_env_048[/* value */1], /* None */0, env);
80428032
token$4(env, token$5);
@@ -14087,7 +14077,6 @@ function parse(content, _) {
1408714077
]
1408814078
]);
1408914079
}
14090-
break;
1409114080
case 6 :
1409214081
var binary = match[0];
1409314082
var match$4 = binary[/* operator */0];

jscomp/test/gpr_1698_test.js

-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ function is_number(_expr) {
1313
} else {
1414
return /* true */1;
1515
}
16-
break;
1716
case 1 :
1817
_expr = expr[0];
1918
continue ;
@@ -167,7 +166,6 @@ function compare(context, state, _a, _b) {
167166
default:
168167
return -1;
169168
}
170-
break;
171169
case 2 :
172170
var denom = compare(context, state, da, db);
173171
var match = +(denom === 0);
@@ -179,7 +177,6 @@ function compare(context, state, _a, _b) {
179177
} else {
180178
return denom;
181179
}
182-
break;
183180

184181
}
185182
};

jscomp/test/gpr_2413_test.js

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ function f(param) {
1414
var a$1 = match[0];
1515
return a$1 + a$1 | 0;
1616
}
17-
break;
1817
case 1 :
1918
case 2 :
2019
exit = 1;

jscomp/test/js_json_test.js

-5
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ function eq_at_i(loc, json, i, kind, expected) {
289289
} else {
290290
return eq(loc, ty$1[0], expected);
291291
}
292-
break;
293292
case 1 :
294293
if (typeof ty$1 === "number") {
295294
return add_test(loc, (function () {
@@ -302,7 +301,6 @@ function eq_at_i(loc, json, i, kind, expected) {
302301
return /* Ok */Block.__(4, [/* false */0]);
303302
}));
304303
}
305-
break;
306304
case 2 :
307305
if (typeof ty$1 === "number") {
308306
return add_test(loc, (function () {
@@ -315,7 +313,6 @@ function eq_at_i(loc, json, i, kind, expected) {
315313
return /* Ok */Block.__(4, [/* false */0]);
316314
}));
317315
}
318-
break;
319316
case 3 :
320317
if (typeof ty$1 === "number") {
321318
return add_test(loc, (function () {
@@ -328,7 +325,6 @@ function eq_at_i(loc, json, i, kind, expected) {
328325
return /* Ok */Block.__(4, [/* false */0]);
329326
}));
330327
}
331-
break;
332328
case 4 :
333329
if (typeof ty$1 === "number") {
334330
switch (ty$1) {
@@ -347,7 +343,6 @@ function eq_at_i(loc, json, i, kind, expected) {
347343
return /* Ok */Block.__(4, [/* false */0]);
348344
}));
349345
}
350-
break;
351346
case 5 :
352347
if (typeof ty$1 === "number") {
353348
if (ty$1 >= 2) {

jscomp/test/mario_game.js

-5
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,6 @@ function update_player(player, keys, context) {
968968
player$1[/* dir */6] = /* Left */0;
969969
return /* () */0;
970970
}
971-
break;
972971
case 1 :
973972
if (player$1[/* crouch */10]) {
974973
return 0;
@@ -979,7 +978,6 @@ function update_player(player, keys, context) {
979978
player$1[/* dir */6] = /* Right */1;
980979
return /* () */0;
981980
}
982-
break;
983981
case 2 :
984982
if (!player$1[/* jumping */4] && player$1[/* grounded */5]) {
985983
player$1[/* jumping */4] = /* true */1;
@@ -1401,7 +1399,6 @@ function kill(collid, ctx) {
14011399
} else {
14021400
return /* [] */0;
14031401
}
1404-
break;
14051402

14061403
}
14071404
}
@@ -1886,7 +1883,6 @@ function process_collision(dir, c1, c2, state) {
18861883
/* None */0
18871884
];
18881885
}
1889-
break;
18901886

18911887
}
18921888
break;
@@ -2021,7 +2017,6 @@ function process_collision(dir, c1, c2, state) {
20212017
/* None */0
20222018
];
20232019
}
2024-
break;
20252020

20262021
}
20272022
}

0 commit comments

Comments
 (0)