Skip to content

Commit f1f0d24

Browse files
committed
Add location after return statement
1 parent 3698fe4 commit f1f0d24

File tree

17 files changed

+3771
-3293
lines changed

17 files changed

+3771
-3293
lines changed

compiler/bin-wasm_of_ocaml/compile.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ let build_js_runtime ~primitives ?runtime_arguments () =
193193
List.split_last
194194
@@ Driver.link_and_pack
195195
~link:`Needed
196-
[ Javascript.Return_statement (Some (EObj l)), N ]
196+
[ Javascript.Return_statement (Some (EObj l), N), N ]
197197
with
198198
| Some x -> x
199199
| None -> assert false

compiler/lib/generate.ml

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ type state =
561561
; dom : Structure.graph
562562
; visited_blocks : Addr.Set.t ref
563563
; ctx : Ctx.t
564+
; pc : Addr.t
564565
}
565566

566567
module DTree = struct
@@ -681,7 +682,7 @@ let build_graph ctx pc =
681682
let visited_blocks = ref Addr.Set.empty in
682683
let structure = Structure.build_graph ctx.Ctx.blocks pc in
683684
let dom = Structure.dominator_tree structure in
684-
{ visited_blocks; structure; dom; ctx }
685+
{ visited_blocks; structure; dom; ctx; pc }
685686

686687
(****)
687688

@@ -835,7 +836,8 @@ let generate_apply_fun ctx { arity; exact; trampolined } =
835836
( None
836837
, J.fun_
837838
(f :: params)
838-
[ J.Return_statement (Some (apply_fun_raw ctx f' params' exact trampolined)), J.N
839+
[ ( J.Return_statement (Some (apply_fun_raw ctx f' params' exact trampolined), J.N)
840+
, J.N )
839841
]
840842
J.N )
841843

@@ -1282,7 +1284,7 @@ let rec translate_expr ctx queue loc x e level : _ * J.statement_list =
12821284
loc
12831285
in
12841286
let e =
1285-
J.EFun (Some f, J.fun_ args [ J.Return_statement (Some call), J.N ] J.N)
1287+
J.EFun (Some f, J.fun_ args [ J.Return_statement (Some call, J.N), J.N ] J.N)
12861288
in
12871289
e, const_p, queue
12881290
| Extern "caml_alloc_dummy_function", _ -> assert false
@@ -1675,6 +1677,8 @@ and compile_decision_tree kind st scope_stack loc cx dtree ~fall_through =
16751677
in
16761678
( never1 && never2
16771679
, Js_simpl.if_statement
1680+
~function_end:(fun () ->
1681+
source_location_ctx st.ctx ~force:After (After st.pc))
16781682
e'
16791683
loc
16801684
(Js_simpl.block iftrue)
@@ -1758,15 +1762,25 @@ and compile_conditional st queue ~fall_through last scope_stack : _ * _ =
17581762
let return_expr =
17591763
if Var.equal st.ctx.deadcode_sentinal x then None else Some cx
17601764
in
1761-
true, flush_all queue [ J.Return_statement return_expr, loc ]
1765+
let loc' =
1766+
match cx with
1767+
| ECall _ -> (
1768+
(* We usually don't have a good locations for tail
1769+
calls, so use the end of the function instead *)
1770+
match source_location_ctx st.ctx ~force:After (After st.pc) with
1771+
| J.N -> loc
1772+
| loc -> loc)
1773+
| _ -> loc
1774+
in
1775+
true, flush_all queue [ J.Return_statement (return_expr, loc'), loc ]
17621776
| Raise (x, k) ->
17631777
let (_px, cx), queue = access_queue queue x in
17641778
true, flush_all queue (throw_statement st.ctx cx k loc)
17651779
| Stop ->
17661780
let e_opt =
17671781
if st.ctx.Ctx.should_export then Some (s_var Global_constant.exports) else None
17681782
in
1769-
true, flush_all queue [ J.Return_statement e_opt, loc ]
1783+
true, flush_all queue [ J.Return_statement (e_opt, loc), loc ]
17701784
| Branch cont -> compile_branch st queue cont scope_stack ~fall_through
17711785
| Pushtrap (c1, x, e1) ->
17721786
let never_body, body = compile_branch st [] c1 scope_stack ~fall_through in

compiler/lib/javascript.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ and statement =
347347
* (statement * location)
348348
| Continue_statement of Label.t option
349349
| Break_statement of Label.t option
350-
| Return_statement of expression option
350+
| Return_statement of expression option * location
351351
| With_statement of expression * (statement * location)
352352
| Labelled_statement of Label.t * (statement * location)
353353
| Switch_statement of

compiler/lib/javascript.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ and statement =
265265
* (statement * location)
266266
| Continue_statement of Label.t option
267267
| Break_statement of Label.t option
268-
| Return_statement of expression option
268+
| Return_statement of expression option * location
269269
| With_statement of expression * (statement * location)
270270
| Labelled_statement of Label.t * (statement * location)
271271
| Switch_statement of

compiler/lib/js_output.ml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,13 +509,14 @@ struct
509509
PP.end_group f);
510510
PP.end_group f;
511511
(match b, consise with
512-
| [ (Return_statement (Some e), loc) ], true ->
512+
| [ (Return_statement (Some e, loc), loc') ], true ->
513513
(* Should not starts with '{' *)
514514
PP.start_group f 1;
515515
PP.break1 f;
516-
output_debug_info f loc;
516+
output_debug_info f loc';
517517
parenthesized_expression ~obj:true AssignementExpression f e;
518-
PP.end_group f
518+
PP.end_group f;
519+
output_debug_info f loc
519520
| l, _ ->
520521
let b =
521522
match l with
@@ -1466,10 +1467,11 @@ struct
14661467
let (Utf8 l) = nane_of_label s in
14671468
PP.string f l;
14681469
last_semi ()
1469-
| Return_statement e -> (
1470+
| Return_statement (e, loc) -> (
14701471
match e with
14711472
| None ->
14721473
PP.string f "return";
1474+
output_debug_info f loc;
14731475
last_semi ()
14741476
| Some (EFun (i, ({ async = false; generator = false }, l, b, pc))) ->
14751477
PP.start_group f 1;
@@ -1490,6 +1492,7 @@ struct
14901492
function_body f b;
14911493
output_debug_info f pc;
14921494
PP.string f "}";
1495+
output_debug_info f loc;
14931496
last_semi ();
14941497
PP.end_group f
14951498
| Some e ->
@@ -1498,6 +1501,7 @@ struct
14981501
PP.non_breaking_space f;
14991502
PP.start_group f 0;
15001503
expression Expression f e;
1504+
output_debug_info f loc;
15011505
last_semi ();
15021506
PP.end_group f;
15031507
PP.end_group f

compiler/lib/js_parser.mly

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ break_stmt:
736736
| T_BREAK l=label? sc { (Break_statement (l)) }
737737

738738
return_stmt:
739-
| T_RETURN e=expr? sc { (Return_statement e) }
739+
| T_RETURN e=expr? sc { (Return_statement (e, p $endpos(e))) }
740740

741741
switch_stmt:
742742
| T_SWITCH "(" subject=expr ")" cb=case_block
@@ -1100,7 +1100,7 @@ async_arrow_function:
11001100
(* was called consise body in spec *)
11011101
arrow_body:
11021102
| "{" b=function_body "}" { b, false }
1103-
| e=assignment_expr_for_consise_body { [(Return_statement (Some e), p $symbolstartpos)], true }
1103+
| e=assignment_expr_for_consise_body { [(Return_statement (Some e, p $endpos), p $symbolstartpos)], true }
11041104

11051105
(*----------------------------*)
11061106
(* no in *)

compiler/lib/js_simpl.ml

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,13 @@ exception Not_expression
110110

111111
let rec expression_of_statement_list l =
112112
match l with
113-
| (J.Return_statement (Some e), _) :: _ -> e
113+
| (J.Return_statement (Some e, _), _) :: _ -> e
114114
| (J.Expression_statement e, _) :: rem -> J.ESeq (e, expression_of_statement_list rem)
115115
| _ -> raise Not_expression
116116

117117
let expression_of_statement st =
118118
match fst st with
119-
| J.Return_statement (Some e) -> e
119+
| J.Return_statement (Some e, _) -> e
120120
| J.Block l -> expression_of_statement_list l
121121
| _ -> raise Not_expression
122122

@@ -194,15 +194,16 @@ and depth_class_block b =
194194
| J.CEField _ -> acc
195195
| J.CEStaticBLock b -> depth_block b + 2)
196196

197-
let rec if_statement_2 e loc iftrue truestop iffalse falsestop =
197+
let rec if_statement_2 ~function_end e loc iftrue truestop iffalse falsestop =
198198
let e = simplify_condition e in
199199
match fst iftrue, fst iffalse with
200200
(* Empty blocks *)
201201
| J.Block [], J.Block [] -> (
202202
match e with
203203
| J.EVar _ -> []
204204
| _ -> [ J.Expression_statement e, loc ])
205-
| J.Block [], _ -> if_statement_2 (enot e) loc iffalse falsestop iftrue truestop
205+
| J.Block [], _ ->
206+
if_statement_2 ~function_end (enot e) loc iffalse falsestop iftrue truestop
206207
| _, J.Block [] -> [ J.If_statement (e, iftrue, None), loc ]
207208
| _ -> (
208209
try
@@ -226,7 +227,7 @@ let rec if_statement_2 e loc iftrue truestop iffalse falsestop =
226227
try
227228
let e1 = expression_of_statement iftrue in
228229
let e2 = expression_of_statement iffalse in
229-
[ J.Return_statement (Some (J.ECond (e, e1, e2))), loc ]
230+
[ J.Return_statement (Some (J.ECond (e, e1, e2)), function_end ()), loc ]
230231
with Not_expression ->
231232
let truestop, falsestop =
232233
if truestop && falsestop
@@ -247,32 +248,48 @@ let unopt b =
247248
| Some b -> b
248249
| None -> J.Block [], J.N
249250

250-
let if_statement e loc iftrue truestop iffalse falsestop =
251+
let if_statement ~function_end e loc iftrue truestop iffalse falsestop =
251252
(*FIX: should be done at an earlier stage*)
252253
let e = simplify_condition e in
253254
match iftrue, iffalse with
254255
(* Shared statements *)
255256
| (J.If_statement (e', iftrue', iffalse'), _), _ when Poly.(iffalse = unopt iffalse') ->
256-
if_statement_2 (J.EBin (J.And, e, e')) loc iftrue' truestop iffalse falsestop
257+
if_statement_2
258+
~function_end
259+
(J.EBin (J.And, e, e'))
260+
loc
261+
iftrue'
262+
truestop
263+
iffalse
264+
falsestop
257265
| (J.If_statement (e', iftrue', iffalse'), _), _ when Poly.(iffalse = iftrue') ->
258266
if_statement_2
267+
~function_end
259268
(J.EBin (J.And, e, J.EUn (J.Not, e')))
260269
loc
261270
(unopt iffalse')
262271
truestop
263272
iffalse
264273
falsestop
265274
| _, (J.If_statement (e', iftrue', iffalse'), _) when Poly.(iftrue = iftrue') ->
266-
if_statement_2 (J.EBin (J.Or, e, e')) loc iftrue truestop (unopt iffalse') falsestop
275+
if_statement_2
276+
~function_end
277+
(J.EBin (J.Or, e, e'))
278+
loc
279+
iftrue
280+
truestop
281+
(unopt iffalse')
282+
falsestop
267283
| _, (J.If_statement (e', iftrue', iffalse'), _) when Poly.(iftrue = unopt iffalse') ->
268284
if_statement_2
285+
~function_end
269286
(J.EBin (J.Or, e, J.EUn (J.Not, e')))
270287
loc
271288
iftrue
272289
truestop
273290
iftrue'
274291
falsestop
275-
| _ -> if_statement_2 e loc iftrue truestop iffalse falsestop
292+
| _ -> if_statement_2 ~function_end e loc iftrue truestop iffalse falsestop
276293

277294
let function_body b =
278295
(* We only check for a return at the end since it is by far the most
@@ -281,7 +298,7 @@ let function_body b =
281298
let rec check l =
282299
match l with
283300
| [] -> false
284-
| [ (J.Return_statement None, _) ] -> true
301+
| [ (J.Return_statement (None, _), _) ] -> true
285302
| _ :: r -> check r
286303
in
287304
check b
@@ -291,7 +308,7 @@ let function_body b =
291308
let rec remove acc l =
292309
match l with
293310
| [] -> acc
294-
| [ (J.Return_statement None, _) ] -> acc
311+
| [ (J.Return_statement (None, _), _) ] -> acc
295312
| i :: r -> remove (i :: acc) r
296313
in
297314
List.rev (remove [] b)

compiler/lib/js_simpl.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
open Javascript
2222

2323
val if_statement :
24-
expression
24+
function_end:(unit -> location)
25+
-> expression
2526
-> location
2627
-> statement * location
2728
-> bool

compiler/lib/js_traverse.ml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ class map : mapper =
187187
ForAwaitOf_statement (e1, m#expression e2, (m#statement s, m#loc loc))
188188
| Continue_statement s -> Continue_statement s
189189
| Break_statement s -> Break_statement s
190-
| Return_statement e -> Return_statement (m#expression_o e)
190+
| Return_statement (e, loc) -> Return_statement (m#expression_o e, m#loc loc)
191191
| Labelled_statement (l, (s, loc)) ->
192192
Labelled_statement (l, (m#statement s, m#loc loc))
193193
| Throw_statement e -> Throw_statement (m#expression e)
@@ -549,7 +549,7 @@ class iter : iterator =
549549
m#statement s
550550
| Continue_statement _ -> ()
551551
| Break_statement _ -> ()
552-
| Return_statement e -> m#expression_o e
552+
| Return_statement (e, _) -> m#expression_o e
553553
| Labelled_statement (_, (s, _)) -> m#statement s
554554
| Throw_statement e -> m#expression e
555555
| Switch_statement (e, l, def, l') ->
@@ -1750,8 +1750,16 @@ class simpl =
17501750
| If_statement (ENum n, _, iffalse) when Num.is_zero n -> opt_cons iffalse rem
17511751
(* if (e1) return e2 else return e3 --> return e1 ? e2 : e3 *)
17521752
| If_statement
1753-
(cond, (Return_statement (Some e1), _), Some (Return_statement (Some e2), _))
1754-
-> (Return_statement (Some (ECond (cond, e1, e2))), loc) :: rem
1753+
( cond
1754+
, (Return_statement (Some e1, _), _)
1755+
, Some (Return_statement (Some e2, _), _) ) ->
1756+
( Return_statement
1757+
( Some (ECond (cond, e1, e2))
1758+
, U
1759+
(*TODO: it would be better to use the location of the
1760+
end of the function, but we can't easily get it. *) )
1761+
, loc )
1762+
:: rem
17551763
(* if (e1) v1 = e2 else v1 = e3 --> v1 = e1 ? e2 : e3 *)
17561764
| If_statement
17571765
( cond

0 commit comments

Comments
 (0)