From 31d6342924a522a642cf23a5d944084d867845cf Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 24 Feb 2026 15:22:38 -0800 Subject: [PATCH 1/4] test --- test/lit/merge/annotations-func-only.wat | 44 +++++++++++++++++++ .../merge/annotations-func-only.wat.second | 12 +++++ 2 files changed, 56 insertions(+) create mode 100644 test/lit/merge/annotations-func-only.wat create mode 100644 test/lit/merge/annotations-func-only.wat.second diff --git a/test/lit/merge/annotations-func-only.wat b/test/lit/merge/annotations-func-only.wat new file mode 100644 index 00000000000..90f01d08362 --- /dev/null +++ b/test/lit/merge/annotations-func-only.wat @@ -0,0 +1,44 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-merge %s first %s.second second -all -S -o - | filecheck %s + +;; Test that we handle code annotations properly when they appear *only* in +;; functions (not code). Both the first and second wasm files have an annotation +;; that should be preserved. + +(module + ;; CHECK: (type $0 (func)) + + ;; CHECK: (export "first" (func $first)) + + ;; CHECK: (export "second" (func $second)) + + ;; CHECK: (@binaryen.js.called) + ;; CHECK-NEXT: (func $first (type $0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (then + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (@binaryen.js.called) + (func $first (export "first") + (if + (i32.const 0) + (then + (return) + ) + ) + ) +) + +;; CHECK: (@binaryen.js.called) +;; CHECK-NEXT: (func $second (type $0) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: (then +;; CHECK-NEXT: (return) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) diff --git a/test/lit/merge/annotations-func-only.wat.second b/test/lit/merge/annotations-func-only.wat.second new file mode 100644 index 00000000000..2bc67fd5c0e --- /dev/null +++ b/test/lit/merge/annotations-func-only.wat.second @@ -0,0 +1,12 @@ +(module + (@binaryen.js.called) + (func $second (export "second") + (if + (i32.const 0) + (then + (return) + ) + ) + ) +) + From b264d0a5451c1b7399034a4ab29027fdad1d0336 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 24 Feb 2026 15:27:01 -0800 Subject: [PATCH 2/4] fix --- src/wasm.h | 5 +++++ src/wasm/wasm-binary.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wasm.h b/src/wasm.h index 2731986bde5..fbeb8d46927 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -2279,6 +2279,11 @@ struct CodeAnnotation { return removableIfUnused == other.removableIfUnused && jsCalled == other.jsCalled && idempotent == other.idempotent; } + + // Checks if no annotation is actually set. + bool empty() { + return *this == CodeAnnotation(); + } }; class Function : public Importable { diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 6ad805c271d..7c116861d49 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -460,7 +460,7 @@ void WasmBinaryWriter::writeFunctions() { // of expressions inside it, or, if it has code annotations (the function // itself may be annotated, even if nothing inside it is). if (!binaryLocationTrackedExpressionsForFunc.empty() || - !func->codeAnnotations.empty()) { + !func->codeAnnotations.empty() || !func->funcAnnotations.empty()) { binaryLocations.functions[func] = BinaryLocations::FunctionLocations{ BinaryLocation(sizePos), BinaryLocation(start - adjustmentForLEBShrinking), From e1f6021cf0ce2fd3683023a844a52658118022b1 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 24 Feb 2026 15:27:10 -0800 Subject: [PATCH 3/4] fmrt --- src/wasm.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wasm.h b/src/wasm.h index fbeb8d46927..3c84e02b984 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -2281,9 +2281,7 @@ struct CodeAnnotation { } // Checks if no annotation is actually set. - bool empty() { - return *this == CodeAnnotation(); - } + bool empty() { return *this == CodeAnnotation(); } }; class Function : public Importable { From 21d7373545de4257c435439fe8686b83e547cd2b Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 24 Feb 2026 15:36:56 -0800 Subject: [PATCH 4/4] fix --- src/ir/metadata.cpp | 5 +++-- src/wasm/wasm-binary.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ir/metadata.cpp b/src/ir/metadata.cpp index a260ade165b..6ac749b1fff 100644 --- a/src/ir/metadata.cpp +++ b/src/ir/metadata.cpp @@ -44,7 +44,8 @@ void copyBetweenFunctions(Expression* origin, Function* originFunc, Function* copyFunc) { if (originFunc->debugLocations.empty() && - originFunc->codeAnnotations.empty()) { + originFunc->codeAnnotations.empty() && + originFunc->funcAnnotations.empty()) { // Nothing to copy. return; } @@ -75,7 +76,7 @@ void copyBetweenFunctions(Expression* origin, } } - // Also copy function-level annotations, if any. + // Also copy function-level annotations. copyFunc->funcAnnotations = originFunc->funcAnnotations; } diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 7c116861d49..6ad805c271d 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -460,7 +460,7 @@ void WasmBinaryWriter::writeFunctions() { // of expressions inside it, or, if it has code annotations (the function // itself may be annotated, even if nothing inside it is). if (!binaryLocationTrackedExpressionsForFunc.empty() || - !func->codeAnnotations.empty() || !func->funcAnnotations.empty()) { + !func->codeAnnotations.empty()) { binaryLocations.functions[func] = BinaryLocations::FunctionLocations{ BinaryLocation(sizePos), BinaryLocation(start - adjustmentForLEBShrinking),