@@ -117,9 +117,25 @@ let drop n (vs : 'a stack) at =
117
117
* c : config
118
118
*)
119
119
120
- let const_i32_add i j at msg =
121
- let k = I32. add i j in
122
- if I32. lt_u k i then Trapping msg else Plain (Const (I32 k @@ at))
120
+ let mem_oob frame x i n =
121
+ I64. gt_u (I64. add (I64_convert. extend_i32_u i) (I64_convert. extend_i32_u n))
122
+ (Memory. bound (memory frame.inst x))
123
+
124
+ let data_oob frame x i n =
125
+ match ! (data frame.inst x) with
126
+ | None -> false
127
+ | Some bs -> I64. gt_u (I64. add (I64_convert. extend_i32_u i) (I64_convert. extend_i32_u n))
128
+ (I64. of_int_u (String. length bs))
129
+
130
+ let table_oob frame x i n =
131
+ I64. gt_u (I64. add (I64_convert. extend_i32_u i) (I64_convert. extend_i32_u n))
132
+ (I64_convert. extend_i32_u (Table. size (table frame.inst x)))
133
+
134
+ let elem_oob frame x i n =
135
+ match ! (elem frame.inst x) with
136
+ | None -> false
137
+ | Some es -> I64. gt_u (I64. add (I64_convert. extend_i32_u i) (I64_convert. extend_i32_u n))
138
+ (I64. of_int_u (List. length es))
123
139
124
140
let rec step (c : config ) : config =
125
141
let {frame; code = vs, es; _} = c in
@@ -205,6 +221,10 @@ let rec step (c : config) : config =
205
221
| TableCopy , I32 0l :: I32 s :: I32 d :: vs' ->
206
222
vs', []
207
223
224
+ | TableCopy , I32 n :: I32 s :: I32 d :: vs'
225
+ when table_oob frame (0l @@ e.at) s n || table_oob frame (0l @@ e.at) d n ->
226
+ vs', [Trapping (table_error e.at Table. Bounds ) @@ e.at]
227
+
208
228
(* TODO: turn into small-step, but needs reference values *)
209
229
| TableCopy , I32 n :: I32 s :: I32 d :: vs' ->
210
230
let tab = table frame.inst (0l @@ e.at) in
@@ -214,6 +234,10 @@ let rec step (c : config) : config =
214
234
| TableInit x , I32 0l :: I32 s :: I32 d :: vs' ->
215
235
vs', []
216
236
237
+ | TableInit x, I32 n :: I32 s :: I32 d :: vs'
238
+ when table_oob frame (0l @@ e.at) d n || elem_oob frame x s n ->
239
+ vs', [Trapping (table_error e.at Table. Bounds ) @@ e.at]
240
+
217
241
(* TODO: turn into small-step, but needs reference values *)
218
242
| TableInit x , I32 n :: I32 s :: I32 d :: vs' ->
219
243
let tab = table frame.inst (0l @@ e.at) in
@@ -233,22 +257,22 @@ let rec step (c : config) : config =
233
257
234
258
| Load {offset; ty; sz; _} , I32 i :: vs' ->
235
259
let mem = memory frame.inst (0l @@ e.at) in
236
- let addr = I64_convert. extend_i32_u i in
260
+ let a = I64_convert. extend_i32_u i in
237
261
(try
238
262
let v =
239
263
match sz with
240
- | None -> Memory. load_value mem addr offset ty
241
- | Some (sz , ext ) -> Memory. load_packed sz ext mem addr offset ty
264
+ | None -> Memory. load_value mem a offset ty
265
+ | Some (sz , ext ) -> Memory. load_packed sz ext mem a offset ty
242
266
in v :: vs', []
243
267
with exn -> vs', [Trapping (memory_error e.at exn ) @@ e.at])
244
268
245
269
| Store {offset; sz; _} , v :: I32 i :: vs' ->
246
270
let mem = memory frame.inst (0l @@ e.at) in
247
- let addr = I64_convert. extend_i32_u i in
271
+ let a = I64_convert. extend_i32_u i in
248
272
(try
249
273
(match sz with
250
- | None -> Memory. store_value mem addr offset v
251
- | Some sz -> Memory. store_packed sz mem addr offset v
274
+ | None -> Memory. store_value mem a offset v
275
+ | Some sz -> Memory. store_packed sz mem a offset v
252
276
);
253
277
vs', []
254
278
with exn -> vs', [Trapping (memory_error e.at exn ) @@ e.at]);
@@ -268,21 +292,17 @@ let rec step (c : config) : config =
268
292
| MemoryFill , I32 0l :: v :: I32 i :: vs' ->
269
293
vs', []
270
294
271
- | MemoryFill , I32 1l :: v :: I32 i :: vs' ->
272
- vs', List. map (at e.at) [
273
- Plain (Const (I32 i @@ e.at));
274
- Plain (Const (v @@ e.at));
275
- Plain (Store
276
- {ty = I32Type ; align = 0 ; offset = 0l ; sz = Some Memory. Pack8 });
277
- ]
295
+ | MemoryFill , I32 n :: v :: I32 i :: vs'
296
+ when mem_oob frame (0l @@ e.at) i n ->
297
+ vs', [Trapping (memory_error e.at Memory. Bounds ) @@ e.at]
278
298
279
299
| MemoryFill , I32 n :: v :: I32 i :: vs' ->
280
300
vs', List. map (at e.at) [
281
301
Plain (Const (I32 i @@ e.at));
282
302
Plain (Const (v @@ e.at));
283
- Plain (Const ( I32 1l @@ e.at));
284
- Plain ( MemoryFill );
285
- const_i32_add i 1l e.at (memory_error e.at Memory. Bounds );
303
+ Plain (Store
304
+ {ty = I32Type ; align = 0 ; offset = 0l ; sz = Some Memory. Pack8 } );
305
+ Plain ( Const ( I32 ( I32. add i 1l ) @@ e.at) );
286
306
Plain (Const (v @@ e.at));
287
307
Plain (Const (I32 (I32. sub n 1l ) @@ e.at));
288
308
Plain (MemoryFill );
@@ -291,71 +311,67 @@ let rec step (c : config) : config =
291
311
| MemoryCopy , I32 0l :: I32 s :: I32 d :: vs' ->
292
312
vs', []
293
313
294
- | MemoryCopy , I32 1l :: I32 s :: I32 d :: vs' ->
314
+ | MemoryCopy , I32 n :: I32 s :: I32 d :: vs'
315
+ when mem_oob frame (0l @@ e.at) s n || mem_oob frame (0l @@ e.at) d n ->
316
+ vs', [Trapping (memory_error e.at Memory. Bounds ) @@ e.at]
317
+
318
+ | MemoryCopy , I32 n :: I32 s :: I32 d :: vs' when d < = s ->
295
319
vs', List. map (at e.at) [
296
320
Plain (Const (I32 d @@ e.at));
297
321
Plain (Const (I32 s @@ e.at));
298
322
Plain (Load
299
323
{ty = I32Type ; align = 0 ; offset = 0l ; sz = Some Memory. (Pack8 , ZX )});
300
324
Plain (Store
301
325
{ty = I32Type ; align = 0 ; offset = 0l ; sz = Some Memory. Pack8 });
302
- ]
303
-
304
- | MemoryCopy , I32 n :: I32 s :: I32 d :: vs' when d < = s ->
305
- vs', List. map (at e.at) [
306
- Plain (Const (I32 d @@ e.at));
307
- Plain (Const (I32 s @@ e.at));
308
- Plain (Const (I32 1l @@ e.at));
309
- Plain (MemoryCopy );
310
- const_i32_add d 1l e.at (memory_error e.at Memory. Bounds );
311
- const_i32_add s 1l e.at (memory_error e.at Memory. Bounds );
326
+ Plain (Const (I32 (I32. add d 1l ) @@ e.at));
327
+ Plain (Const (I32 (I32. add s 1l ) @@ e.at));
312
328
Plain (Const (I32 (I32. sub n 1l ) @@ e.at));
313
329
Plain (MemoryCopy );
314
330
]
315
331
316
332
| MemoryCopy , I32 n :: I32 s :: I32 d :: vs' when s < d ->
317
333
vs', List. map (at e.at) [
318
- const_i32_add d (I32. sub n 1l ) e.at (memory_error e.at Memory. Bounds );
319
- const_i32_add s (I32. sub n 1l ) e.at (memory_error e.at Memory. Bounds );
320
- Plain (Const (I32 1l @@ e.at));
334
+ Plain ( Const (I32 ( I32. add d 1l ) @@ e.at) );
335
+ Plain ( Const (I32 ( I32. add s 1l ) @@ e.at) );
336
+ Plain (Const (I32 ( I32. sub n 1l ) @@ e.at));
321
337
Plain (MemoryCopy );
322
338
Plain (Const (I32 d @@ e.at));
323
339
Plain (Const (I32 s @@ e.at));
324
- Plain (Const (I32 (I32. sub n 1l ) @@ e.at));
325
- Plain (MemoryCopy );
340
+ Plain (Load
341
+ {ty = I32Type ; align = 0 ; offset = 0l ; sz = Some Memory. (Pack8 , ZX )});
342
+ Plain (Store
343
+ {ty = I32Type ; align = 0 ; offset = 0l ; sz = Some Memory. Pack8 });
326
344
]
327
345
328
346
| MemoryInit x , I32 0l :: I32 s :: I32 d :: vs' ->
329
347
vs', []
330
348
331
- | MemoryInit x , I32 1l :: I32 s :: I32 d :: vs' ->
349
+ | MemoryInit x, I32 n :: I32 s :: I32 d :: vs'
350
+ when mem_oob frame (0l @@ e.at) d n ->
351
+ vs', [Trapping (memory_error e.at Memory. Bounds ) @@ e.at]
352
+
353
+ | MemoryInit x, I32 n :: I32 s :: I32 d :: vs'
354
+ when data_oob frame x s n ->
355
+ vs', [Trapping " out of bounds data segment access" @@ e.at]
356
+
357
+ | MemoryInit x , I32 n :: I32 s :: I32 d :: vs' ->
332
358
(match ! (data frame.inst x) with
333
359
| None ->
334
360
vs', [Trapping " data segment dropped" @@ e.at]
335
- | Some bs when Int32. to_int s > = String. length bs ->
336
- vs', [Trapping " out of bounds data segment access" @@ e.at]
337
361
| Some bs ->
338
362
let b = Int32. of_int (Char. code bs.[Int32. to_int s]) in
339
363
vs', List. map (at e.at) [
340
364
Plain (Const (I32 d @@ e.at));
341
365
Plain (Const (I32 b @@ e.at));
342
366
Plain (
343
367
Store {ty = I32Type ; align = 0 ; offset = 0l ; sz = Some Memory. Pack8 });
368
+ Plain (Const (I32 (I32. add d 1l ) @@ e.at));
369
+ Plain (Const (I32 (I32. add s 1l ) @@ e.at));
370
+ Plain (Const (I32 (I32. sub n 1l ) @@ e.at));
371
+ Plain (MemoryInit x);
344
372
]
345
373
)
346
374
347
- | MemoryInit x , I32 n :: I32 s :: I32 d :: vs' ->
348
- vs', List. map (at e.at) [
349
- Plain (Const (I32 d @@ e.at));
350
- Plain (Const (I32 s @@ e.at));
351
- Plain (Const (I32 1l @@ e.at));
352
- Plain (MemoryInit x);
353
- const_i32_add d 1l e.at (memory_error e.at Memory. Bounds );
354
- const_i32_add s 1l e.at (memory_error e.at Memory. Bounds );
355
- Plain (Const (I32 (I32. sub n 1l ) @@ e.at));
356
- Plain (MemoryInit x);
357
- ]
358
-
359
375
| DataDrop x , vs ->
360
376
let seg = data frame.inst x in
361
377
(match ! seg with
0 commit comments