Skip to content

Commit b86490c

Browse files
authored
Merge pull request #84 from WebAssembly/wasmfx
Reference interpreter for stack-switching
2 parents a929dc4 + c768f15 commit b86490c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2888
-446
lines changed

.github/workflows/ci-interpreter.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ jobs:
3333
- name: Run tests
3434
# TODO: reactiate node once it supports all of Wasm 3.0
3535
# run: cd interpreter && opam exec make JS=node ci
36-
run: cd interpreter && opam exec make ci
36+
run: cd interpreter && opam exec make test

interpreter/binary/decode.ml

+50-8
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ let heap_type s =
180180
(fun s -> VarHT (var_type s33 s));
181181
(fun s ->
182182
match s7 s with
183+
| -0x0b -> NoContHT
183184
| -0x0c -> NoExnHT
184185
| -0x0d -> NoFuncHT
185186
| -0x0e -> NoExternHT
@@ -192,13 +193,15 @@ let heap_type s =
192193
| -0x15 -> StructHT
193194
| -0x16 -> ArrayHT
194195
| -0x17 -> ExnHT
196+
| -0x18 -> ContHT
195197
| _ -> error s pos "malformed heap type"
196198
)
197199
] s
198200

199201
let ref_type s =
200202
let pos = pos s in
201203
match s7 s with
204+
| -0x0b -> (Null, NoContHT)
202205
| -0x0c -> (Null, NoExnHT)
203206
| -0x0d -> (Null, NoFuncHT)
204207
| -0x0e -> (Null, NoExternHT)
@@ -211,6 +214,7 @@ let ref_type s =
211214
| -0x15 -> (Null, StructHT)
212215
| -0x16 -> (Null, ArrayHT)
213216
| -0x17 -> (Null, ExnHT)
217+
| -0x18 -> (Null, ContHT)
214218
| -0x1c -> (NoNull, heap_type s)
215219
| -0x1d -> (Null, heap_type s)
216220
| _ -> error s pos "malformed reference type"
@@ -253,11 +257,15 @@ let func_type s =
253257
let ts2 = result_type s in
254258
FuncT (ts1, ts2)
255259

260+
let cont_type s =
261+
ContT (heap_type s)
262+
256263
let str_type s =
257264
match s7 s with
258265
| -0x20 -> DefFuncT (func_type s)
259266
| -0x21 -> DefStructT (struct_type s)
260267
| -0x22 -> DefArrayT (array_type s)
268+
| -0x23 -> DefContT (cont_type s) (* TODO(dhil): See comment in encode.ml *)
261269
| _ -> error s (pos s - 1) "malformed definition type"
262270

263271
let sub_type s =
@@ -293,14 +301,15 @@ let memory_type s =
293301
let lim = limits u32 s in
294302
MemoryT lim
295303

304+
let tag_type s =
305+
zero s;
306+
at var s
307+
296308
let global_type s =
297309
let t = val_type s in
298310
let mut = mutability s in
299311
GlobalT (mut, t)
300312

301-
let tag_type s =
302-
zero s; at var s
303-
304313

305314
(* Instructions *)
306315

@@ -340,6 +349,16 @@ let locals s =
340349
s pos "too many locals";
341350
List.flatten (List.map (Lib.Fun.uncurry Lib.List32.make) nts)
342351

352+
let on_clause s =
353+
match byte s with
354+
| 0x00 ->
355+
let x = at var s in
356+
let y = at var s in
357+
(x, OnLabel y)
358+
| 0x01 ->
359+
let x = at var s in
360+
(x, OnSwitch)
361+
| _ -> error s (pos s) "ON opcode expected"
343362

344363
let rec instr s =
345364
let pos = pos s in
@@ -399,7 +418,10 @@ let rec instr s =
399418
| 0x14 -> call_ref (at var s)
400419
| 0x15 -> return_call_ref (at var s)
401420

402-
| 0x16 | 0x17 | 0x18 | 0x19 as b -> illegal s pos b
421+
| (0x16 | 0x17) as b -> illegal s pos b
422+
423+
| 0x18 -> error s pos "misplaced DELEGATE opcode"
424+
| 0x19 -> error s pos "misplaced CATCH_ALL opcode"
403425

404426
| 0x1a -> drop
405427
| 0x1b -> select None
@@ -607,6 +629,26 @@ let rec instr s =
607629
| 0xd5 -> br_on_null (at var s)
608630
| 0xd6 -> br_on_non_null (at var s)
609631

632+
| 0xe0 -> cont_new (at var s)
633+
| 0xe1 ->
634+
let x = at var s in
635+
let y = at var s in
636+
cont_bind x y
637+
| 0xe2 -> suspend (at var s)
638+
| 0xe3 ->
639+
let x = at var s in
640+
let xls = vec on_clause s in
641+
resume x xls
642+
| 0xe4 ->
643+
let x = at var s in
644+
let tag = at var s in
645+
let xls = vec on_clause s in
646+
resume_throw x tag xls
647+
| 0xe5 ->
648+
let x = at var s in
649+
let y = at var s in
650+
switch x y
651+
610652
| 0xfb as b ->
611653
(match u32 s with
612654
| 0x00l -> struct_new (at var s)
@@ -971,11 +1013,11 @@ let rec instr s =
9711013
and instr_block s = List.rev (instr_block' s [])
9721014
and instr_block' s es =
9731015
match peek s with
974-
| None | Some (0x05 | 0x0b) -> es
1016+
| None | Some (0x05 | 0x07 | 0x0b | 0x19) -> es
9751017
| _ ->
9761018
let pos = pos s in
9771019
let e' = instr s in
978-
instr_block' s ((e' @@ region s pos pos) :: es)
1020+
instr_block' s (Source.(e' @@ region s pos pos) :: es)
9791021

9801022
and catch s =
9811023
match byte s with
@@ -1045,7 +1087,7 @@ let import_desc s =
10451087
| 0x01 -> TableImport (table_type s)
10461088
| 0x02 -> MemoryImport (memory_type s)
10471089
| 0x03 -> GlobalImport (global_type s)
1048-
| 0x04 -> TagImport (tag_type s)
1090+
| 0x04 -> TagImport (at var s)
10491091
| _ -> error s (pos s - 1) "malformed import kind"
10501092

10511093
let import s =
@@ -1106,6 +1148,7 @@ let tag_section s =
11061148
section Custom.Tag (vec (at tag)) [] s
11071149

11081150

1151+
11091152
(* Global section *)
11101153

11111154
let global s =
@@ -1336,7 +1379,6 @@ let module_ s =
13361379
imports; exports; elems; datas; start },
13371380
customs
13381381

1339-
13401382
let decode_custom m bs custom =
13411383
let open Source in
13421384
let Custom.{name; content; place} = custom.it in

interpreter/binary/encode.ml

+36-12
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ struct
130130
| NoExnHT -> s7 (-0x0c)
131131
| ExternHT -> s7 (-0x11)
132132
| NoExternHT -> s7 (-0x0e)
133+
| ContHT -> s7 (-0x18)
134+
| NoContHT -> s7 (-0x0b)
133135
| VarHT x -> var_type s33 x
134136
| DefHT _ | BotHT -> assert false
135137

@@ -150,6 +152,8 @@ struct
150152
| (Null, NoExnHT) -> s7 (-0x0c)
151153
| (Null, ExternHT) -> s7 (-0x11)
152154
| (Null, NoExternHT) -> s7 (-0x0e)
155+
| (Null, ContHT) -> s7 (-0x18)
156+
| (Null, NoContHT) -> s7 (-0x0b)
153157
| (Null, t) -> s7 (-0x1d); heap_type t
154158
| (NoNull, t) -> s7 (-0x1c); heap_type t
155159

@@ -180,10 +184,17 @@ struct
180184
let func_type = function
181185
| FuncT (ts1, ts2) -> vec val_type ts1; vec val_type ts2
182186

187+
let cont_type = function
188+
| ContT ht -> heap_type ht
189+
183190
let str_type = function
184191
| DefStructT st -> s7 (-0x21); struct_type st
185192
| DefArrayT at -> s7 (-0x22); array_type at
186193
| DefFuncT ft -> s7 (-0x20); func_type ft
194+
| DefContT ct -> s7 (-0x23); cont_type ct
195+
(* TODO(dhil): This might need to change again in the future as a
196+
different proposal might claim this opcode! GC proposal claimed
197+
the previous opcode we were using. *)
187198

188199
let sub_type = function
189200
| SubT (Final, [], st) -> str_type st
@@ -206,9 +217,7 @@ struct
206217
let global_type = function
207218
| GlobalT (mut, t) -> val_type t; mutability mut
208219

209-
let tag_type x =
210-
u32 0x00l; var x
211-
220+
let tag_type x = u32 0x00l; var x
212221

213222
(* Expressions *)
214223

@@ -245,6 +254,16 @@ struct
245254
| nlocs -> (1, loc) :: nlocs
246255
in vec local (List.fold_right combine locs [])
247256

257+
let on_clause (x, y) =
258+
match y with
259+
| OnSwitch ->
260+
byte 0x01; var x
261+
| OnLabel y ->
262+
byte 0x00; var x; var y
263+
264+
let resumetable xls =
265+
vec on_clause xls
266+
248267
let rec instr e =
249268
match e.it with
250269
| Unreachable -> op 0x00
@@ -278,6 +297,13 @@ struct
278297
| ReturnCallRef x -> op 0x15; var x
279298
| ReturnCallIndirect (x, y) -> op 0x13; var y; var x
280299

300+
| ContNew x -> op 0xe0; var x
301+
| ContBind (x, y) -> op 0xe1; var x; var y
302+
| Suspend x -> op 0xe2; var x
303+
| Resume (x, xls) -> op 0xe3; var x; resumetable xls
304+
| ResumeThrow (x, y, xls) -> op 0xe4; var x; var y; resumetable xls
305+
| Switch (x, y) -> op 0xe5; var x; var y
306+
281307
| Throw x -> op 0x08; var x
282308
| ThrowRef -> op 0x0a
283309

@@ -925,7 +951,7 @@ struct
925951
| TableImport t -> byte 0x01; table_type t
926952
| MemoryImport t -> byte 0x02; memory_type t
927953
| GlobalImport t -> byte 0x03; global_type t
928-
| TagImport t -> byte 0x04; tag_type t
954+
| TagImport t -> byte 0x04; var t
929955

930956
let import im =
931957
let {module_name; item_name; idesc} = im.it in
@@ -966,14 +992,6 @@ struct
966992
section 5 (vec memory) mems (mems <> [])
967993

968994

969-
(* Tag section *)
970-
971-
let tag (t : tag) = byte 0x00; var t.it.tgtype
972-
973-
let tag_section ts =
974-
section 13 (vec tag) ts (ts <> [])
975-
976-
977995
(* Global section *)
978996

979997
let global g =
@@ -983,6 +1001,12 @@ struct
9831001
let global_section gs =
9841002
section 6 (vec global) gs (gs <> [])
9851003

1004+
(* Tag section *)
1005+
let tag tag =
1006+
tag_type tag.it.tgtype
1007+
1008+
let tag_section ts =
1009+
section 13 (vec tag) ts (ts <> [])
9861010

9871011
(* Export section *)
9881012

0 commit comments

Comments
 (0)