Skip to content

Commit ac01a86

Browse files
authored
Merge pull request #3775 from BuckleScript/invariant_check_for_staticfail
add one more invariant check of staticfail
2 parents d9e73ea + b50847e commit ac01a86

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

jscomp/core/lam_check.ml

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,64 @@ let check file lam =
4646
end
4747
else Ident_hash_set.add defined_variables id
4848
in
49+
(* TODO: replaced by a slow version of {!Lam_iter.inner_iter} *)
4950
let rec
50-
iter_list xs = List.iter iter xs
51+
check_list xs (cxt : Set_int.t) = Ext_list.iter xs (fun x -> check_staticfails x cxt)
52+
and check_list_snd : 'a. ('a * Lam.t) list -> _ -> unit = fun xs cxt ->
53+
Ext_list.iter_snd xs (fun x -> check_staticfails x cxt)
54+
and check_staticfails (l : Lam.t) (cxt : Set_int.t)=
55+
match l with
56+
| Lvar _ -> ()
57+
| Lconst _ -> ()
58+
| Lglobal_module _ -> ()
59+
| Lprim {args; _} ->
60+
check_list args cxt
61+
| Lapply{fn; args; _} ->
62+
check_list (fn::args) cxt
63+
(* check invariant that staticfaill does not cross function/while/for loop*)
64+
| Lfunction{body;params} ->
65+
check_staticfails body Set_int.empty
66+
| Lwhile(e1, e2) ->
67+
check_staticfails e1 cxt;
68+
check_staticfails e2 Set_int.empty
69+
| Lfor(v, e1, e2, dir, e3) ->
70+
check_staticfails e1 cxt; check_staticfails e2 cxt;
71+
check_staticfails e3 Set_int.empty;
72+
| Llet(str, id, arg, body) ->
73+
check_list [arg;body] cxt
74+
| Lletrec(decl, body) ->
75+
check_list_snd decl cxt;
76+
check_staticfails body cxt
77+
| Lswitch(arg, sw) ->
78+
check_staticfails arg cxt ;
79+
check_list_snd sw.sw_consts cxt;
80+
check_list_snd sw.sw_blocks cxt;
81+
Ext_option.iter sw.sw_failaction (fun x -> check_staticfails x cxt);
82+
| Lstringswitch (arg,cases,default) ->
83+
check_staticfails arg cxt ;
84+
check_list_snd cases cxt;
85+
Ext_option.iter default (fun x -> check_staticfails x cxt)
86+
| Lstaticraise (i,args) ->
87+
if Set_int.mem cxt i then check_list args cxt
88+
else failwith ("exit " ^ string_of_int i ^ " unbound")
89+
| Lstaticcatch(e1, (j,vars), e2) ->
90+
check_staticfails e1 (Set_int.add cxt j);
91+
check_staticfails e2 cxt
92+
| Ltrywith(e1, exn, e2) ->
93+
check_staticfails e1 cxt;
94+
check_staticfails e2 cxt
95+
| Lifthenelse(e1, e2, e3) ->
96+
check_list [e1;e2;e3] cxt
97+
| Lsequence(e1, e2) ->
98+
check_list [e1;e2] cxt
99+
100+
| Lassign(id, e) ->
101+
check_staticfails e cxt
102+
| Lsend (k, met, obj, args, _) ->
103+
check_list (met::obj::args) cxt
104+
in
105+
let rec
106+
iter_list xs = Ext_list.iter xs iter
51107
and iter_list_snd : 'a. ('a * Lam.t) list -> unit = fun xs ->
52108
Ext_list.iter_snd xs iter
53109
and iter (l : Lam.t) =
@@ -110,6 +166,7 @@ let check file lam =
110166

111167
in
112168
begin
169+
check_staticfails lam Set_int.empty;
113170
iter lam;
114171
assert (!success) ;
115172
lam

0 commit comments

Comments
 (0)