From 2112b054e024e5e102f5fbd3406f2fc33fc9f2a7 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Fri, 15 May 2026 07:45:26 +0000 Subject: [PATCH 1/2] [wasm-split] Validate output modules We are currently validating inputs but not outputs. This PR makes wasm-split validate output modules too unless `--no-validation` is given. I had to add `--no-validation` to three existing tests to make them pass. They fail because of this reason, from #8043's description: > Do not use exact imports when custom descriptors are not enabled. In > principle this could cause validation errors because we allow e.g. > exact locals even when custom descriptors are not enabled. This could > be worked around in the future either by running a pass to remove > exactness before splitting or by always using and allowing exact > imports, but then emitting them as inexact imports when custom > descriptors are disabled. --- src/tools/wasm-split/wasm-split.cpp | 9 ++++++++- .../active-table-base-global-used-elsewhere.wast | 2 +- test/lit/wasm-split/exact.wast | 2 +- test/lit/wasm-split/table64-global-offset.wast | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp index 8faa1bef488..04ad8598793 100644 --- a/src/tools/wasm-split/wasm-split.cpp +++ b/src/tools/wasm-split/wasm-split.cpp @@ -52,7 +52,8 @@ void parseInput(Module& wasm, const WasmSplitOptions& options) { options.applyOptionsAfterParse(wasm); - if (options.passOptions.validate && !WasmValidator().validate(wasm)) { + if (options.passOptions.validate && + !WasmValidator().validate(wasm, options.passOptions)) { Fatal() << "error validating input"; } } @@ -100,6 +101,12 @@ void writeModule(Module& wasm, runner.add("strip-debug"); runner.run(); } + + if (options.passOptions.validate && + !WasmValidator().validate(wasm, options.passOptions)) { + Fatal() << "error validating output module"; + } + ModuleWriter writer(options.passOptions); writer.setBinary(options.emitBinary); writer.setDebugInfo(options.passOptions.debugInfo && !options.stripDebug); diff --git a/test/lit/wasm-split/active-table-base-global-used-elsewhere.wast b/test/lit/wasm-split/active-table-base-global-used-elsewhere.wast index ca3380ce405..6594850c28f 100644 --- a/test/lit/wasm-split/active-table-base-global-used-elsewhere.wast +++ b/test/lit/wasm-split/active-table-base-global-used-elsewhere.wast @@ -1,7 +1,7 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; We need to disable reference-types to reuse the existing table as the active ;; table -;; RUN: wasm-split %s --disable-reference-types --split-funcs=split -g -o1 %t.1.wasm -o2 %t.2.wasm +;; RUN: wasm-split %s --no-validation --disable-reference-types --split-funcs=split -g -o1 %t.1.wasm -o2 %t.2.wasm ;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY ;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY diff --git a/test/lit/wasm-split/exact.wast b/test/lit/wasm-split/exact.wast index 2275acec7d0..3c7d280576c 100644 --- a/test/lit/wasm-split/exact.wast +++ b/test/lit/wasm-split/exact.wast @@ -8,7 +8,7 @@ ;; RUN: wasm-opt -all %t.1.wasm --print | filecheck %s --check-prefix=PRIMARY ;; RUN: wasm-opt -all %t.2.wasm --print | filecheck %s --check-prefix=SECONDARY -;; RUN: wasm-split -all --disable-custom-descriptors -g %s --keep-funcs=foo -o1 %t.1.wasm -o2 %t.2.wasm +;; RUN: wasm-split -all --no-validation --disable-custom-descriptors -g %s --keep-funcs=foo -o1 %t.1.wasm -o2 %t.2.wasm ;; RUN: wasm-opt -all --disable-custom-descriptors %t.1.wasm --print | filecheck %s --check-prefix=PRIMARY_NOCD ;; RUN: wasm-opt -all --disable-custom-descriptors %t.2.wasm --print | filecheck %s --check-prefix=SECONDARY_NOCD diff --git a/test/lit/wasm-split/table64-global-offset.wast b/test/lit/wasm-split/table64-global-offset.wast index ebcc930903b..8baa181cf87 100644 --- a/test/lit/wasm-split/table64-global-offset.wast +++ b/test/lit/wasm-split/table64-global-offset.wast @@ -1,5 +1,5 @@ ;; When reference types is disabled, we reuse the existing i64 table -;; RUN: wasm-split %s -g -o1 %t.1.wasm -o2 %t.2.wasm --export-prefix='%' --keep-funcs=foo --enable-memory64 -v 2>&1 | filecheck %s --check-prefix CHECK +;; RUN: wasm-split %s --no-validation -g -o1 %t.1.wasm -o2 %t.2.wasm --export-prefix='%' --keep-funcs=foo --enable-memory64 -v 2>&1 | filecheck %s --check-prefix CHECK ;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY-NOREF ;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY-NOREF ;; Check whether the split files conform to memory64 @@ -7,7 +7,7 @@ ;; RUN: wasm-opt --enable-memory64 %t.2.wasm ;; When reference types is enabled, we create a new table -;; RUN: wasm-split %s -g -o1 %t.1.wasm -o2 %t.2.wasm --export-prefix='%' --keep-funcs=foo --enable-memory64 --enable-reference-types -v 2>&1 | filecheck %s --check-prefix CHECK +;; RUN: wasm-split %s --no-validation -g -o1 %t.1.wasm -o2 %t.2.wasm --export-prefix='%' --keep-funcs=foo --enable-memory64 --enable-reference-types -v 2>&1 | filecheck %s --check-prefix CHECK ;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY-REF ;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY-REF ;; Check whether the split files conform to memory64 From 6f63abeb23953e6410e5ad91db150e62119a5f1d Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Sun, 24 May 2026 09:21:47 +0000 Subject: [PATCH 2/2] Enable validation only when custom-desriptor is enabled --- src/tools/wasm-split/wasm-split.cpp | 7 ++++++- .../active-table-base-global-used-elsewhere.wast | 2 +- test/lit/wasm-split/exact.wast | 2 +- test/lit/wasm-split/table64-global-offset.wast | 4 ++-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp index 04ad8598793..920c390b6e6 100644 --- a/src/tools/wasm-split/wasm-split.cpp +++ b/src/tools/wasm-split/wasm-split.cpp @@ -102,8 +102,13 @@ void writeModule(Module& wasm, runner.run(); } + // We currently cannot enable validation for outputs when custom-descriptors + // is not enabled. See the description of + // https://github.com/WebAssembly/binaryen/pull/8043. + // TODO Fix this and enable validation for all cases. if (options.passOptions.validate && - !WasmValidator().validate(wasm, options.passOptions)) { + !WasmValidator().validate(wasm, options.passOptions) && + wasm.features.hasCustomDescriptors()) { Fatal() << "error validating output module"; } diff --git a/test/lit/wasm-split/active-table-base-global-used-elsewhere.wast b/test/lit/wasm-split/active-table-base-global-used-elsewhere.wast index 6594850c28f..ca3380ce405 100644 --- a/test/lit/wasm-split/active-table-base-global-used-elsewhere.wast +++ b/test/lit/wasm-split/active-table-base-global-used-elsewhere.wast @@ -1,7 +1,7 @@ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. ;; We need to disable reference-types to reuse the existing table as the active ;; table -;; RUN: wasm-split %s --no-validation --disable-reference-types --split-funcs=split -g -o1 %t.1.wasm -o2 %t.2.wasm +;; RUN: wasm-split %s --disable-reference-types --split-funcs=split -g -o1 %t.1.wasm -o2 %t.2.wasm ;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY ;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY diff --git a/test/lit/wasm-split/exact.wast b/test/lit/wasm-split/exact.wast index 3c7d280576c..2275acec7d0 100644 --- a/test/lit/wasm-split/exact.wast +++ b/test/lit/wasm-split/exact.wast @@ -8,7 +8,7 @@ ;; RUN: wasm-opt -all %t.1.wasm --print | filecheck %s --check-prefix=PRIMARY ;; RUN: wasm-opt -all %t.2.wasm --print | filecheck %s --check-prefix=SECONDARY -;; RUN: wasm-split -all --no-validation --disable-custom-descriptors -g %s --keep-funcs=foo -o1 %t.1.wasm -o2 %t.2.wasm +;; RUN: wasm-split -all --disable-custom-descriptors -g %s --keep-funcs=foo -o1 %t.1.wasm -o2 %t.2.wasm ;; RUN: wasm-opt -all --disable-custom-descriptors %t.1.wasm --print | filecheck %s --check-prefix=PRIMARY_NOCD ;; RUN: wasm-opt -all --disable-custom-descriptors %t.2.wasm --print | filecheck %s --check-prefix=SECONDARY_NOCD diff --git a/test/lit/wasm-split/table64-global-offset.wast b/test/lit/wasm-split/table64-global-offset.wast index 8baa181cf87..ebcc930903b 100644 --- a/test/lit/wasm-split/table64-global-offset.wast +++ b/test/lit/wasm-split/table64-global-offset.wast @@ -1,5 +1,5 @@ ;; When reference types is disabled, we reuse the existing i64 table -;; RUN: wasm-split %s --no-validation -g -o1 %t.1.wasm -o2 %t.2.wasm --export-prefix='%' --keep-funcs=foo --enable-memory64 -v 2>&1 | filecheck %s --check-prefix CHECK +;; RUN: wasm-split %s -g -o1 %t.1.wasm -o2 %t.2.wasm --export-prefix='%' --keep-funcs=foo --enable-memory64 -v 2>&1 | filecheck %s --check-prefix CHECK ;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY-NOREF ;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY-NOREF ;; Check whether the split files conform to memory64 @@ -7,7 +7,7 @@ ;; RUN: wasm-opt --enable-memory64 %t.2.wasm ;; When reference types is enabled, we create a new table -;; RUN: wasm-split %s --no-validation -g -o1 %t.1.wasm -o2 %t.2.wasm --export-prefix='%' --keep-funcs=foo --enable-memory64 --enable-reference-types -v 2>&1 | filecheck %s --check-prefix CHECK +;; RUN: wasm-split %s -g -o1 %t.1.wasm -o2 %t.2.wasm --export-prefix='%' --keep-funcs=foo --enable-memory64 --enable-reference-types -v 2>&1 | filecheck %s --check-prefix CHECK ;; RUN: wasm-dis %t.1.wasm | filecheck %s --check-prefix PRIMARY-REF ;; RUN: wasm-dis %t.2.wasm | filecheck %s --check-prefix SECONDARY-REF ;; Check whether the split files conform to memory64