@@ -23,6 +23,10 @@ type heaptype =
23
23
| Nofunc
24
24
| Extern
25
25
| Noextern
26
+ | Exn
27
+ | Noexn
28
+ | Cont
29
+ | Nocont
26
30
| Any
27
31
| Eq
28
32
| I31
@@ -66,6 +70,7 @@ type comptype =
66
70
}
67
71
| Struct of fieldtype array
68
72
| Array of fieldtype
73
+ | Cont of int
69
74
70
75
type subtype =
71
76
{ final : bool
@@ -147,6 +152,8 @@ module Write = struct
147
152
148
153
let heaptype st ch typ =
149
154
match (typ : heaptype ) with
155
+ | Nocont -> byte ch 0x75
156
+ | Noexn -> byte ch 0x74
150
157
| Nofunc -> byte ch 0x73
151
158
| Noextern -> byte ch 0x72
152
159
| None_ -> byte ch 0x71
@@ -157,6 +164,8 @@ module Write = struct
157
164
| I31 -> byte ch 0x6C
158
165
| Struct -> byte ch 0x6B
159
166
| Array -> byte ch 0x6A
167
+ | Exn -> byte ch 0x69
168
+ | Cont -> byte ch 0x68
160
169
| Type idx -> sint ch (typeidx st idx)
161
170
162
171
let reftype st ch { nullable; typ } =
@@ -202,6 +211,9 @@ module Write = struct
202
211
byte ch 1 ;
203
212
uint ch (typeidx st supertype));
204
213
match typ with
214
+ | Cont idx ->
215
+ byte ch 0x5D ;
216
+ sint ch (typeidx st idx)
205
217
| Array field_type ->
206
218
byte ch 0x5E ;
207
219
fieldtype st ch field_type
@@ -569,7 +581,9 @@ module Read = struct
569
581
let heaptype st ch =
570
582
let i = sint ch in
571
583
match i + 128 with
572
- | 0X73 -> Nofunc
584
+ | 0x75 -> Nocont
585
+ | 0x74 -> Noexn
586
+ | 0x73 -> Nofunc
573
587
| 0x72 -> Noextern
574
588
| 0x71 -> None_
575
589
| 0x70 -> Func
@@ -579,6 +593,8 @@ module Read = struct
579
593
| 0x6C -> I31
580
594
| 0x6B -> Struct
581
595
| 0x6A -> Array
596
+ | 0x69 -> Exn
597
+ | 0x68 -> Cont
582
598
| _ ->
583
599
if i < 0 then failwith (Printf. sprintf " Unknown heaptype %x@." i);
584
600
let i =
@@ -596,7 +612,9 @@ module Read = struct
596
612
597
613
let reftype' st i ch =
598
614
match i with
599
- | 0X73 -> nullable Nofunc
615
+ | 0x75 -> nullable Nocont
616
+ | 0x74 -> nullable Noexn
617
+ | 0x73 -> nullable Nofunc
600
618
| 0x72 -> nullable Noextern
601
619
| 0x71 -> nullable None_
602
620
| 0x70 -> nullable Func
@@ -606,6 +624,8 @@ module Read = struct
606
624
| 0x6C -> nullable I31
607
625
| 0x6B -> nullable Struct
608
626
| 0x6A -> nullable Array
627
+ | 0x69 -> nullable Exn
628
+ | 0x68 -> nullable Cont
609
629
| 0x63 -> nullable (heaptype st ch)
610
630
| 0x64 -> { nullable = false ; typ = heaptype st ch }
611
631
| _ -> failwith (Printf. sprintf " Unknown reftype %x@." i)
@@ -652,6 +672,14 @@ module Read = struct
652
672
653
673
let comptype st i ch =
654
674
match i with
675
+ | 0x5D ->
676
+ let i = sint ch in
677
+ let i =
678
+ if i > = st.type_index_count
679
+ then lnot (i - st.type_index_count)
680
+ else st.type_mapping.(i)
681
+ in
682
+ Cont i
655
683
| 0x5E -> Array (fieldtype st ch)
656
684
| 0x5F -> Struct (vec (fieldtype st) ch)
657
685
| 0x60 ->
@@ -1252,6 +1280,13 @@ module Scan = struct
1252
1280
| 0xD1 (* ref .is_null * ) | 0xD3 (* ref .eq * ) | 0xD4 (* ref.as_non_null *) ->
1253
1281
pos + 1 |> instructions
1254
1282
| 0xD2 (* ref .func * ) -> pos + 1 |> funcidx |> instructions
1283
+ | 0xE0 (* cont .new * ) -> pos + 1 |> typeidx |> instructions
1284
+ | 0xE1 (* cont .bind * ) -> pos + 1 |> typeidx |> typeidx |> instructions
1285
+ | 0xE2 (* suspend * ) -> pos + 1 |> tagidx |> instructions
1286
+ | 0xE3 (* resume * ) -> pos + 1 |> typeidx |> vector on_clause |> instructions
1287
+ | 0xE4 (* resume_throw *) ->
1288
+ pos + 1 |> typeidx |> tagidx |> vector on_clause |> instructions
1289
+ | 0xE5 (* switch * ) -> pos + 1 |> typeidx |> tagidx |> instructions
1255
1290
| 0xFB -> pos + 1 |> gc_instruction
1256
1291
| 0xFC -> (
1257
1292
if debug then Format. eprintf " %d@." (get (pos + 1 ));
@@ -1386,6 +1421,11 @@ module Scan = struct
1386
1421
| 0 (* catch * ) | 1 (* catch_ref * ) -> pos + 1 |> tagidx |> labelidx
1387
1422
| 2 (* catch_all * ) | 3 (* catch_all_ref * ) -> pos + 1 |> labelidx
1388
1423
| c -> failwith (Printf. sprintf " bad catch 0x02%d@." c)
1424
+ and on_clause pos =
1425
+ match get pos with
1426
+ | 0 (* on * ) -> pos + 1 |> tagidx |> labelidx
1427
+ | 1 (* on .. switch * ) -> pos + 1 |> tagidx
1428
+ | c -> failwith (Printf. sprintf " bad on clause 0x02%d@." c)
1389
1429
and block_end pos =
1390
1430
if debug then Format. eprintf " 0x%02X (@%d) block end@." (get pos) pos;
1391
1431
match get pos with
@@ -1538,30 +1578,43 @@ let rec subtype subtyping_info (i : int) i' =
1538
1578
| None -> false
1539
1579
| Some s -> subtype subtyping_info s i'
1540
1580
1541
- let heap_subtype (subtyping_info : subtype array ) (ty : heaptype ) (ty' : heaptype ) =
1581
+ let rec heap_subtype (subtyping_info : subtype array ) (ty : heaptype ) (ty' : heaptype ) =
1542
1582
match ty, ty' with
1543
- | (Func | Nofunc ), Func
1544
- | Nofunc , Nofunc
1545
- | (Extern | Noextern ), Extern
1583
+ | Func , Func
1584
+ | Extern , Extern
1585
+ | Noextern , Noextern
1586
+ | Exn , Exn
1587
+ | Noexn , Noexn
1588
+ | Cont , Cont
1589
+ | Nocont , Nocont
1546
1590
| (Any | Eq | I31 | Struct | Array | None_ | Type _), Any
1547
1591
| (Eq | I31 | Struct | Array | None_ | Type _), Eq
1548
- | ( I31 | None_ ) , I31
1549
- | ( Struct | None_ ) , Struct
1550
- | ( Array | None_ ) , Array
1592
+ | I31 , I31
1593
+ | Struct , Struct
1594
+ | Array , Array
1551
1595
| None_ , None_ -> true
1552
1596
| Type i , Struct -> (
1553
1597
match subtyping_info.(i).typ with
1554
1598
| Struct _ -> true
1555
- | Array _ | Func _ -> false )
1599
+ | Array _ | Func _ | Cont _ -> false )
1556
1600
| Type i , Array -> (
1557
1601
match subtyping_info.(i).typ with
1558
1602
| Array _ -> true
1559
- | Struct _ | Func _ -> false )
1603
+ | Struct _ | Func _ | Cont _ -> false )
1560
1604
| Type i , Func -> (
1561
1605
match subtyping_info.(i).typ with
1562
1606
| Func _ -> true
1563
- | Struct _ | Array _ -> false )
1607
+ | Struct _ | Array _ | Cont _ -> false )
1608
+ | Type i , Cont -> (
1609
+ match subtyping_info.(i).typ with
1610
+ | Cont _ -> true
1611
+ | Struct _ | Array _ | Func _ -> false )
1564
1612
| Type i , Type i' -> subtype subtyping_info i i'
1613
+ | Nofunc , _ -> heap_subtype subtyping_info ty' Func
1614
+ | Noextern , _ -> heap_subtype subtyping_info ty' Extern
1615
+ | Noexn , _ -> heap_subtype subtyping_info ty' Exn
1616
+ | Nocont , _ -> heap_subtype subtyping_info ty' Cont
1617
+ | None_ , _ -> heap_subtype subtyping_info ty' Any
1565
1618
| _ -> false
1566
1619
1567
1620
let ref_subtype subtyping_info { nullable; typ } { nullable = nullable' ; typ = typ' } =
@@ -2449,7 +2502,6 @@ let f ?(filter_export = fun _ -> true) files ~output_file =
2449
2502
(*
2450
2503
LATER
2451
2504
- testsuite : import/export matching, source maps, multiple start functions, ...
2452
- - missing instructions ==> typed continuations (?)
2453
2505
- check features?
2454
2506
2455
2507
MAYBE
0 commit comments