From 35691d3e7e1ed28c1eedd79ea6d72fca8b0457fd Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Thu, 6 Nov 2025 18:15:25 -0600 Subject: [PATCH 1/2] Update binary parser --- interpreter/binary/decode.ml | 22 +++++++++++++++++----- test/core/imports.wast | 14 ++++++++------ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index 433b092ed..0e3406c42 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -16,11 +16,14 @@ let pos s = !(s.pos) let eos s = (pos s = len s) let reset s pos = s.pos := pos -let check n s = if pos s + n > len s then raise EOS +let has n s = (pos s + n > len s) +let check n s = if has n s then raise EOS let skip n s = if n < 0 then raise EOS else check n s; s.pos := !(s.pos) + n -let read s = Char.code (s.bytes.[!(s.pos)]) +let read_n n s = Char.code (s.bytes.[!(s.pos) + n]) +let read s = read_n 0 s let peek s = if eos s then None else Some (read s) +let peek_n n s = if has n s then Some (read_n n s) else None let get s = check 1 s; let b = read s in skip 1 s; b let get_string n s = let i = pos s in skip n s; String.sub s.bytes i n @@ -1028,13 +1031,22 @@ let type_section s = (* Import section *) let import s = - let module_name = name s in let item_name = name s in let xt = externtype s in - Import (module_name, item_name, xt) + (item_name, xt) + +let imports s = + if (peek_n 0 s = Some 0x01) && (peek_n 1 s = Some 0xFF) then + let module_name = name s in + let imports = vec (at import) s in + List.map (fun { it = (item_name, xt); at } -> Import (module_name, item_name, xt) @@ at) imports + else + let module_name = name s in + let { it = (item_name, xt); at } = (at import) s in + [Import (module_name, item_name, xt) @@ at] let import_section s = - section Custom.Import (vec (at import)) [] s + section Custom.Import (fun s -> List.flatten (vec imports s)) [] s (* Function section *) diff --git a/test/core/imports.wast b/test/core/imports.wast index 543ed65c5..34bcf09f5 100644 --- a/test/core/imports.wast +++ b/test/core/imports.wast @@ -40,12 +40,14 @@ (import "spectest" "print_i32" (func (param i32))) (func (import "spectest" "print_i64") (param i64)) - (import "spectest" "print_i32" (func $print_i32 (param i32))) - (import "spectest" "print_i64" (func $print_i64 (param i64))) - (import "spectest" "print_f32" (func $print_f32 (param f32))) - (import "spectest" "print_f64" (func $print_f64 (param f64))) - (import "spectest" "print_i32_f32" (func $print_i32_f32 (param i32 f32))) - (import "spectest" "print_f64_f64" (func $print_f64_f64 (param f64 f64))) + (import "spectest" + (item "print_i32" (func $print_i32 (param i32))) + (item "print_i64" (func $print_i64 (param i64))) + (item "print_f32" (func $print_f32 (param f32))) + (item "print_f64" (func $print_f64 (param f64))) + (item "print_i32_f32" (func $print_i32_f32 (param i32 f32))) + (item "print_f64_f64" (func $print_f64_f64 (param f64 f64))) + ) (func $print_i32-2 (import "spectest" "print_i32") (param i32)) (func $print_f64-2 (import "spectest" "print_f64") (param f64)) (import "test" "func-i64->i64" (func $i64->i64 (param i64) (result i64))) From 0c31d23d0a2eaac4b3895b8fb3bc7e53e89520ce Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Fri, 7 Nov 2025 12:16:34 -0600 Subject: [PATCH 2/2] Update text parser There is one test failure that I can't decipher right now. --- interpreter/text/parser.mly | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 194590270..a230bad64 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -1249,10 +1249,20 @@ externtype : { fun c -> ignore ($3 c anon_func bind_func); fun () -> ExternFuncT (Idx (inline_functype c ($4 c) $loc($4)).it) } -import : +imports : | LPAR IMPORT name name externtype RPAR { fun c -> let df = $5 c in - fun () -> Import ($3, $4, df ()) @@ $sloc } + fun () -> [Import ($3, $4, df ()) @@ $sloc] } + | LPAR IMPORT name import_item_list RPAR + { fun c -> let items = $4 c in + fun () -> List.map (fun (nm, df, loc) -> Import($3, nm, df) @@ loc) items } + +import_item_list : + | /* empty */ { fun c -> [] } + | import_item import_item_list { fun c -> $1 c :: $2 c } + +import_item : + | LPAR ITEM name externtype RPAR { fun c -> ($3, $4 c (), $loc) } inline_import : | LPAR IMPORT name name RPAR { $3, $4 } @@ -1374,11 +1384,11 @@ module_fields1 : match m.start with | Some _ -> error x.at "multiple start sections" | None -> {m with start = Some x} } - | import module_fields + | imports module_fields { fun c -> let imf = $1 c in let mff = $2 c in fun () -> let mf = mff () in - fun () -> let im = imf () in let m = mf () in - {m with imports = im :: m.imports} } + fun () -> let ims = imf () in let m = mf () in + {m with imports = ims @ m.imports} } | export module_fields { fun c -> let mff = $2 c in fun () -> let mf = mff () in