@@ -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
@@ -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 ->
@@ -1258,6 +1286,13 @@ module Scan = struct
1258
1286
| 0xD1 (* ref .is_null * ) | 0xD3 (* ref .eq * ) | 0xD4 (* ref.as_non_null *) ->
1259
1287
pos + 1 |> instructions
1260
1288
| 0xD2 (* ref .func * ) -> pos + 1 |> funcidx |> instructions
1289
+ | 0xE0 (* cont .new * ) -> pos + 1 |> typeidx |> instructions
1290
+ | 0xE1 (* cont .bind * ) -> pos + 1 |> typeidx |> typeidx |> instructions
1291
+ | 0xE2 (* suspend * ) -> pos + 1 |> tagidx |> instructions
1292
+ | 0xE3 (* resume * ) -> pos + 1 |> typeidx |> vector on_clause |> instructions
1293
+ | 0xE4 (* resume_throw *) ->
1294
+ pos + 1 |> typeidx |> tagidx |> vector on_clause |> instructions
1295
+ | 0xE5 (* switch * ) -> pos + 1 |> typeidx |> tagidx |> instructions
1261
1296
| 0xFB -> pos + 1 |> gc_instruction
1262
1297
| 0xFC -> (
1263
1298
if debug then Format. eprintf " %d@." (get (pos + 1 ));
@@ -1392,6 +1427,11 @@ module Scan = struct
1392
1427
| 0 (* catch * ) | 1 (* catch_ref * ) -> pos + 1 |> tagidx |> labelidx
1393
1428
| 2 (* catch_all * ) | 3 (* catch_all_ref * ) -> pos + 1 |> labelidx
1394
1429
| c -> failwith (Printf. sprintf " bad catch 0x02%d@." c)
1430
+ and on_clause pos =
1431
+ match get pos with
1432
+ | 0 (* on * ) -> pos + 1 |> tagidx |> labelidx
1433
+ | 1 (* on .. switch * ) -> pos + 1 |> tagidx
1434
+ | c -> failwith (Printf. sprintf " bad on clause 0x02%d@." c)
1395
1435
and block_end pos =
1396
1436
if debug then Format. eprintf " 0x%02X (@%d) block end@." (get pos) pos;
1397
1437
match get pos with
@@ -1544,30 +1584,43 @@ let rec subtype subtyping_info (i : int) i' =
1544
1584
| None -> false
1545
1585
| Some s -> subtype subtyping_info s i'
1546
1586
1547
- let heap_subtype (subtyping_info : subtype array ) (ty : heaptype ) (ty' : heaptype ) =
1587
+ let rec heap_subtype (subtyping_info : subtype array ) (ty : heaptype ) (ty' : heaptype ) =
1548
1588
match ty, ty' with
1549
- | (Func | Nofunc ), Func
1550
- | Nofunc , Nofunc
1551
- | (Extern | Noextern ), Extern
1589
+ | Func , Func
1590
+ | Extern , Extern
1591
+ | Noextern , Noextern
1592
+ | Exn , Exn
1593
+ | Noexn , Noexn
1594
+ | Cont , Cont
1595
+ | Nocont , Nocont
1552
1596
| (Any | Eq | I31 | Struct | Array | None_ | Type _), Any
1553
1597
| (Eq | I31 | Struct | Array | None_ | Type _), Eq
1554
- | ( I31 | None_ ) , I31
1555
- | ( Struct | None_ ) , Struct
1556
- | ( Array | None_ ) , Array
1598
+ | I31 , I31
1599
+ | Struct , Struct
1600
+ | Array , Array
1557
1601
| None_ , None_ -> true
1558
1602
| Type i , Struct -> (
1559
1603
match subtyping_info.(i).typ with
1560
1604
| Struct _ -> true
1561
- | Array _ | Func _ -> false )
1605
+ | Array _ | Func _ | Cont _ -> false )
1562
1606
| Type i , Array -> (
1563
1607
match subtyping_info.(i).typ with
1564
1608
| Array _ -> true
1565
- | Struct _ | Func _ -> false )
1609
+ | Struct _ | Func _ | Cont _ -> false )
1566
1610
| Type i , Func -> (
1567
1611
match subtyping_info.(i).typ with
1568
1612
| Func _ -> true
1569
- | Struct _ | Array _ -> false )
1613
+ | Struct _ | Array _ | Cont _ -> false )
1614
+ | Type i , Cont -> (
1615
+ match subtyping_info.(i).typ with
1616
+ | Cont _ -> true
1617
+ | Struct _ | Array _ | Func _ -> false )
1570
1618
| Type i , Type i' -> subtype subtyping_info i i'
1619
+ | Nofunc , _ -> heap_subtype subtyping_info ty' Func
1620
+ | Noextern , _ -> heap_subtype subtyping_info ty' Extern
1621
+ | Noexn , _ -> heap_subtype subtyping_info ty' Exn
1622
+ | Nocont , _ -> heap_subtype subtyping_info ty' Cont
1623
+ | None_ , _ -> heap_subtype subtyping_info ty' Any
1571
1624
| _ -> false
1572
1625
1573
1626
let ref_subtype subtyping_info { nullable; typ } { nullable = nullable' ; typ = typ' } =
@@ -2455,7 +2508,6 @@ let f ?(filter_export = fun _ -> true) files ~output_file =
2455
2508
(*
2456
2509
LATER
2457
2510
- testsuite : import/export matching, source maps, multiple start functions, ...
2458
- - missing instructions ==> typed continuations (?)
2459
2511
- check features?
2460
2512
2461
2513
MAYBE
0 commit comments