From 0bb9dd82661856f86e9ace1d61911f298c27fbe2 Mon Sep 17 00:00:00 2001 From: Akshat Lakhera Date: Mon, 19 Oct 2026 16:16:15 +0700 Subject: [PATCH 1/2] LegalizeJSInterface: pick unique names for generated stubs Signed-off-by: Akshat Lakhera --- src/passes/LegalizeJSInterface.cpp | 15 +++-- .../legalize-js-interface-name-collision.wast | 55 +++++++++++++++++++ 2 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 test/lit/passes/legalize-js-interface-name-collision.wast diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index 4bb74918ff0..c8354962d91 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -33,6 +33,7 @@ #include "ir/element-utils.h" #include "ir/import-utils.h" #include "ir/literal-utils.h" +#include "ir/names.h" #include "ir/utils.h" #include "pass.h" #include "shared-constants.h" @@ -269,12 +270,14 @@ struct LegalizeJSInterface : public Pass { Function* makeLegalStubForCalledImport(Function* im, Module* module) { Builder builder(*module); auto legalIm = std::make_unique(); - legalIm->name = Name(std::string("legalimport$") + im->name.toString()); + legalIm->name = Names::getValidFunctionName( + *module, Name(std::string("legalimport$") + im->name.toString())); legalIm->module = im->module; legalIm->base = im->base; legalIm->hasExplicitName = true; auto stub = std::make_unique(); - stub->name = Name(std::string("legalfunc$") + im->name.toString()); + stub->name = Names::getValidFunctionName( + *module, Name(std::string("legalfunc$") + im->name.toString())); stub->type = im->type.with(Exact); stub->hasExplicitName = true; @@ -309,12 +312,8 @@ struct LegalizeJSInterface : public Pass { Type(Signature(Type(params), call->type), NonNullable, Inexact); auto* stubPtr = stub.get(); - if (!module->getFunctionOrNull(stub->name)) { - module->addFunction(std::move(stub)); - } - if (!module->getFunctionOrNull(legalIm->name)) { - module->addFunction(std::move(legalIm)); - } + module->addFunction(std::move(stub)); + module->addFunction(std::move(legalIm)); return stubPtr; } diff --git a/test/lit/passes/legalize-js-interface-name-collision.wast b/test/lit/passes/legalize-js-interface-name-collision.wast new file mode 100644 index 00000000000..1c9576e2c2d --- /dev/null +++ b/test/lit/passes/legalize-js-interface-name-collision.wast @@ -0,0 +1,55 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-opt %s --legalize-js-interface -S -o - | filecheck %s + +;; The module already has functions named like the ones the pass would create +;; for the illegal import. The pass must pick fresh names instead of reusing +;; (or failing to add) the existing ones. + +(module + (import "env" "imp" (func $imp (param i64) (result i32))) + ;; CHECK: (type $0 (func (param i64) (result i32))) + + ;; CHECK: (type $1 (func (result f32))) + + ;; CHECK: (type $2 (func (result i32))) + + ;; CHECK: (type $3 (func (param i32 i32) (result i32))) + + ;; CHECK: (import "env" "imp" (func $legalimport$imp_4 (param i32 i32) (result i32))) + + ;; CHECK: (func $legalfunc$imp (param $0 i64) (result i32) + ;; CHECK-NEXT: (i32.const 7) + ;; CHECK-NEXT: ) + (func $legalfunc$imp (param i64) (result i32) + (i32.const 7) + ) + ;; CHECK: (func $legalimport$imp (result f32) + ;; CHECK-NEXT: (f32.const 8) + ;; CHECK-NEXT: ) + (func $legalimport$imp (result f32) + (f32.const 8) + ) + ;; CHECK: (func $f (result i32) + ;; CHECK-NEXT: (call $legalfunc$imp_4 + ;; CHECK-NEXT: (i64.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $f (result i32) + (call $imp + (i64.const 1) + ) + ) +) +;; CHECK: (func $legalfunc$imp_4 (param $0 i64) (result i32) +;; CHECK-NEXT: (call $legalimport$imp_4 +;; CHECK-NEXT: (i32.wrap_i64 +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.wrap_i64 +;; CHECK-NEXT: (i64.shr_u +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: (i64.const 32) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) From 19abeb599d36a75cc719d8865638777488eee175 Mon Sep 17 00:00:00 2001 From: Akshat Lakhera Date: Mon, 19 Oct 2026 17:36:47 +0700 Subject: [PATCH 2/2] Use the pointer returned by addFunction Signed-off-by: Akshat Lakhera --- src/passes/LegalizeJSInterface.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp index c8354962d91..c1aa9a8af8d 100644 --- a/src/passes/LegalizeJSInterface.cpp +++ b/src/passes/LegalizeJSInterface.cpp @@ -311,8 +311,7 @@ struct LegalizeJSInterface : public Pass { legalIm->type = Type(Signature(Type(params), call->type), NonNullable, Inexact); - auto* stubPtr = stub.get(); - module->addFunction(std::move(stub)); + auto* stubPtr = module->addFunction(std::move(stub)); module->addFunction(std::move(legalIm)); return stubPtr; }