Skip to content

Commit 773c1bc

Browse files
committed
generate defensive code
1 parent c7bcdd4 commit 773c1bc

17 files changed

+650
-94
lines changed

jscomp/others/js_mapperRt.ml

+17-14
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@
3232
[uper -lower > 1], [mid <> lower]
3333
*)
3434
let rec binSearchAux lower upper xs (k : int) =
35+
[%assert lower < upper];
3536
let mid = (lower + upper) / 2 in
36-
let i,v = Array.unsafe_get xs mid in
37+
let i,v = Array.unsafe_get xs mid in
3738
if i = k then v
3839
else if i < k then
3940
binSearchAux (mid + 1) upper xs k
4041
else
41-
binSearchAux lower (mid - 1) xs k
42+
binSearchAux lower mid xs k (*Invariant: mid < upper *)
4243

4344

4445

@@ -58,16 +59,17 @@ let rec revSearchAux
5859
let revSearch len array (x : string) : int option =
5960
revSearchAux 0 len array x
6061

61-
let rec revSearchAssertAux
62+
let rec revSearchAssertAux len
6263
i (xs : (int * string) array) (k : string) =
64+
[%assert i < len];
6365
let (idx,s) = Array.unsafe_get xs i in
6466
if s = k then
6567
idx
6668
else
67-
revSearchAssertAux (i + 1) xs k
69+
revSearchAssertAux len (i + 1) xs k
6870

69-
let revSearchAssert array (x : string) : int =
70-
revSearchAssertAux 0 array x
71+
let revSearchAssert len array (x : string) : int =
72+
revSearchAssertAux len 0 array x
7173

7274
let toInt (i : int) (xs : int array) =
7375
Array.unsafe_get xs i
@@ -82,12 +84,13 @@ let rec fromIntAux (enum : int) i len xs =
8284
let fromInt len (xs : int array) (enum : int ) : 'variant option =
8385
fromIntAux enum 0 len xs
8486

85-
let rec fromIntAssertAux (enum : int) i xs =
86-
let k = Array.unsafe_get xs i in
87-
if k = enum then i
88-
else fromIntAssertAux enum (i + 1) xs
89-
87+
let rec fromIntAssertAux len (enum : int) i xs =
88+
[%assert i < len];
89+
(*TODO: replaced by [%assert i < len ]*)
90+
let k = Array.unsafe_get xs i in
91+
if k = enum then i
92+
else fromIntAssertAux len enum (i + 1) xs
93+
9094
(** [length] is not relevant any more *)
91-
let fromIntAssert (xs : int array) (enum : int )=
92-
fromIntAssertAux enum 0 xs
93-
95+
let fromIntAssert len (xs : int array) (enum : int )=
96+
fromIntAssertAux len enum 0 xs

jscomp/others/js_mapperRt.mli

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ val revSearch:
4444
int option
4545

4646
val revSearchAssert:
47+
int -> (* len *)
4748
(int * string) array ->
4849
string ->
4950
int
@@ -66,6 +67,7 @@ val fromInt :
6667
int option
6768

6869
val fromIntAssert:
70+
int -> (* len *)
6971
int array ->
7072
int ->
7173
int

jscomp/syntax/ast_derive_js_mapper.ml

+37-9
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ let handle_config (config : Parsetree.expression option) =
5858
}
5959
],None)
6060
-> not (x = "false")
61+
| Pexp_ident {txt = Lident ("jsType")}
62+
-> true
6163
| _ -> invalid_config config)
6264
| None -> false
6365
let noloc = Location.none
@@ -110,11 +112,12 @@ let revSearch len constantArray exp =
110112
constantArray
111113
exp
112114

113-
let revSearchAssert constantArray exp =
114-
app2
115+
let revSearchAssert len constantArray exp =
116+
app3
115117
(Exp.ident
116118
{loc= noloc;
117119
txt = Longident.Ldot (jsMapperRt, "revSearchAssert")})
120+
len
118121
constantArray
119122
exp
120123

@@ -134,14 +137,24 @@ let fromInt len array exp =
134137
array
135138
exp
136139

137-
let fromIntAssert array exp =
138-
app2
140+
let fromIntAssert len array exp =
141+
app3
139142
(Exp.ident
140143
{loc = noloc;
141144
txt = Longident.Ldot (jsMapperRt,"fromIntAssert")})
145+
len
142146
array
143147
exp
144148

149+
150+
let assertExp e =
151+
Exp.extension
152+
({Asttypes.loc = noloc; txt = "assert"},
153+
(PStr
154+
[Str.eval e ]
155+
)
156+
)
157+
145158
let init () =
146159
Ast_derive.register
147160
"jsMapper"
@@ -267,6 +280,7 @@ let init () =
267280
(Pat.var pat_param)
268281
(if createType then
269282
revSearchAssert
283+
exp_len
270284
expConstantArray
271285
(exp_param +: newType)
272286
+>
@@ -295,6 +309,7 @@ let init () =
295309
match xs with
296310
| `New xs ->
297311
let constantArrayExp = Exp.ident {loc; txt = Lident constantArray} in
312+
let exp_len = const_int (List.length ctors) in
298313
let v = [
299314
eraseTypeStr;
300315
Ast_comb.single_non_rec_value
@@ -316,13 +331,14 @@ let init () =
316331
(
317332
if createType then
318333
fromIntAssert
334+
exp_len
319335
constantArrayExp
320336
(exp_param +: newType)
321337
+>
322338
core_type
323339
else
324340
fromInt
325-
(const_int (List.length ctors))
341+
exp_len
326342
constantArrayExp
327343
exp_param
328344
+>
@@ -340,18 +356,30 @@ let init () =
340356
(eraseType exp_param +~ const_int offset)
341357
)
342358
;
359+
let len = List.length ctors in
360+
let range_low = const_int (offset + 0) in
361+
let range_upper = const_int (offset + len - 1) in
362+
343363
Ast_comb.single_non_rec_value
344364
{loc ; txt = fromJs}
345365
(Exp.fun_ "" None
346366
(Pat.var pat_param)
347367
(if createType then
348-
(( exp_param +: newType) -~ const_int offset)
368+
(Exp.let_ Nonrecursive
369+
[Vb.mk
370+
(Pat.var pat_param)
371+
(exp_param +: newType)
372+
]
373+
(
374+
Exp.sequence
375+
(assertExp
376+
((exp_param <=~ range_upper) &&~ (range_low <=~ exp_param))
377+
)
378+
(exp_param -~ const_int offset))
379+
)
349380
+>
350381
core_type
351382
else
352-
let len = List.length ctors in
353-
let range_low = const_int (offset + 0) in
354-
let range_upper = const_int (offset + len - 1) in
355383
(Exp.ifthenelse
356384
( (exp_param <=~ range_upper) &&~ (range_low <=~ exp_param))
357385
(Exp.construct {loc; txt = Lident "Some"}

jscomp/test/.depend

+2-1
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ array_safe_get.cmj : ../stdlib/array.cmj
6464
array_subtle_test.cmj : mt.cmj ../runtime/js.cmj ../stdlib/array.cmj
6565
array_test.cmj : ../stdlib/pervasives.cmj mt.cmj ../stdlib/list.cmj \
6666
../stdlib/array.cmj array_test.cmi
67-
ast_abstract_test.cmj :
67+
ast_abstract_test.cmj : mt.cmj
6868
ast_js_mapper_poly_test.cmj : mt.cmj ../stdlib/array.cmj
6969
ast_js_mapper_test.cmj : ../stdlib/array.cmj ast_js_mapper_test.cmi
70+
ast_mapper_defensive_test.cmj : ../stdlib/obj.cmj mt.cmj
7071
async_ideas.cmj :
7172
attr_test.cmj :
7273
b.cmj :

jscomp/test/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ OTHERS := test_literals a test_ari test_export2 test_internalOO test_obj_simple_
204204
ast_js_mapper_test\
205205
ast_js_mapper_poly_test\
206206
big_polyvar_test\
207-
ast_abstract_test
207+
ast_abstract_test\
208+
ast_mapper_defensive_test\
208209
# bs_uncurry_test
209210
# needs Lam to get rid of Uncurry arity first
210211
# simple_derive_test

0 commit comments

Comments
 (0)