diff --git a/src/lib_webassembly/binary/decode.ml b/src/lib_webassembly/binary/decode.ml index 934112567b294092aff2fd7f4fd91a278a85202b..a2ce8df50210d66e713b4cb90e371ee0e27a6279 100644 --- a/src/lib_webassembly/binary/decode.ml +++ b/src/lib_webassembly/binary/decode.ml @@ -290,6 +290,41 @@ let block_type s = | Some b when b land 0xc0 = 0x40 -> ValBlockType (Some (value_type s)) | _ -> VarBlockType (at vs33 s) +type 'a lazy_stack = LazyStack of {length : int32; vector : 'a Vector.t} + +let empty_stack () = LazyStack {length = 0l; vector = Vector.empty ()} + +let push_stack v (LazyStack {length; vector}) = + let vector, length = + if length >= Vector.num_elements vector then Vector.append v vector + else (Vector.set length v vector, length) + in + LazyStack {length = Int32.succ length; vector} + +let push_rev_values values stack = + List.fold_left (fun stack v -> push_stack v stack) stack (List.rev values) + +let pop_stack (LazyStack {length; vector}) = + let open Lwt.Syntax in + if length = 0l then Lwt.return_none + else + let length = Int32.pred length in + let+ value = Vector.get length vector in + Some (value, LazyStack {length; vector}) + +let pop_at_most n stack = + let open Lwt.Syntax in + let rec fold acc n stack = + if n = 0 then Lwt.return (acc, stack) + else + let* value = pop_stack stack in + match value with + | None -> Lwt.return (acc, stack) + | Some (v, stack) -> (fold [@ocaml.tailcall]) (v :: acc) (n - 1) stack + in + let+ values, stack = fold [] n stack in + (List.rev values, stack) + (** Instruction parsing continuations. *) type instr_block_kont = | IKStop of block_label (** Final step of a block parsing. *) @@ -907,56 +942,71 @@ let instr s pos tag = let instr_block_step s bs cont = let open Lwt.Syntax in + let* cont, stack = pop_at_most 3 cont in match cont with + | _ :: _ :: _ :: _ :: _ -> + Stdlib.failwith "More than 3 values popped from the stack" + (* Enforces the number of values popped from the stack, which shouldn't fail. *) | [IKStop lbl] -> invalid_arg "instr_block" - | IKStop lbl :: IKBlock (bt, pos) :: IKNext plbl :: rest -> + | [IKStop lbl; IKBlock (bt, pos); IKNext plbl] -> end_ s ; let e = Source.(block bt lbl @@ region s pos pos) in let+ () = add_to_block bs plbl e in - IKNext plbl :: rest - | IKStop lbl :: IKLoop (bt, pos) :: IKNext plbl :: rest -> + push_stack (IKNext plbl) stack + | [IKStop lbl; IKLoop (bt, pos); IKNext plbl] -> end_ s ; let e = Source.(loop bt lbl @@ region s pos pos) in let+ () = add_to_block bs plbl e in - IKNext plbl :: rest - | IKStop lbl1 :: IKIf1 (bt, pos) :: IKNext plbl :: rest -> + push_stack (IKNext plbl) stack + | [IKStop lbl1; IKIf1 (bt, pos); IKNext plbl] -> if peek s = Some 0x05 then (skip 1 s ; - IKNext (alloc_block bs) :: IKIf2 (bt, pos, lbl1) :: IKNext plbl :: rest) + push_rev_values + [IKNext (alloc_block bs); IKIf2 (bt, pos, lbl1); IKNext plbl] + stack) |> Lwt.return else ( end_ s ; let e = Source.(if_ bt lbl1 empty_block @@ region s pos pos) in let+ () = add_to_block bs plbl e in - IKNext plbl :: rest) - | IKStop lbl2 :: IKIf2 (bt, pos, lbl1) :: IKNext plbl :: rest -> + push_stack (IKNext plbl) stack) + | [IKStop lbl2; IKIf2 (bt, pos, lbl1); IKNext plbl] -> end_ s ; let e = Source.(if_ bt lbl1 lbl2 @@ region s pos pos) in let+ () = add_to_block bs plbl e in - IKNext plbl :: rest + push_stack (IKNext plbl) stack | IKNext lbl :: ks -> ( match peek s with - | None | Some (0x05 | 0x0b) -> IKStop lbl :: ks |> Lwt.return + | None | Some (0x05 | 0x0b) -> + push_rev_values (IKStop lbl :: ks) stack |> Lwt.return | _ -> ( let pos = pos s in let tag = op s in match tag with | 0x02 -> let bt = block_type s in - IKNext (alloc_block bs) :: IKBlock (bt, pos) :: IKNext lbl :: ks + push_rev_values + (IKNext (alloc_block bs) + :: IKBlock (bt, pos) + :: IKNext lbl :: ks) + stack |> Lwt.return | 0x03 -> let bt = block_type s in - IKNext (alloc_block bs) :: IKLoop (bt, pos) :: IKNext lbl :: ks + push_rev_values + (IKNext (alloc_block bs) :: IKLoop (bt, pos) :: IKNext lbl :: ks) + stack |> Lwt.return | 0x04 -> let bt = block_type s in - IKNext (alloc_block bs) :: IKIf1 (bt, pos) :: IKNext lbl :: ks + push_rev_values + (IKNext (alloc_block bs) :: IKIf1 (bt, pos) :: IKNext lbl :: ks) + stack |> Lwt.return | _ -> let e = Source.(instr s pos tag @@ region s pos pos) in let+ () = add_to_block bs lbl e in - IKNext lbl :: ks)) + push_rev_values (IKNext lbl :: ks) stack)) (* Stop can only be followed a new block, or being the final state. *) | IKStop _ :: _ -> invalid_arg "instr_block" (* These continuations never reduce directly and are always preceded by an end @@ -965,25 +1015,42 @@ let instr_block_step s bs cont = (* The empty continuation cannot reduce. *) | [] -> assert false -(** Vector and size continuations *) +type block_kont = + | BlockStart + | BlockParse of instr_block_kont lazy_stack + | BlockStop of block_label + +let block_step s bs = + let open Lwt.Syntax in + function + | BlockStart -> + let lbl = alloc_block bs in + let vector = empty_stack () |> push_stack (IKNext lbl) in + Lwt.return (BlockParse vector) + | BlockParse (LazyStack {length; vector} as kont) -> + if length = 1l then + let* head = Vector.get 0l vector in + match head with + | IKStop lbl -> Lwt.return (BlockStop lbl) + | instr -> + let+ kont = instr_block_step s bs kont in + BlockParse kont + else + let+ kont = instr_block_step s bs kont in + BlockParse kont + | BlockStop lbl -> assert false -(** Vector accumulator, used in two steps: first accumulating the values, then - reversing them and possibly mapping them, counting the number of values in - the list. Continuation passing style transformation of {!List.map} also - returning length. *) -type ('a, 'b) vec_map_kont = - | Collect of int * 'a list - | Rev of 'a list * 'b list * int +(** Vector and size continuations *) -type 'a lazy_vec_kont = Lazy_vec of {offset : int32; vector : 'a Vector.t} +type 'a lazy_vec_kont = LazyVec of {offset : int32; vector : 'a Vector.t} -let is_end_of_vec (Lazy_vec {offset; vector}) = +let is_end_of_vec (LazyVec {offset; vector}) = Vector.num_elements vector <= offset -let init_lazy_vec n = Lazy_vec {offset = 0l; vector = Vector.create n} +let init_lazy_vec n = LazyVec {offset = 0l; vector = Vector.create n} -let lazy_vec_step v (Lazy_vec {offset; vector}) = - Lazy_vec {offset = Int32.add offset 1l; vector = Vector.set offset v vector} +let lazy_vec_step v (LazyVec {offset; vector}) = + LazyVec {offset = Int32.add offset 1l; vector = Vector.set offset v vector} type pos = int @@ -1008,13 +1075,13 @@ let name_step s = function let pos = pos s in let len = len32 s in NKParse (pos, init_lazy_vec 0l, len) - | NKParse (pos, Lazy_vec {vector; _}, 0) -> NKStop vector - | NKParse (pos, Lazy_vec lv, len) -> + | NKParse (pos, LazyVec {vector; _}, 0) -> NKStop vector + | NKParse (pos, LazyVec lv, len) -> let d, offset = try Utf8.decode_step get s with Utf8 -> error s pos "malformed UTF-8 encoding" in - let vec = Lazy_vec {lv with vector = Vector.grow 1l lv.vector} in + let vec = LazyVec {lv with vector = Vector.grow 1l lv.vector} in NKParse (pos, lazy_vec_step d vec, len - offset) | NKStop l -> assert false (* final step, cannot reduce. *) @@ -1083,13 +1150,13 @@ let func_type_step s = function let len = len32 s in if tag = -0x20 then FKIns (init_lazy_vec (Int32.of_int len)) else error s (pos s - 1) "malformed function type" - | FKIns (Lazy_vec {vector = ins; _} as vec) when is_end_of_vec vec -> + | FKIns (LazyVec {vector = ins; _} as vec) when is_end_of_vec vec -> let len = len32 s in FKOut (ins, init_lazy_vec (Int32.of_int len)) | FKIns ins -> let vt = value_type s in FKIns (lazy_vec_step vt ins) - | FKOut (ins, (Lazy_vec {vector = out; _} as out_vec)) + | FKOut (ins, (LazyVec {vector = out; _} as out_vec)) when is_end_of_vec out_vec -> FKStop (FuncType (ins, out)) | FKOut (ins, out_vec) -> @@ -1199,7 +1266,7 @@ type code_kont = left : pos; size : size; locals : value_type Vector.t; - const_kont : instr_block_kont list; + const_kont : block_kont; } (** Parsing step of the body of a function. *) | CKStop of func (** Final step of a parsed function, irreducible. *) @@ -1231,7 +1298,7 @@ let code_step s bs = left; size; pos; - vec_kont = Lazy_vec {vector = types; _} as vec_kont; + vec_kont = LazyVec {vector = types; _} as vec_kont; locals_size; } when is_end_of_vec vec_kont -> @@ -1243,7 +1310,7 @@ let code_step s bs = size; pos; vec_kont; - type_vec = Lazy_vec {offset = 0l; vector = types}; + type_vec = LazyVec {offset = 0l; vector = types}; curr_type = None; } |> Lwt.return @@ -1257,10 +1324,9 @@ let code_step s bs = {left; size; pos; vec_kont = lazy_vec_step local vec_kont; locals_size} |> Lwt.return | CKLocalsAccumulate - {left; size; pos; vec_kont = Lazy_vec {vector = locals; _} as vec_kont; _} + {left; size; pos; vec_kont = LazyVec {vector = locals; _} as vec_kont; _} when is_end_of_vec vec_kont -> - CKBody {left; size; locals; const_kont = [IKNext (alloc_block bs)]} - |> Lwt.return + CKBody {left; size; locals; const_kont = BlockStart} |> Lwt.return | CKLocalsAccumulate { left; @@ -1268,7 +1334,7 @@ let code_step s bs = pos; vec_kont; curr_type = None | Some (0l, _); - type_vec = Lazy_vec {offset = n; vector = types}; + type_vec = LazyVec {offset = n; vector = types}; } -> let+ next_type = Vector.get n types in CKLocalsAccumulate @@ -1278,7 +1344,7 @@ let code_step s bs = pos; vec_kont; curr_type = Some next_type; - type_vec = Lazy_vec {offset = Int32.succ n; vector = types}; + type_vec = LazyVec {offset = Int32.succ n; vector = types}; } | CKLocalsAccumulate {left; size; pos; vec_kont; curr_type = Some (occurences, ty); type_vec} @@ -1294,7 +1360,7 @@ let code_step s bs = type_vec; } |> Lwt.return - | CKBody {left; size; locals; const_kont = [IKStop body]} -> + | CKBody {left; size; locals; const_kont = BlockStop body} -> end_ s ; check_size size s ; let func = @@ -1302,7 +1368,7 @@ let code_step s bs = in CKStop func |> Lwt.return | CKBody {left; size; locals; const_kont} -> - let+ const_kont = instr_block_step s bs const_kont in + let+ const_kont = block_step s bs const_kont in CKBody {left; size; locals; const_kont} | CKStop _ -> assert false (* final step, cannot reduce *) @@ -1329,7 +1395,7 @@ type elem_kont = index : int32 Source.phrase; index_kind : index_kind; early_ref_type : ref_type option; - offset_kont : pos * instr_block_kont list; + offset_kont : pos * block_kont; } (** Element segment mode parsing step. *) | EKInitIndexed of { mode : segment_mode; @@ -1341,7 +1407,7 @@ type elem_kont = mode : segment_mode; ref_type : ref_type; einit_vec : const lazy_vec_kont; - einit_kont : pos * instr_block_kont list; + einit_kont : pos * block_kont; } (** Element segment initialization code parsing step for constant values. *) | EKStop of elem_segment' (** Final step of a segment parsing. *) @@ -1359,7 +1425,7 @@ let ek_start s bs = index; index_kind = Indexed; early_ref_type = Some FuncRefType; - offset_kont = (left, [IKNext (alloc_block bs)]); + offset_kont = (left, BlockStart); } | 0x01l -> (* passive *) @@ -1379,7 +1445,7 @@ let ek_start s bs = index; index_kind = Indexed; early_ref_type = None; - offset_kont = (left_offset, [IKNext (alloc_block bs)]); + offset_kont = (left_offset, BlockStart); } | 0x03l -> (* declarative *) @@ -1392,14 +1458,13 @@ let ek_start s bs = (* active_zero *) let index = Source.(0l @@ Source.no_region) in let left = pos s in - let lbl = alloc_block bs in EKMode { left; index; index_kind = Const; early_ref_type = Some FuncRefType; - offset_kont = (left, [IKNext lbl]); + offset_kont = (left, BlockStart); } | 0x05l -> (* passive *) @@ -1413,7 +1478,7 @@ let ek_start s bs = mode; ref_type; einit_vec = init_lazy_vec (Int32.of_int n); - einit_kont = (left, [IKNext (alloc_block bs)]); + einit_kont = (left, BlockStart); } | 0x06l -> (* active *) @@ -1426,7 +1491,7 @@ let ek_start s bs = index; index_kind = Const; early_ref_type = None; - offset_kont = (left_offset, [IKNext (alloc_block bs)]); + offset_kont = (left_offset, BlockStart); } | 0x07l -> (* declarative *) @@ -1440,7 +1505,7 @@ let ek_start s bs = mode; ref_type; einit_vec = init_lazy_vec (Int32.of_int n); - einit_kont = (left, [IKNext (alloc_block bs)]); + einit_kont = (left, BlockStart); } | _ -> error s (pos s - 1) "malformed elements segment kind" @@ -1454,7 +1519,7 @@ let elem_step s bs = index; index_kind; early_ref_type; - offset_kont = left_offset, [IKStop offset]; + offset_kont = left_offset, BlockStop offset; } -> end_ s ; let right = pos s in @@ -1478,12 +1543,12 @@ let elem_step s bs = mode; ref_type; einit_vec = init_lazy_vec (Int32.of_int n); - einit_kont = (left, [IKNext (alloc_block bs)]); + einit_kont = (left, BlockStart); } |> Lwt.return | EKMode {left; index; index_kind; early_ref_type; offset_kont = left_offset, k} -> - let+ k' = instr_block_step s bs k in + let+ k' = block_step s bs k in EKMode { left; @@ -1494,9 +1559,9 @@ let elem_step s bs = } (* End of initialization parsing *) | EKInitConst - {mode; ref_type; einit_vec = Lazy_vec {vector = einit; _} as einit_vec; _} + {mode; ref_type; einit_vec = LazyVec {vector = einit; _} as einit_vec; _} | EKInitIndexed - {mode; ref_type; einit_vec = Lazy_vec {vector = einit; _} as einit_vec} + {mode; ref_type; einit_vec = LazyVec {vector = einit; _} as einit_vec} when is_end_of_vec einit_vec -> EKStop {etype = ref_type; einit; emode = mode} |> Lwt.return (* Indexed *) @@ -1505,7 +1570,7 @@ let elem_step s bs = EKInitIndexed {mode; ref_type; einit_vec = lazy_vec_step elem_index einit_vec} (* Const *) - | EKInitConst {mode; ref_type; einit_vec; einit_kont = left, [IKStop einit]} + | EKInitConst {mode; ref_type; einit_vec; einit_kont = left, BlockStop einit} -> end_ s ; let right = pos s in @@ -1515,11 +1580,11 @@ let elem_step s bs = mode; ref_type; einit_vec = lazy_vec_step einit einit_vec; - einit_kont = (right, [IKNext (alloc_block bs)]); + einit_kont = (right, BlockStart); } |> Lwt.return | EKInitConst {mode; ref_type; einit_vec; einit_kont = left, k} -> - let+ k' = instr_block_step s bs k in + let+ k' = block_step s bs k in EKInitConst {mode; ref_type; einit_vec; einit_kont = (left, k')} | EKStop _ -> assert false (* Final step, cannot reduce *) @@ -1530,7 +1595,7 @@ type data_kont = | DKMode of { left : pos; index : int32 Source.phrase; - offset_kont : pos * instr_block_kont list; + offset_kont : pos * block_kont; } (** Data segment mode parsing step. *) | DKInit of {dmode : segment_mode; init_kont : byte_vector_kont} | DKStop of data_segment' (** Final step of a data segment parsing. *) @@ -1541,7 +1606,7 @@ let data_start s bs = (* active_zero *) let index = Source.(0l @@ Source.no_region) in let left = pos s in - DKMode {left; index; offset_kont = (left, [IKNext (alloc_block bs)])} + DKMode {left; index; offset_kont = (left, BlockStart)} | 0x01l -> (* passive *) let mode_pos = pos s in @@ -1552,22 +1617,21 @@ let data_start s bs = let left = pos s in let index = at var s in let left_offset = pos s in - DKMode - {left; index; offset_kont = (left_offset, [IKNext (alloc_block bs)])} + DKMode {left; index; offset_kont = (left_offset, BlockStart)} | _ -> error s (pos s - 1) "malformed data segment kind" let data_step s bs = let open Lwt.Syntax in function | DKStart -> data_start s bs |> Lwt.return - | DKMode {left; index; offset_kont = left_offset, [IKStop offset]} -> + | DKMode {left; index; offset_kont = left_offset, BlockStop offset} -> end_ s ; let right = pos s in let offset = Source.(offset @@ region s left_offset right) in let dmode = Source.(Active {index; offset} @@ region s left right) in DKInit {dmode; init_kont = VKStart} |> Lwt.return | DKMode {left; index; offset_kont = left_offset, k} -> - let+ k' = instr_block_step s bs k in + let+ k' = block_step s bs k in DKMode {left; index; offset_kont = (left_offset, k')} | DKInit {dmode; init_kont = VKStop dinit} -> DKStop {dmode; dinit} |> Lwt.return @@ -1652,8 +1716,7 @@ type module_kont = (** Import section parsing. *) | MKExport of export_kont * pos * size * export lazy_vec_kont (** Export section parsing. *) - | MKGlobal of - global_type * int * instr_block_kont list * size * global lazy_vec_kont + | MKGlobal of global_type * int * block_kont * size * global lazy_vec_kont (** Globals section parsing, containing the starting position, the continuation of the current global block instruction, and the size of the section. *) @@ -1743,7 +1806,7 @@ let find_vec ty fields = find_vec' ty 0l fields let find_single ty fields = find_single' ty 0l fields -let vec_field ty (Lazy_vec {vector; _}) = VecField (ty, vector) +let vec_field ty (LazyVec {vector; _}) = VecField (ty, vector) let module_step state = let open Lwt.Syntax in @@ -1890,7 +1953,7 @@ let module_step state = next @@ MKField (ty, size, lazy_vec_step f vec) | GlobalField -> let gtype = global_type s in - next @@ MKGlobal (gtype, pos s, [IKNext (alloc_block bs)], size, vec) + next @@ MKGlobal (gtype, pos s, BlockStart, size, vec) | ExportField -> next @@ MKExport (ExpKStart, pos s, size, vec) | StartField -> (* not a vector *) @@ -1918,13 +1981,13 @@ let module_step state = next @@ MKField (ExportField, size, lazy_vec_step f vec) | MKExport (k, pos, size, curr_vec) -> next @@ MKExport (export_step s k, pos, size, curr_vec) - | MKGlobal (gtype, left, [IKStop res], size, vec) -> + | MKGlobal (gtype, left, BlockStop res, size, vec) -> end_ s ; let ginit = Source.(res @@ region s left (pos s)) in let f = Source.({gtype; ginit} @@ region s left (pos s)) in next @@ MKField (GlobalField, size, lazy_vec_step f vec) | MKGlobal (ty, pos, k, size, curr_vec) -> - let* k = instr_block_step s bs k in + let* k = block_step s bs k in next @@ MKGlobal (ty, pos, k, size, curr_vec) | MKElem (EKStop elem, left, size, vec) -> let elem = Source.(elem @@ region s left (pos s)) in @@ -1944,10 +2007,10 @@ let module_step state = let* code_kont = code_step s bs code_kont in next @@ MKCode (code_kont, pos, size, curr_vec) | MKElaborateFunc - (ft, fb, (Lazy_vec {vector = func_types; _} as vec), no_datas_in_func) + (ft, fb, (LazyVec {vector = func_types; _} as vec), no_datas_in_func) when is_end_of_vec vec -> next @@ MKBuild (Some func_types, no_datas_in_func) - | MKElaborateFunc (fts, fbs, (Lazy_vec {offset; _} as vec), no_datas_in_func) + | MKElaborateFunc (fts, fbs, (LazyVec {offset; _} as vec), no_datas_in_func) -> let* ft = Vector.get offset fts in let* fb = Vector.get offset fbs in diff --git a/src/lib_webassembly/binary/decode.mli b/src/lib_webassembly/binary/decode.mli index 81ff755a0bd8ba1b695a9bf925c683e3d1239cd2..b407ea9f64c9ed506938ac45ab8d87f35775d7e8 100644 --- a/src/lib_webassembly/binary/decode.mli +++ b/src/lib_webassembly/binary/decode.mli @@ -2,6 +2,30 @@ module Vector = Lazy_vector.LwtInt32Vector exception Code of Source.region * string +(** Lazy stack using an underlying lazy vector, and a pointer on the head of the + stack. *) +type 'a lazy_stack = LazyStack of {length : int32; vector : 'a Vector.t} + +(** [empty_stack ()] returns a new empty stack. *) +val empty_stack : unit -> 'a lazy_stack + +(** [push_stack v s] pushes value [v] on the stack [s] at index [s.length] and + updates the length. If [s.vector] is full, it appends the value to the vector + (growing it by 1), otherwise it set the value in the vector. *) +val push_stack : 'a -> 'a lazy_stack -> 'a lazy_stack + +(** [push_rev_values vs s] pushes values in [vs] on the stack [s], starting from + the end of the list. *) +val push_rev_values : 'a list -> 'a lazy_stack -> 'a lazy_stack + +(** [pop_stack s] returns the value at [s.length - 1] and a new stack with + length decreased by one. *) +val pop_stack : 'a lazy_stack -> ('a * 'a lazy_stack) option Lwt.t + +(** [pop_at_most n s] returns at most the [n] values on top of the stack, and + the resulting stack. *) +val pop_at_most : int -> 'a lazy_stack -> ('a list * 'a lazy_stack) Lwt.t + (** Instruction parsing continuations. *) type instr_block_kont = | IKStop of Ast.block_label (** Final step of a block parsing. *) @@ -13,19 +37,21 @@ type instr_block_kont = | IKIf2 of Ast.block_type * int * Ast.block_label (** If .. else parsing step. *) -(** Vector and size continuations *) +(** Block parsing continuations. *) +type block_kont = + | BlockStart + (** Initial step of a block parsing, allocating the block in the block table. *) + | BlockParse of instr_block_kont lazy_stack + (** Parsing of a block, with the continuation stack. *) + | BlockStop of Ast.block_label + (** End of a block, returning the label corresponding to the allocated block + at the beginning. *) -(** Vector accumulator, used in two step: first accumulating the values, then - reversing them and possibly mapping them, counting the number of values in - the list. Continuation passing style transformation of {!List.map} also - returning length. *) -type ('a, 'b) vec_map_kont = - | Collect of int * 'a list - | Rev of 'a list * 'b list * int +(** Vector and size continuations *) (** Lazy vector accumulator, with the current offset to write the next value in the vector. *) -type 'a lazy_vec_kont = Lazy_vec of {offset : int32; vector : 'a Vector.t} +type 'a lazy_vec_kont = LazyVec of {offset : int32; vector : 'a Vector.t} (** Position of a value on the stream. *) type pos = private int @@ -87,7 +113,7 @@ type code_kont = left : pos; size : size; locals : Types.value_type Vector.t; - const_kont : instr_block_kont list; + const_kont : block_kont; } (** Parsing step of the body of a function. *) | CKStop of Ast.func (** Final step of a parsed function, irreducible. *) @@ -100,7 +126,7 @@ type elem_kont = index : int32 Source.phrase; index_kind : index_kind; early_ref_type : Types.ref_type option; - offset_kont : pos * instr_block_kont list; + offset_kont : pos * block_kont; } (** Element segment mode parsing step. *) | EKInitIndexed of { mode : Ast.segment_mode; @@ -112,7 +138,7 @@ type elem_kont = mode : Ast.segment_mode; ref_type : Types.ref_type; einit_vec : Ast.const lazy_vec_kont; - einit_kont : pos * instr_block_kont list; + einit_kont : pos * block_kont; } (** Element segment initialization code parsing step for constant values. *) | EKStop of Ast.elem_segment' (** Final step of a segment parsing. *) @@ -122,7 +148,7 @@ type data_kont = | DKMode of { left : pos; index : int32 Source.phrase; - offset_kont : pos * instr_block_kont list; + offset_kont : pos * block_kont; } (** Data segment mode parsing step. *) | DKInit of {dmode : Ast.segment_mode; init_kont : byte_vector_kont} | DKStop of Ast.data_segment' (** Final step of a data segment parsing. *) @@ -190,11 +216,7 @@ type module_kont = | MKExport of export_kont * pos * size * Ast.export lazy_vec_kont (** Export section parsing. *) | MKGlobal of - Types.global_type - * int - * instr_block_kont list - * size - * Ast.global lazy_vec_kont + Types.global_type * int * block_kont * size * Ast.global lazy_vec_kont (** Globals section parsing, containing the starting position, the continuation of the current global block instruction, and the size of the section. *)