Skip to content

Commit 4ac368a

Browse files
committed
Implement try..finally syntax
1 parent a631b38 commit 4ac368a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1264
-167
lines changed

analysis/reanalyze/src/Arnold.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -967,11 +967,12 @@ module Compile = struct
967967
| Texp_tuple expressions | Texp_array expressions ->
968968
expressions |> List.map (expression ~ctx) |> Command.unorderedSequence
969969
| Texp_assert _ -> Command.nothing
970-
| Texp_try (e, cases) ->
970+
| Texp_try (e, cases, finally_expr) ->
971971
let cE = e |> expression ~ctx in
972972
let cCases = cases |> List.map (case ~ctx) |> Command.nondet in
973+
let cFinally = finally_expr |> expressionOpt ~ctx in
973974
let open Command in
974-
cE +++ cCases
975+
cE +++ cCases +++ cFinally
975976
| Texp_variant (_label, eOpt) -> eOpt |> expressionOpt ~ctx
976977
| Texp_while _ ->
977978
notImplemented "Texp_while";

analysis/reanalyze/src/Exception.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ let traverseAst () =
335335
kind = Raises;
336336
}
337337
:: !currentEvents
338-
| Texp_try (e, cases) ->
338+
| Texp_try (e, cases, finally_expr) ->
339339
let exceptions =
340340
cases
341341
|> List.map (fun case -> case.Typedtree.c_lhs.pat_desc)
@@ -346,7 +346,8 @@ let traverseAst () =
346346
e |> iterExpr self;
347347
currentEvents :=
348348
{Event.exceptions; loc; kind = Catches !currentEvents} :: oldEvents;
349-
cases |> iterCases self
349+
cases |> iterCases self;
350+
finally_expr |> iterExprOpt self
350351
| _ -> super.expr self expr |> ignore);
351352
(if isDoesNoRaise then
352353
let nestedEvents = !currentEvents in

analysis/reanalyze/src/SideEffects.ml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ let rec exprNoSideEffects (expr : Typedtree.expression) =
4545
partial = Total && e |> exprNoSideEffects
4646
&& cases |> List.for_all caseNoSideEffects
4747
| Texp_letmodule _ -> false
48-
| Texp_try (e, cases) ->
49-
e |> exprNoSideEffects && cases |> List.for_all caseNoSideEffects
48+
| Texp_try (e, cases, finally_expr) ->
49+
e |> exprNoSideEffects
50+
&& cases |> List.for_all caseNoSideEffects
51+
&& finally_expr |> exprOptNoSideEffects
5052
| Texp_tuple el -> el |> List.for_all exprNoSideEffects
5153
| Texp_variant (_lbl, eo) -> eo |> exprOptNoSideEffects
5254
| Texp_field (e, _lid, _ld) -> e |> exprNoSideEffects

analysis/src/ProcessCmt.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,14 +700,15 @@ and scanLetModules ~env (e : Typedtree.expression) =
700700
| Some g -> scanLetModules ~env g
701701
| None -> ());
702702
scanLetModules ~env c_rhs
703-
| Texp_try (e, cases) ->
703+
| Texp_try (e, cases, finally_expr) ->
704704
scanLetModules ~env e;
705705
cases
706706
|> List.iter (fun {Typedtree.c_lhs = _; c_guard; c_rhs} ->
707707
(match c_guard with
708708
| Some g -> scanLetModules ~env g
709709
| None -> ());
710-
scanLetModules ~env c_rhs)
710+
scanLetModules ~env c_rhs);
711+
finally_expr |> Option.iter (scanLetModules ~env)
711712
| Texp_ifthenelse (e1, e2, e3Opt) -> (
712713
scanLetModules ~env e1;
713714
scanLetModules ~env e2;

compiler/core/js_dump.ml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,10 +1581,10 @@ and statement_desc top cxt f (s : J.statement_desc) : cxt =
15811581
match fin with
15821582
| None -> cxt
15831583
| Some b ->
1584-
P.group f 1 (fun _ ->
1585-
P.string f L.finally;
1586-
P.space f;
1587-
brace_block cxt f b))
1584+
P.space f;
1585+
P.string f L.finally;
1586+
P.space f;
1587+
brace_block cxt f b)
15881588

15891589
and function_body ?directive (cxt : cxt) f ~return_unit (b : J.block) : unit =
15901590
(match directive with

compiler/core/lam.ml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ module Types = struct
101101
| Lstringswitch of t * (string * t) list * t option
102102
| Lstaticraise of int * t list
103103
| Lstaticcatch of t * (int * ident list) * t
104-
| Ltrywith of t * ident * t
104+
| Ltrywith of t * ident * t option * t option
105105
| Lifthenelse of t * t * t
106106
| Lsequence of t * t
107107
| Lwhile of t * t
@@ -153,7 +153,7 @@ module X = struct
153153
| Lstringswitch of t * (string * t) list * t option
154154
| Lstaticraise of int * t list
155155
| Lstaticcatch of t * (int * ident list) * t
156-
| Ltrywith of t * ident * t
156+
| Ltrywith of t * ident * t option * t option
157157
| Lifthenelse of t * t * t
158158
| Lsequence of t * t
159159
| Lwhile of t * t
@@ -224,10 +224,11 @@ let inner_map (l : t) (f : t -> X.t) : X.t =
224224
let e1 = f e1 in
225225
let e2 = f e2 in
226226
Lstaticcatch (e1, vars, e2)
227-
| Ltrywith (e1, exn, e2) ->
227+
| Ltrywith (e1, exn, e2, finally_expr) ->
228228
let e1 = f e1 in
229-
let e2 = f e2 in
230-
Ltrywith (e1, exn, e2)
229+
let e2 = Ext_option.map e2 f in
230+
let finally_expr = Ext_option.map finally_expr f in
231+
Ltrywith (e1, exn, e2, finally_expr)
231232
| Lifthenelse (e1, e2, e3) ->
232233
let e1 = f e1 in
233234
let e2 = f e2 in
@@ -457,7 +458,8 @@ let function_ ~attr ~arity ~params ~body : t =
457458
let let_ kind id e body : t = Llet (kind, id, e, body)
458459
let letrec bindings body : t = Lletrec (bindings, body)
459460
let while_ a b : t = Lwhile (a, b)
460-
let try_ body id handler : t = Ltrywith (body, id, handler)
461+
let try_ body id handler finally_expr : t =
462+
Ltrywith (body, id, handler, finally_expr)
461463
let for_ v e1 e2 dir e3 : t = Lfor (v, e1, e2, dir, e3)
462464
let assign v l : t = Lassign (v, l)
463465
let staticcatch a b c : t = Lstaticcatch (a, b, c)

compiler/core/lam.mli

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ and t = private
7474
| Lstringswitch of t * (string * t) list * t option
7575
| Lstaticraise of int * t list
7676
| Lstaticcatch of t * (int * ident list) * t
77-
| Ltrywith of t * ident * t
77+
| Ltrywith of t * ident * t option * t option
7878
| Lifthenelse of t * t * t
7979
| Lsequence of t * t
8080
| Lwhile of t * t
@@ -151,7 +151,7 @@ val seq : t -> t -> t
151151
val while_ : t -> t -> t
152152

153153
(* val event : t -> Lambda.lambda_event -> t *)
154-
val try_ : t -> ident -> t -> t
154+
val try_ : t -> ident -> t option -> t option -> t
155155

156156
val assign : ident -> t -> t
157157

compiler/core/lam_analysis.ml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,10 @@ let rec no_side_effects (lam : Lam.t) : bool =
109109
for example [String.contains],
110110
[Format.make_queue_elem]
111111
*)
112-
| Ltrywith (body, _exn, handler) ->
113-
no_side_effects body && no_side_effects handler
112+
| Ltrywith (body, _exn, handler, finally_expr) ->
113+
no_side_effects body
114+
&& Option.fold ~none:true ~some:no_side_effects handler
115+
&& Option.fold ~none:true ~some:no_side_effects finally_expr
114116
| Lifthenelse (a, b, c) ->
115117
no_side_effects a && no_side_effects b && no_side_effects c
116118
| Lsequence (a, b) -> no_side_effects a && no_side_effects b
@@ -174,7 +176,10 @@ let rec size (lam : Lam.t) =
174176
| Lstaticraise (_i, ls) ->
175177
Ext_list.fold_left ls 1 (fun acc x -> size x + acc)
176178
| Lstaticcatch _ -> really_big ()
177-
| Ltrywith _ -> really_big ()
179+
| Ltrywith (body, _exn, handler, finally_expr) ->
180+
size body
181+
+ Option.fold ~none:0 ~some:size handler
182+
+ Option.fold ~none:0 ~some:size finally_expr
178183
| Lifthenelse (l1, l2, l3) -> 1 + size l1 + size l2 + size l3
179184
| Lsequence (l1, l2) -> size l1 + size l2
180185
| Lwhile _ -> really_big ()

compiler/core/lam_arity_analysis.ml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,12 @@ let rec get_arity (meta : Lam_stats.t) (lam : Lam.t) : Lam_arity.t =
125125
| None -> all_lambdas meta (Ext_list.map sw snd)
126126
| Some v -> all_lambdas meta (v :: Ext_list.map sw snd))
127127
| Lstaticcatch (_, _, handler) -> get_arity meta handler
128-
| Ltrywith (l1, _, l2) -> all_lambdas meta [l1; l2]
128+
| Ltrywith (l1, _, Some l2, Some finally_expr) ->
129+
all_lambdas meta [l1; l2; finally_expr]
130+
| Ltrywith (l1, _, Some l2, None) -> all_lambdas meta [l1; l2]
131+
| Ltrywith (l1, _, None, Some finally_expr) ->
132+
all_lambdas meta [l1; finally_expr]
133+
| Ltrywith (l1, _, None, None) -> all_lambdas meta [l1]
129134
| Lifthenelse (_, l2, l3) -> all_lambdas meta [l2; l3]
130135
| Lsequence (_, l2) -> get_arity meta l2
131136
| Lstaticraise _ (* since it will not be in tail position *) -> Lam_arity.na

compiler/core/lam_bounded_vars.ml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,12 @@ let rewrite (map : _ Hash_ident.t) (lam : Lam.t) : Lam.t =
136136
let l = aux l in
137137
Lam.stringswitch l (Ext_list.map_snd sw aux) (option_map d)
138138
| Lstaticraise (i, ls) -> Lam.staticraise i (Ext_list.map ls aux)
139-
| Ltrywith (l1, v, l2) ->
139+
| Ltrywith (l1, v, l2, finally_expr) ->
140140
let l1 = aux l1 in
141141
let v = rebind v in
142-
let l2 = aux l2 in
143-
Lam.try_ l1 v l2
142+
let l2 = option_map l2 in
143+
let finally_expr = option_map finally_expr in
144+
Lam.try_ l1 v l2 finally_expr
144145
| Lifthenelse (l1, l2, l3) ->
145146
let l1 = aux l1 in
146147
let l2 = aux l2 in

0 commit comments

Comments
 (0)