@@ -23,6 +23,10 @@ type heaptype =
2323 | Nofunc
2424 | Extern
2525 | Noextern
26+ | Exn
27+ | Noexn
28+ | Cont
29+ | Nocont
2630 | Any
2731 | Eq
2832 | I31
@@ -66,6 +70,7 @@ type comptype =
6670 }
6771 | Struct of fieldtype array
6872 | Array of fieldtype
73+ | Cont of int
6974
7075type subtype =
7176 { final : bool
@@ -147,6 +152,8 @@ module Write = struct
147152
148153 let heaptype st ch typ =
149154 match (typ : heaptype ) with
155+ | Nocont -> byte ch 0x75
156+ | Noexn -> byte ch 0x74
150157 | Nofunc -> byte ch 0x73
151158 | Noextern -> byte ch 0x72
152159 | None_ -> byte ch 0x71
@@ -157,6 +164,8 @@ module Write = struct
157164 | I31 -> byte ch 0x6C
158165 | Struct -> byte ch 0x6B
159166 | Array -> byte ch 0x6A
167+ | Exn -> byte ch 0x69
168+ | Cont -> byte ch 0x68
160169 | Type idx -> sint ch (typeidx st idx)
161170
162171 let reftype st ch { nullable; typ } =
@@ -202,6 +211,9 @@ module Write = struct
202211 byte ch 1 ;
203212 uint ch (typeidx st supertype));
204213 match typ with
214+ | Cont idx ->
215+ byte ch 0x5D ;
216+ sint ch (typeidx st idx)
205217 | Array field_type ->
206218 byte ch 0x5E ;
207219 fieldtype st ch field_type
@@ -569,7 +581,9 @@ module Read = struct
569581 let heaptype st ch =
570582 let i = sint ch in
571583 match i + 128 with
572- | 0X73 -> Nofunc
584+ | 0x75 -> Nocont
585+ | 0x74 -> Noexn
586+ | 0x73 -> Nofunc
573587 | 0x72 -> Noextern
574588 | 0x71 -> None_
575589 | 0x70 -> Func
@@ -579,6 +593,8 @@ module Read = struct
579593 | 0x6C -> I31
580594 | 0x6B -> Struct
581595 | 0x6A -> Array
596+ | 0x69 -> Exn
597+ | 0x68 -> Cont
582598 | _ ->
583599 if i < 0 then failwith (Printf. sprintf " Unknown heaptype %x@." i);
584600 let i =
@@ -596,7 +612,9 @@ module Read = struct
596612
597613 let reftype' st i ch =
598614 match i with
599- | 0X73 -> nullable Nofunc
615+ | 0x75 -> nullable Nocont
616+ | 0x74 -> nullable Noexn
617+ | 0x73 -> nullable Nofunc
600618 | 0x72 -> nullable Noextern
601619 | 0x71 -> nullable None_
602620 | 0x70 -> nullable Func
@@ -606,6 +624,8 @@ module Read = struct
606624 | 0x6C -> nullable I31
607625 | 0x6B -> nullable Struct
608626 | 0x6A -> nullable Array
627+ | 0x69 -> nullable Exn
628+ | 0x68 -> nullable Cont
609629 | 0x63 -> nullable (heaptype st ch)
610630 | 0x64 -> { nullable = false ; typ = heaptype st ch }
611631 | _ -> failwith (Printf. sprintf " Unknown reftype %x@." i)
@@ -652,6 +672,14 @@ module Read = struct
652672
653673 let comptype st i ch =
654674 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
655683 | 0x5E -> Array (fieldtype st ch)
656684 | 0x5F -> Struct (vec (fieldtype st) ch)
657685 | 0x60 ->
@@ -1252,6 +1280,13 @@ module Scan = struct
12521280 | 0xD1 (* ref .is_null * ) | 0xD3 (* ref .eq * ) | 0xD4 (* ref.as_non_null *) ->
12531281 pos + 1 |> instructions
12541282 | 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
12551290 | 0xFB -> pos + 1 |> gc_instruction
12561291 | 0xFC -> (
12571292 if debug then Format. eprintf " %d@." (get (pos + 1 ));
@@ -1386,6 +1421,11 @@ module Scan = struct
13861421 | 0 (* catch * ) | 1 (* catch_ref * ) -> pos + 1 |> tagidx |> labelidx
13871422 | 2 (* catch_all * ) | 3 (* catch_all_ref * ) -> pos + 1 |> labelidx
13881423 | 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)
13891429 and block_end pos =
13901430 if debug then Format. eprintf " 0x%02X (@%d) block end@." (get pos) pos;
13911431 match get pos with
@@ -1538,30 +1578,43 @@ let rec subtype subtyping_info (i : int) i' =
15381578 | None -> false
15391579 | Some s -> subtype subtyping_info s i'
15401580
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 ) =
15421582 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
15461590 | (Any | Eq | I31 | Struct | Array | None_ | Type _), Any
15471591 | (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
15511595 | None_ , None_ -> true
15521596 | Type i , Struct -> (
15531597 match subtyping_info.(i).typ with
15541598 | Struct _ -> true
1555- | Array _ | Func _ -> false )
1599+ | Array _ | Func _ | Cont _ -> false )
15561600 | Type i , Array -> (
15571601 match subtyping_info.(i).typ with
15581602 | Array _ -> true
1559- | Struct _ | Func _ -> false )
1603+ | Struct _ | Func _ | Cont _ -> false )
15601604 | Type i , Func -> (
15611605 match subtyping_info.(i).typ with
15621606 | 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 )
15641612 | 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
15651618 | _ -> false
15661619
15671620let ref_subtype subtyping_info { nullable; typ } { nullable = nullable' ; typ = typ' } =
@@ -2449,7 +2502,6 @@ let f ?(filter_export = fun _ -> true) files ~output_file =
24492502(*
24502503LATER
24512504- testsuite : import/export matching, source maps, multiple start functions, ...
2452- - missing instructions ==> typed continuations (?)
24532505- check features?
24542506
24552507MAYBE
0 commit comments