From d129cc8b94d11e532fc30bac9a6b67d906488131 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Wed, 2 Sep 2026 14:11:02 -0500 Subject: [PATCH 1/4] Ensure that inline (data)s and (elem)s count toward identifiers The (memory (data ...)) and (table (elem ...)) syntax sugar was not correctly counting the indices of the data and elem segments, causing the identifiers' indices on later data and elem segments to be off by one. Because the identifier context needs to be updated as we parse, memory_fields and table_fields are updated to do some of their work in the first pass. --- interpreter/text/parser.mly | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index b1a32431f2..50a8fd100b 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -1112,20 +1112,23 @@ memoryuse : memory : | LPAR MEMORY bindidx_opt memory_fields RPAR { fun c -> let x = $3 c anon_memory bind_memory @@ $sloc in - fun () -> $4 c x $sloc } + let mff = $4 c in + fun () -> mff x $sloc } memory_fields : | memorytype - { fun c x loc -> [Memory ($1 c) @@ loc], [], [], [] } + { fun c -> fun x loc -> [Memory ($1 c) @@ loc], [], [], [] } | inline_import memorytype /* Sugar */ - { fun c x loc -> + { fun c -> fun x loc -> [], [], [Import (fst $1, snd $1, ExternMemoryT ($2 c)) @@ loc], [] } | inline_export memory_fields /* Sugar */ - { fun c x loc -> let mems, data, ims, exs = $2 c x loc in + { fun c -> let mff = $2 c in + fun x loc -> let mems, data, ims, exs = mff x loc in mems, data, ims, $1 (MemoryX x) c :: exs } | addrtype LPAR DATA string_list RPAR /* Sugar */ - { fun c x loc -> + { fun c -> ignore (anon_data c $sloc); + fun x loc -> let size = Int64.(div (add (of_int (String.length $4)) 65535L) 65536L) in let offset = [at_const $1 (0L @@ loc) @@ loc] @@ loc in [Memory (MemoryT ($1, {min = size; max = Some size})) @@ loc], @@ -1185,23 +1188,26 @@ tableuse : table : | LPAR TABLE bindidx_opt table_fields RPAR { fun c -> let x = $3 c anon_table bind_table @@ $sloc in - fun () -> $4 c x $sloc } + let tff = $4 c in + fun () -> tff x $sloc } table_fields : | tabletype constexpr1 - { fun c x loc -> [Table ($1 c, $2 c) @@ loc], [], [], [] } + { fun c -> fun x loc -> [Table ($1 c, $2 c) @@ loc], [], [], [] } | tabletype /* Sugar */ - { fun c x loc -> let TableT (_, _, (_, ht)) as tt = $1 c in + { fun c -> fun x loc -> let TableT (_, _, (_, ht)) as tt = $1 c in [Table (tt, [RefNull ht @@ loc] @@ loc) @@ loc], [], [], [] } | inline_import tabletype /* Sugar */ - { fun c x loc -> + { fun c -> fun x loc -> [], [], [Import (fst $1, snd $1, ExternTableT ($2 c)) @@ loc], [] } | inline_export table_fields /* Sugar */ - { fun c x loc -> let tabs, elems, ims, exs = $2 c x loc in + { fun c -> let tff = $2 c in + fun x loc -> let tabs, elems, ims, exs = tff x loc in tabs, elems, ims, $1 (TableX x) c :: exs } | addrtype reftype LPAR ELEM elemexpr elemexpr_list RPAR /* Sugar */ - { fun c x loc -> + { fun c -> ignore (anon_elem c $sloc); + fun x loc -> let offset = [at_const $1 (0L @@ loc) @@ loc] @@ loc in let einit = $5 c :: $6 c in let size = Lib.List64.length einit in @@ -1211,7 +1217,8 @@ table_fields : [Elem (rt, einit, Active (x, offset) @@ loc) @@ loc], [], [] } | addrtype reftype LPAR ELEM elemidx_list RPAR /* Sugar */ - { fun c x loc -> + { fun c -> ignore (anon_elem c $sloc); + fun x loc -> let (_, ht) as rt = $2 c in let tinit = [RefNull ht @@ loc] @@ loc in let offset = [at_const $1 (0L @@ loc) @@ loc] @@ loc in From 2a5cef6fab37211069ed4ef0fca36d80a17cbef0 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Thu, 3 Sep 2026 07:49:30 -0500 Subject: [PATCH 2/4] Add tests for identifier context of inline data/elem segments --- test/core/data.wast | 14 ++++++++++++++ test/core/elem.wast | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/test/core/data.wast b/test/core/data.wast index 73112b673f..fd05b5e443 100644 --- a/test/core/data.wast +++ b/test/core/data.wast @@ -527,3 +527,17 @@ ) "constant expression required" ) + +;; Testing how identifiers interact with data segments specified inline +(module + (memory (data "\AB")) + (data $d "\CD") + (func (export "init") + (memory.init $d (i32.const 0) (i32.const 0) (i32.const 1)) + ) + (func (export "load") (result i32) + (i32.load8_u (i32.const 0)) + ) +) +(invoke "init") +(assert_return (invoke "load") (i32.const 0xCD)) diff --git a/test/core/elem.wast b/test/core/elem.wast index 1722a30b81..6cf25e65fb 100644 --- a/test/core/elem.wast +++ b/test/core/elem.wast @@ -1108,3 +1108,19 @@ (assert_return (invoke "call_in_table" (i32.const 6)) (i32.const 42)) (assert_trap (invoke "call_in_table" (i32.const 0)) "uninitialized element") + +;; Testing how identifiers interact with elem segments specified inline +(module + (func $f (result i32) i32.const 0xAB) + (func $g (result i32) i32.const 0xCD) + (table funcref (elem (ref.func $f))) + (elem $e funcref (ref.func $g)) + (func (export "init") + (table.init $e (i32.const 0) (i32.const 0) (i32.const 1)) + ) + (func (export "run") (result i32) + (call_indirect (result i32) (i32.const 0)) + ) +) +(invoke "init") +(assert_return (invoke "run") (i32.const 0xCD)) From 56ddf2327a920e21591d6adbc2e0a5a96a57da9b Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Thu, 3 Sep 2026 07:49:52 -0500 Subject: [PATCH 3/4] Fix typo --- interpreter/script/js.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/script/js.ml b/interpreter/script/js.ml index b2a1aa1e1b..26dc3f55a7 100644 --- a/interpreter/script/js.ml +++ b/interpreter/script/js.ml @@ -275,7 +275,7 @@ let lookup_export (env : env) x_opt name at = let exports = find_inst env x_opt at in try NameMap.find name exports with Not_found -> raise (Eval.Crash (at, "unknown export \"" ^ - string_of_name name ^ "\" within module isntance")) + string_of_name name ^ "\" within module instance")) (* Transitively unsubstitute deftype into list of unrolled recursive types *) From 6d2e9c56e480af295c6d38cde8cbb640512084c1 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Thu, 3 Sep 2026 07:51:09 -0500 Subject: [PATCH 4/4] Remove unnecessary `fun` definitions --- interpreter/text/parser.mly | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 50a8fd100b..7952a3abe5 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -1117,9 +1117,9 @@ memory : memory_fields : | memorytype - { fun c -> fun x loc -> [Memory ($1 c) @@ loc], [], [], [] } + { fun c x loc -> [Memory ($1 c) @@ loc], [], [], [] } | inline_import memorytype /* Sugar */ - { fun c -> fun x loc -> + { fun c x loc -> [], [], [Import (fst $1, snd $1, ExternMemoryT ($2 c)) @@ loc], [] } | inline_export memory_fields /* Sugar */ @@ -1193,12 +1193,12 @@ table : table_fields : | tabletype constexpr1 - { fun c -> fun x loc -> [Table ($1 c, $2 c) @@ loc], [], [], [] } + { fun c x loc -> [Table ($1 c, $2 c) @@ loc], [], [], [] } | tabletype /* Sugar */ - { fun c -> fun x loc -> let TableT (_, _, (_, ht)) as tt = $1 c in + { fun c x loc -> let TableT (_, _, (_, ht)) as tt = $1 c in [Table (tt, [RefNull ht @@ loc] @@ loc) @@ loc], [], [], [] } | inline_import tabletype /* Sugar */ - { fun c -> fun x loc -> + { fun c x loc -> [], [], [Import (fst $1, snd $1, ExternTableT ($2 c)) @@ loc], [] } | inline_export table_fields /* Sugar */