@@ -17,6 +17,10 @@ exception Trap = Trap.Error
17
17
exception Crash = Crash. Error (* failure that cannot happen in valid code *)
18
18
exception Exhaustion = Exhaustion. Error
19
19
20
+ let table_error at = function
21
+ | Table. Bounds -> " out of bounds table access"
22
+ | exn -> raise exn
23
+
20
24
let memory_error at = function
21
25
| Memory. Bounds -> " out of bounds memory access"
22
26
| Memory. SizeOverflow -> " memory size overflow"
@@ -78,6 +82,8 @@ let func (inst : module_inst) x = lookup "function" inst.funcs x
78
82
let table (inst : module_inst ) x = lookup " table" inst.tables x
79
83
let memory (inst : module_inst ) x = lookup " memory" inst.memories x
80
84
let global (inst : module_inst ) x = lookup " global" inst.globals x
85
+ let elems (inst : module_inst ) x = lookup " elems" inst.elems x
86
+ let data (inst : module_inst ) x = lookup " data" inst.data x
81
87
let local (frame : frame ) x = lookup " local" frame.locals x
82
88
83
89
let elem inst x i at =
@@ -249,6 +255,22 @@ let rec step (c : config) : config =
249
255
(try Eval_numeric. eval_cvtop cvtop v :: vs', []
250
256
with exn -> vs', [Trapping (numeric_error e.at exn ) @@ e.at])
251
257
258
+ | MemoryInit x , I32 n :: I32 s :: I32 d :: vs' ->
259
+ let mem = memory frame.inst (0l @@ e.at) in
260
+ (match ! (data frame.inst x) with
261
+ | Some bs ->
262
+ let dst = I64_convert. extend_i32_u d in
263
+ let src = I64_convert. extend_i32_u s in
264
+ (try Memory. init mem bs dst src n; vs', []
265
+ with exn -> vs', [Trapping (memory_error e.at exn ) @@ e.at])
266
+ | None -> vs', [Trapping " data segment dropped" @@ e.at])
267
+
268
+ | DataDrop x , vs ->
269
+ let seg = data frame.inst x in
270
+ (match ! seg with
271
+ | Some _ -> seg := None ; vs, []
272
+ | None -> vs, [Trapping " data segment dropped" @@ e.at])
273
+
252
274
| MemoryCopy , I32 n :: I32 s :: I32 d :: vs' ->
253
275
let mem = memory frame.inst (0l @@ e.at) in
254
276
let dst = I64_convert. extend_i32_u d in
@@ -262,6 +284,25 @@ let rec step (c : config) : config =
262
284
(try Memory. fill mem addr (Int32. to_int b) n; vs', []
263
285
with exn -> vs', [Trapping (memory_error e.at exn ) @@ e.at])
264
286
287
+ | TableInit x , I32 n :: I32 s :: I32 d :: vs' ->
288
+ let tab = table frame.inst (0l @@ e.at) in
289
+ (match ! (elems frame.inst x) with
290
+ | Some es ->
291
+ (try Table. init tab es d s n; vs', []
292
+ with exn -> vs', [Trapping (table_error e.at exn ) @@ e.at])
293
+ | None -> vs', [Trapping " elements segment dropped" @@ e.at])
294
+
295
+ | ElemDrop x , vs ->
296
+ let seg = elems frame.inst x in
297
+ (match ! seg with
298
+ | Some _ -> seg := None ; vs, []
299
+ | None -> vs, [Trapping " elements segment dropped" @@ e.at])
300
+
301
+ | TableCopy , I32 n :: I32 s :: I32 d :: vs' ->
302
+ let tab = table frame.inst (0l @@ e.at) in
303
+ (try Table. copy tab d s n; vs', []
304
+ with exn -> vs', [Trapping (table_error e.at exn ) @@ e.at])
305
+
265
306
| _ ->
266
307
let s1 = string_of_values (List. rev vs) in
267
308
let s2 = string_of_value_types (List. map type_of (List. rev vs)) in
@@ -394,6 +435,19 @@ let create_export (inst : module_inst) (ex : export) : export_inst =
394
435
| GlobalExport x -> ExternGlobal (global inst x)
395
436
in name, ext
396
437
438
+ let elems_list inst init =
439
+ List. map (fun x -> (FuncElem (func inst x))) init
440
+
441
+ let create_elems (inst : module_inst ) (seg : table_segment ) : elems_inst =
442
+ match seg.it with
443
+ | Active _ -> ref None
444
+ | Passive init -> ref (Some (elems_list inst init))
445
+
446
+ let create_data (inst : module_inst ) (seg : memory_segment ) : data_inst =
447
+ match seg.it with
448
+ | Active _ -> ref None
449
+ | Passive init -> ref (Some init)
450
+
397
451
398
452
let init_func (inst : module_inst ) (func : func_inst ) =
399
453
match func with
@@ -405,7 +459,9 @@ let init_table (inst : module_inst) (seg : table_segment) =
405
459
| Active {index; offset = const ; init} ->
406
460
let tab = table inst index in
407
461
let offset = i32 (eval_const inst const) const.at in
408
- (try Table. init tab offset (List. map (fun x -> FuncElem (func inst x)) init)
462
+ let elems = elems_list inst init in
463
+ let len = Int32. of_int (List. length elems) in
464
+ (try Table. init tab elems offset 0l len
409
465
with Table. Bounds -> Link. error seg.at " elements segment does not fit table" )
410
466
| Passive init -> ()
411
467
@@ -415,7 +471,8 @@ let init_memory (inst : module_inst) (seg : memory_segment) =
415
471
let mem = memory inst index in
416
472
let offset' = i32 (eval_const inst const) const.at in
417
473
let offset = I64_convert. extend_i32_u offset' in
418
- (try Memory. init mem offset init
474
+ let len = Int32. of_int (String. length init) in
475
+ (try Memory. init mem init offset 0L len
419
476
with Memory. Bounds -> Link. error seg.at " data segment does not fit memory" )
420
477
| Passive init -> ()
421
478
@@ -448,10 +505,16 @@ let init (m : module_) (exts : extern list) : module_inst =
448
505
funcs = inst0.funcs @ fs;
449
506
tables = inst0.tables @ List. map (create_table inst0) tables;
450
507
memories = inst0.memories @ List. map (create_memory inst0) memories;
451
- globals = inst0.globals @ List. map (create_global inst0) globals;
508
+ globals = inst0.globals @ List. map (create_global inst0) globals
509
+ }
510
+ in
511
+ let inst =
512
+ { inst1 with
513
+ exports = List. map (create_export inst1) exports;
514
+ elems = List. map (create_elems inst1) elems;
515
+ data = List. map (create_data inst1) data
452
516
}
453
517
in
454
- let inst = {inst1 with exports = List. map (create_export inst1) exports} in
455
518
List. iter (init_func inst) fs;
456
519
List. iter (init_table inst) elems;
457
520
List. iter (init_memory inst) data;
0 commit comments