Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit ce08751

Browse files
committed
Update interpreter and test suite for table64
1 parent 9ed8215 commit ce08751

File tree

22 files changed

+328
-147
lines changed

22 files changed

+328
-147
lines changed

interpreter/binary/decode.ml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,8 @@ let limits uN s =
190190

191191
let table_type s =
192192
let t = ref_type s in
193-
let lim, is64 = limits u32 s in
194-
require (not is64) s (pos s - 1) "tables cannot have 64-bit indices";
195-
TableType (lim, t)
193+
let lim, is64 = limits u64 s in
194+
TableType (lim, (if is64 then I64IndexType else I32IndexType), t)
196195

197196
let memory_type s =
198197
let lim, is64 = limits u64 s in

interpreter/binary/encode.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ struct
123123
byte flags; vu min; opt vu max
124124

125125
let table_type = function
126-
| TableType (lim, t) -> ref_type t; limits u32 lim I32IndexType
126+
| TableType (lim, it, t) -> ref_type t; limits u64 lim it
127127

128128
let memory_type = function
129129
| MemoryType (lim, it) -> limits u64 lim it

interpreter/exec/eval.ml

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ let numeric_error at = function
4242
| exn -> raise exn
4343

4444

45+
let value_of_index it x =
46+
match it with
47+
| I64IndexType -> Num (I64 x)
48+
| I32IndexType -> Num (I32 (Int64.to_int32 x))
49+
4550
(* Administrative Expressions & Configurations *)
4651

4752
type 'a stack = 'a list
@@ -93,13 +98,13 @@ let local (frame : frame) x = lookup "local" frame.locals x
9398

9499
let any_ref inst x i at =
95100
try Table.load (table inst x) i with Table.Bounds ->
96-
Trap.error at ("undefined element " ^ Int32.to_string i)
101+
Trap.error at ("undefined element " ^ Int64.to_string i)
97102

98103
let func_ref inst x i at =
99104
match any_ref inst x i at with
100105
| FuncRef f -> f
101-
| NullRef _ -> Trap.error at ("uninitialized element " ^ Int32.to_string i)
102-
| _ -> Crash.error at ("type mismatch for element " ^ Int32.to_string i)
106+
| NullRef _ -> Trap.error at ("uninitialized element " ^ Int64.to_string i)
107+
| _ -> Crash.error at ("type mismatch for element " ^ Int64.to_string i)
103108

104109
let func_type_of = function
105110
| Func.AstFunc (t, inst, f) -> t
@@ -140,12 +145,12 @@ let data_oob frame x i n =
140145
(Data.size (data frame.inst x))
141146

142147
let table_oob frame x i n =
143-
I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n))
144-
(I64_convert.extend_i32_u (Table.size (table frame.inst x)))
148+
I64.gt_u (I64.add (Table.index_of_num i) (Table.index_of_num n))
149+
(Table.size (table frame.inst x))
145150

146151
let elem_oob frame x i n =
147-
I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n))
148-
(I64_convert.extend_i32_u (Elem.size (elem frame.inst x)))
152+
I64.gt_u (I64.add (Table.index_of_num i) (Table.index_of_num n))
153+
(Elem.size (elem frame.inst x))
149154

150155
let inc_address i at =
151156
match i with
@@ -206,7 +211,8 @@ let rec step (c : config) : config =
206211
| Call x, vs ->
207212
vs, [Invoke (func frame.inst x) @@ e.at]
208213

209-
| CallIndirect (x, y), Num (I32 i) :: vs ->
214+
| CallIndirect (x, y), Num n :: vs ->
215+
let i = Table.index_of_num n in
210216
let func = func_ref frame.inst x i e.at in
211217
if type_ frame.inst y <> Func.type_of func then
212218
vs, [Trapping "indirect call type mismatch" @@ e.at]
@@ -241,85 +247,97 @@ let rec step (c : config) : config =
241247
with Global.NotMutable -> Crash.error e.at "write to immutable global"
242248
| Global.Type -> Crash.error e.at "type mismatch at global write")
243249

244-
| TableGet x, Num (I32 i) :: vs' ->
250+
| TableGet x, Num n :: vs' ->
251+
let i = Table.index_of_num n in
245252
(try Ref (Table.load (table frame.inst x) i) :: vs', []
246253
with exn -> vs', [Trapping (table_error e.at exn) @@ e.at])
247254

248-
| TableSet x, Ref r :: Num (I32 i) :: vs' ->
255+
| TableSet x, Ref r :: Num n :: vs' ->
256+
let i = Table.index_of_num n in
249257
(try Table.store (table frame.inst x) i r; vs', []
250258
with exn -> vs', [Trapping (table_error e.at exn) @@ e.at])
251259

252260
| TableSize x, vs ->
253-
Num (I32 (Table.size (table frame.inst x))) :: vs, []
261+
let tab = table frame.inst x in
262+
value_of_index (Table.index_of tab) (Table.size (table frame.inst x)) :: vs, []
254263

255-
| TableGrow x, Num (I32 delta) :: Ref r :: vs' ->
264+
| TableGrow x, Num delta :: Ref r :: vs' ->
256265
let tab = table frame.inst x in
266+
let delta_64 = Table.index_of_num delta in
257267
let old_size = Table.size tab in
258268
let result =
259-
try Table.grow tab delta r; old_size
260-
with Table.SizeOverflow | Table.SizeLimit | Table.OutOfMemory -> -1l
261-
in Num (I32 result) :: vs', []
269+
try Table.grow tab delta_64 r; old_size
270+
with Table.SizeOverflow | Table.SizeLimit | Table.OutOfMemory -> -1L
271+
in (value_of_index (Table.index_of tab) result) :: vs', []
262272

263-
| TableFill x, Num (I32 n) :: Ref r :: Num (I32 i) :: vs' ->
273+
| TableFill x, Num n :: Ref r :: Num i :: vs' ->
274+
let n_64 = Table.index_of_num n in
264275
if table_oob frame x i n then
265276
vs', [Trapping (table_error e.at Table.Bounds) @@ e.at]
266-
else if n = 0l then
277+
else if n_64 = 0L then
267278
vs', []
268279
else
269-
let _ = assert (I32.lt_u i 0xffff_ffffl) in
280+
let i_64 = Table.index_of_num i in
281+
let _ = assert (I64.lt_u i_64 0xffff_ffff_ffff_ffffL) in
270282
vs', List.map (at e.at) [
271-
Plain (Const (I32 i @@ e.at));
283+
Plain (Const (I64 i_64 @@ e.at));
272284
Refer r;
273285
Plain (TableSet x);
274-
Plain (Const (I32 (I32.add i 1l) @@ e.at));
286+
Plain (Const (I64 (I64.add i_64 1L) @@ e.at));
275287
Refer r;
276-
Plain (Const (I32 (I32.sub n 1l) @@ e.at));
288+
Plain (Const (I64 (I64.sub n_64 1L) @@ e.at));
277289
Plain (TableFill x);
278290
]
279291

280-
| TableCopy (x, y), Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: vs' ->
292+
| TableCopy (x, y), Num n :: Num s :: Num d :: vs' ->
293+
let n_64 = Table.index_of_num n in
294+
let s_64 = Table.index_of_num s in
295+
let d_64 = Table.index_of_num d in
281296
if table_oob frame x d n || table_oob frame y s n then
282297
vs', [Trapping (table_error e.at Table.Bounds) @@ e.at]
283-
else if n = 0l then
298+
else if n_64 = 0L then
284299
vs', []
285-
else if I32.le_u d s then
300+
else if I64.le_u d_64 s_64 then
286301
vs', List.map (at e.at) [
287-
Plain (Const (I32 d @@ e.at));
288-
Plain (Const (I32 s @@ e.at));
302+
Plain (Const (I64 d_64 @@ e.at));
303+
Plain (Const (I64 s_64 @@ e.at));
289304
Plain (TableGet y);
290305
Plain (TableSet x);
291-
Plain (Const (I32 (I32.add d 1l) @@ e.at));
292-
Plain (Const (I32 (I32.add s 1l) @@ e.at));
293-
Plain (Const (I32 (I32.sub n 1l) @@ e.at));
306+
Plain (Const (I64 (I64.add d_64 1L) @@ e.at));
307+
Plain (Const (I64 (I64.add s_64 1L) @@ e.at));
308+
Plain (Const (I64 (I64.sub n_64 1L) @@ e.at));
294309
Plain (TableCopy (x, y));
295310
]
296311
else (* d > s *)
297-
let n' = I32.sub n 1l in
312+
let n' = I64.sub n_64 1L in
298313
vs', List.map (at e.at) [
299-
Plain (Const (I32 (I32.add d n') @@ e.at));
300-
Plain (Const (I32 (I32.add s n') @@ e.at));
314+
Plain (Const (I64 (I64.add d_64 n') @@ e.at));
315+
Plain (Const (I64 (I64.add s_64 n') @@ e.at));
301316
Plain (TableGet y);
302317
Plain (TableSet x);
303-
Plain (Const (I32 d @@ e.at));
304-
Plain (Const (I32 s @@ e.at));
305-
Plain (Const (I32 n' @@ e.at));
318+
Plain (Const (I64 d_64 @@ e.at));
319+
Plain (Const (I64 s_64 @@ e.at));
320+
Plain (Const (I64 n' @@ e.at));
306321
Plain (TableCopy (x, y));
307322
]
308323

309-
| TableInit (x, y), Num (I32 n) :: Num (I32 s) :: Num (I32 d) :: vs' ->
324+
| TableInit (x, y), Num n :: Num s :: Num d :: vs' ->
325+
let n_64 = Table.index_of_num n in
310326
if table_oob frame x d n || elem_oob frame y s n then
311327
vs', [Trapping (table_error e.at Table.Bounds) @@ e.at]
312-
else if n = 0l then
328+
else if n_64 = 0L then
313329
vs', []
314330
else
331+
let d_64 = Table.index_of_num d in
332+
let s_64 = Table.index_of_num s in
315333
let seg = elem frame.inst y in
316334
vs', List.map (at e.at) [
317-
Plain (Const (I32 d @@ e.at));
318-
Refer (Elem.load seg s);
335+
Plain (Const (I64 d_64 @@ e.at));
336+
Refer (Elem.load seg s_64);
319337
Plain (TableSet x);
320-
Plain (Const (I32 (I32.add d 1l) @@ e.at));
321-
Plain (Const (I32 (I32.add s 1l) @@ e.at));
322-
Plain (Const (I32 (I32.sub n 1l) @@ e.at));
338+
Plain (Const (I64 (I64.add d_64 1L) @@ e.at));
339+
Plain (Const (I64 (I64.add s_64 1L) @@ e.at));
340+
Plain (Const (I64 (I64.sub n_64 1L) @@ e.at));
323341
Plain (TableInit (x, y));
324342
]
325343

@@ -411,15 +429,15 @@ let rec step (c : config) : config =
411429
| MemorySize, vs ->
412430
let mem = memory frame.inst (0l @@ e.at) in
413431

414-
Memory.value_of_address (Memory.index_of mem) (Memory.size mem) :: vs, []
432+
value_of_index (Memory.index_of mem) (Memory.size mem) :: vs, []
415433

416434
| MemoryGrow, Num delta :: vs' ->
417435
let mem = memory frame.inst (0l @@ e.at) in
418436
let old_size = Memory.size mem in
419437
let result =
420438
try Memory.grow mem (Memory.address_of_num delta); old_size
421439
with Memory.SizeOverflow | Memory.SizeLimit | Memory.OutOfMemory -> -1L
422-
in (Memory.value_of_address (Memory.index_of mem) result) :: vs', []
440+
in (value_of_index (Memory.index_of mem) result) :: vs', []
423441

424442
| MemoryFill, Num n :: Num k :: Num i :: vs' ->
425443
let n_64 = Memory.address_of_num n in
@@ -709,7 +727,7 @@ let create_func (inst : module_inst) (f : func) : func_inst =
709727

710728
let create_table (inst : module_inst) (tab : table) : table_inst =
711729
let {ttype} = tab.it in
712-
let TableType (_lim, t) = ttype in
730+
let TableType (_lim, _it, t) = ttype in
713731
Table.alloc ttype (NullRef t)
714732

715733
let create_memory (inst : module_inst) (mem : memory) : memory_inst =

interpreter/host/spectest.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ let global (GlobalType (t, _) as gt) =
1919
in Global.alloc gt v
2020

2121
let table =
22-
Table.alloc (TableType ({min = 10l; max = Some 20l}, FuncRefType))
22+
Table.alloc (TableType ({min = 10L; max = Some 20L}, I32IndexType, FuncRefType))
23+
(NullRef FuncRefType)
24+
let table64 =
25+
Table.alloc (TableType ({min = 10L; max = Some 20L}, I64IndexType, FuncRefType))
2326
(NullRef FuncRefType)
2427
let memory = Memory.alloc (MemoryType ({min = 1L; max = Some 2L}, I32IndexType))
2528
let func f t = Func.alloc_host t (f t)
@@ -51,5 +54,6 @@ let lookup name t =
5154
| "global_f32", _ -> ExternGlobal (global (GlobalType (NumType F32Type, Immutable)))
5255
| "global_f64", _ -> ExternGlobal (global (GlobalType (NumType F64Type, Immutable)))
5356
| "table", _ -> ExternTable table
57+
| "table64", _ -> ExternTable table64
5458
| "memory", _ -> ExternMemory memory
5559
| _ -> raise Not_found

interpreter/runtime/elem.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ type t = elem
44
exception Bounds
55

66
let alloc rs = ref rs
7-
let size seg = Lib.List32.length !seg
7+
let size seg = Lib.List64.length !seg
88

99
let load seg i =
10-
if i < 0l || i >= Lib.List32.length !seg then raise Bounds;
11-
Lib.List32.nth !seg i
10+
if i < 0L || i >= Lib.List64.length !seg then raise Bounds;
11+
Lib.List64.nth !seg i
1212

1313
let drop seg = seg := []

interpreter/runtime/memory.ml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,6 @@ let type_of mem =
5050
let index_of mem =
5151
let (MemoryType (_, it)) = type_of mem in it
5252

53-
let value_of_address it x =
54-
match it with
55-
| I64IndexType -> Num (I64 x)
56-
| I32IndexType -> Num (I32 (Int64.to_int32 x))
57-
5853
let address_of_num x =
5954
match x with
6055
| I64 i -> i

interpreter/runtime/memory.mli

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ val type_of : memory -> memory_type
2222
val index_of : memory -> index_type
2323
val size : memory -> size
2424
val bound : memory -> address
25-
val value_of_address : index_type -> address -> value
2625
val address_of_value : value -> address
2726
val address_of_num : num -> address
2827
val grow : memory -> size -> unit

interpreter/runtime/table.ml

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
open Types
22
open Values
33

4-
type size = int32
5-
type index = int32
4+
type size = int64
5+
type index = int64
66
type count = int32
77

88
type table = {mutable ty : table_type; mutable content : ref_ array}
@@ -17,47 +17,62 @@ exception OutOfMemory
1717
let valid_limits {min; max} =
1818
match max with
1919
| None -> true
20-
| Some m -> I32.le_u min m
20+
| Some m -> I64.le_u min m
2121

22-
let create size r =
23-
try Lib.Array32.make size r
22+
let valid_index it i =
23+
match it with
24+
| I32IndexType -> I64.le_u i 0xffff_ffffL
25+
| I64IndexType -> true
26+
27+
let create size it r =
28+
try Lib.Array64.make size r
2429
with Out_of_memory | Invalid_argument _ -> raise OutOfMemory
2530

26-
let alloc (TableType (lim, _) as ty) r =
31+
let alloc (TableType (lim, it, _) as ty) r =
2732
if not (valid_limits lim) then raise Type;
28-
{ty; content = create lim.min r}
33+
{ty; content = create lim.min it r}
2934

3035
let size tab =
31-
Lib.Array32.length tab.content
36+
Lib.Array64.length tab.content
3237

3338
let type_of tab =
3439
tab.ty
3540

41+
let index_of tab =
42+
let (TableType (_, it, _)) = type_of tab in it
43+
44+
let index_of_num x =
45+
match x with
46+
| I64 i -> i
47+
| I32 i -> I64_convert.extend_i32_u i
48+
| _ -> raise Type
49+
3650
let grow tab delta r =
37-
let TableType (lim, t) = tab.ty in
51+
let TableType (lim, it, t) = tab.ty in
3852
assert (lim.min = size tab);
3953
let old_size = lim.min in
40-
let new_size = Int32.add old_size delta in
41-
if I32.gt_u old_size new_size then raise SizeOverflow else
54+
let new_size = Int64.add old_size delta in
55+
if I64.gt_u old_size new_size then raise SizeOverflow else
4256
let lim' = {lim with min = new_size} in
57+
if not (valid_index it new_size) then raise SizeOverflow else
4358
if not (valid_limits lim') then raise SizeLimit else
44-
let after = create new_size r in
59+
let after = create new_size it r in
4560
Array.blit tab.content 0 after 0 (Array.length tab.content);
46-
tab.ty <- TableType (lim', t);
61+
tab.ty <- TableType (lim', it, t);
4762
tab.content <- after
4863

4964
let load tab i =
50-
if i < 0l || i >= Lib.Array32.length tab.content then raise Bounds;
51-
Lib.Array32.get tab.content i
65+
if i < 0L || i >= Lib.Array64.length tab.content then raise Bounds;
66+
Lib.Array64.get tab.content i
5267

5368
let store tab i r =
54-
let TableType (lim, t) = tab.ty in
69+
let TableType (_lim, _it, t) = tab.ty in
5570
if type_of_ref r <> t then raise Type;
56-
if i < 0l || i >= Lib.Array32.length tab.content then raise Bounds;
57-
Lib.Array32.set tab.content i r
71+
if i < 0L || i >= Lib.Array64.length tab.content then raise Bounds;
72+
Lib.Array64.set tab.content i r
5873

5974
let blit tab offset rs =
6075
let data = Array.of_list rs in
61-
let len = Lib.Array32.length data in
62-
if offset < 0l || offset > Int32.sub (Lib.Array32.length tab.content) len then raise Bounds;
63-
Lib.Array32.blit data 0l tab.content offset len
76+
let len = Lib.Array64.length data in
77+
if offset < 0L || offset > Int64.sub (Lib.Array64.length tab.content) len then raise Bounds;
78+
Lib.Array64.blit data 0L tab.content offset len

0 commit comments

Comments
 (0)