@@ -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
@@ -164,6 +169,8 @@ module Write = struct
164
169
165
170
let heaptype st ch typ =
166
171
match (typ : heaptype ) with
172
+ | Nocont -> byte ch 0x75
173
+ | Noexn -> byte ch 0x74
167
174
| Nofunc -> byte ch 0x73
168
175
| Noextern -> byte ch 0x72
169
176
| None_ -> byte ch 0x71
@@ -174,6 +181,8 @@ module Write = struct
174
181
| I31 -> byte ch 0x6C
175
182
| Struct -> byte ch 0x6B
176
183
| Array -> byte ch 0x6A
184
+ | Exn -> byte ch 0x69
185
+ | Cont -> byte ch 0x68
177
186
| Type idx -> sint ch (typeidx st idx)
178
187
179
188
let reftype st ch { nullable; typ } =
@@ -219,6 +228,9 @@ module Write = struct
219
228
byte ch 1 ;
220
229
uint ch (typeidx st supertype));
221
230
match typ with
231
+ | Cont idx ->
232
+ byte ch 0x5D ;
233
+ sint ch (typeidx st idx)
222
234
| Array field_type ->
223
235
byte ch 0x5E ;
224
236
fieldtype st ch field_type
@@ -571,7 +583,9 @@ module Read = struct
571
583
let heaptype st ch =
572
584
let i = sint ch in
573
585
match i + 128 with
574
- | 0X73 -> Nofunc
586
+ | 0x75 -> Nocont
587
+ | 0x74 -> Noexn
588
+ | 0x73 -> Nofunc
575
589
| 0x72 -> Noextern
576
590
| 0x71 -> None_
577
591
| 0x70 -> Func
@@ -581,6 +595,8 @@ module Read = struct
581
595
| 0x6C -> I31
582
596
| 0x6B -> Struct
583
597
| 0x6A -> Array
598
+ | 0x69 -> Exn
599
+ | 0x68 -> Cont
584
600
| _ ->
585
601
if i < 0 then failwith (Printf. sprintf " Unknown heaptype %x@." i);
586
602
let i =
@@ -598,7 +614,9 @@ module Read = struct
598
614
599
615
let reftype' st i ch =
600
616
match i with
601
- | 0X73 -> nullable Nofunc
617
+ | 0x75 -> nullable Nocont
618
+ | 0x74 -> nullable Noexn
619
+ | 0x73 -> nullable Nofunc
602
620
| 0x72 -> nullable Noextern
603
621
| 0x71 -> nullable None_
604
622
| 0x70 -> nullable Func
@@ -608,6 +626,8 @@ module Read = struct
608
626
| 0x6C -> nullable I31
609
627
| 0x6B -> nullable Struct
610
628
| 0x6A -> nullable Array
629
+ | 0x69 -> nullable Exn
630
+ | 0x68 -> nullable Cont
611
631
| 0x63 -> nullable (heaptype st ch)
612
632
| 0x64 -> { nullable = false ; typ = heaptype st ch }
613
633
| _ -> failwith (Printf. sprintf " Unknown reftype %x@." i)
@@ -654,6 +674,14 @@ module Read = struct
654
674
655
675
let comptype st i ch =
656
676
match i with
677
+ | 0x5D ->
678
+ let i = sint ch in
679
+ let i =
680
+ if i > = st.type_index_count
681
+ then lnot (i - st.type_index_count)
682
+ else st.type_mapping.(i)
683
+ in
684
+ Cont i
657
685
| 0x5E -> Array (fieldtype st ch)
658
686
| 0x5F -> Struct (vec (fieldtype st) ch)
659
687
| 0x60 ->
@@ -1260,6 +1288,13 @@ module Scan = struct
1260
1288
| 0xD1 (* ref .is_null * ) | 0xD3 (* ref .eq * ) | 0xD4 (* ref.as_non_null *) ->
1261
1289
pos + 1 |> instructions
1262
1290
| 0xD2 (* ref .func * ) -> pos + 1 |> funcidx |> instructions
1291
+ | 0xE0 (* cont .new * ) -> pos + 1 |> typeidx |> instructions
1292
+ | 0xE1 (* cont .bind * ) -> pos + 1 |> typeidx |> typeidx |> instructions
1293
+ | 0xE2 (* suspend * ) -> pos + 1 |> tagidx |> instructions
1294
+ | 0xE3 (* resume * ) -> pos + 1 |> typeidx |> vector on_clause |> instructions
1295
+ | 0xE4 (* resume_throw *) ->
1296
+ pos + 1 |> typeidx |> tagidx |> vector on_clause |> instructions
1297
+ | 0xE5 (* switch * ) -> pos + 1 |> typeidx |> tagidx |> instructions
1263
1298
| 0xFB -> pos + 1 |> gc_instruction
1264
1299
| 0xFC -> (
1265
1300
if debug then Format. eprintf " %d@." (get (pos + 1 ));
@@ -1394,6 +1429,11 @@ module Scan = struct
1394
1429
| 0 (* catch * ) | 1 (* catch_ref * ) -> pos + 1 |> tagidx |> labelidx
1395
1430
| 2 (* catch_all * ) | 3 (* catch_all_ref * ) -> pos + 1 |> labelidx
1396
1431
| c -> failwith (Printf. sprintf " bad catch 0x02%d@." c)
1432
+ and on_clause pos =
1433
+ match get pos with
1434
+ | 0 (* on * ) -> pos + 1 |> tagidx |> labelidx
1435
+ | 1 (* on .. switch * ) -> pos + 1 |> tagidx
1436
+ | c -> failwith (Printf. sprintf " bad on clause 0x02%d@." c)
1397
1437
and block_end pos =
1398
1438
if debug then Format. eprintf " 0x%02X (@%d) block end@." (get pos) pos;
1399
1439
match get pos with
@@ -1546,30 +1586,43 @@ let rec subtype subtyping_info (i : int) i' =
1546
1586
| None -> false
1547
1587
| Some s -> subtype subtyping_info s i'
1548
1588
1549
- let heap_subtype (subtyping_info : subtype array ) (ty : heaptype ) (ty' : heaptype ) =
1589
+ let rec heap_subtype (subtyping_info : subtype array ) (ty : heaptype ) (ty' : heaptype ) =
1550
1590
match ty, ty' with
1551
- | (Func | Nofunc ), Func
1552
- | Nofunc , Nofunc
1553
- | (Extern | Noextern ), Extern
1591
+ | Func , Func
1592
+ | Extern , Extern
1593
+ | Noextern , Noextern
1594
+ | Exn , Exn
1595
+ | Noexn , Noexn
1596
+ | Cont , Cont
1597
+ | Nocont , Nocont
1554
1598
| (Any | Eq | I31 | Struct | Array | None_ | Type _), Any
1555
1599
| (Eq | I31 | Struct | Array | None_ | Type _), Eq
1556
- | ( I31 | None_ ) , I31
1557
- | ( Struct | None_ ) , Struct
1558
- | ( Array | None_ ) , Array
1600
+ | I31 , I31
1601
+ | Struct , Struct
1602
+ | Array , Array
1559
1603
| None_ , None_ -> true
1560
1604
| Type i , Struct -> (
1561
1605
match subtyping_info.(i).typ with
1562
1606
| Struct _ -> true
1563
- | Array _ | Func _ -> false )
1607
+ | Array _ | Func _ | Cont _ -> false )
1564
1608
| Type i , Array -> (
1565
1609
match subtyping_info.(i).typ with
1566
1610
| Array _ -> true
1567
- | Struct _ | Func _ -> false )
1611
+ | Struct _ | Func _ | Cont _ -> false )
1568
1612
| Type i , Func -> (
1569
1613
match subtyping_info.(i).typ with
1570
1614
| Func _ -> true
1571
- | Struct _ | Array _ -> false )
1615
+ | Struct _ | Array _ | Cont _ -> false )
1616
+ | Type i , Cont -> (
1617
+ match subtyping_info.(i).typ with
1618
+ | Cont _ -> true
1619
+ | Struct _ | Array _ | Func _ -> false )
1572
1620
| Type i , Type i' -> subtype subtyping_info i i'
1621
+ | Nofunc , _ -> heap_subtype subtyping_info ty' Func
1622
+ | Noextern , _ -> heap_subtype subtyping_info ty' Extern
1623
+ | Noexn , _ -> heap_subtype subtyping_info ty' Exn
1624
+ | Nocont , _ -> heap_subtype subtyping_info ty' Cont
1625
+ | None_ , _ -> heap_subtype subtyping_info ty' Any
1573
1626
| _ -> false
1574
1627
1575
1628
let ref_subtype subtyping_info { nullable; typ } { nullable = nullable' ; typ = typ' } =
@@ -2457,7 +2510,6 @@ let f ?(filter_export = fun _ -> true) files ~output_file =
2457
2510
(*
2458
2511
LATER
2459
2512
- testsuite : import/export matching, source maps, multiple start functions, ...
2460
- - missing instructions ==> typed continuations (?)
2461
2513
- check features?
2462
2514
2463
2515
MAYBE
0 commit comments