diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 7173ec0fb64..8f0306fc008 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -140,20 +140,20 @@ std::vector> buildStubModules(Module& wasm) { Module* module = it->second.get(); struct Visitor { - Module* module; + Module* module = nullptr; + void operator()(Memory* memory) { auto* copied = ModuleUtils::copyMemory(memory, *module); copied->module = Name(); copied->base = Name(); - module->addExport(Builder(*module).makeExport( + module->maybeAddExport(Builder::makeExport( memory->base, copied->name, ExternalKind::Memory)); } void operator()(Table* table) { - // create tables with similar initial and max values auto* copied = ModuleUtils::copyTable(table, *module); copied->module = Name(); copied->base = Name(); - module->addExport(Builder(*module).makeExport( + module->maybeAddExport(Builder::makeExport( table->base, copied->name, ExternalKind::Table)); } void operator()(Global* global) { @@ -163,17 +163,14 @@ std::vector> buildStubModules(Module& wasm) { Builder builder(*module); copied->init = builder.makeConst(Literal::makeZero(global->type)); - module->addExport(builder.makeExport( + module->maybeAddExport(Builder::makeExport( global->base, copied->name, ExternalKind::Global)); } void operator()(Function* func) { Builder builder(*module); - auto* copied = ModuleUtils::copyFunction(func, *module); - copied->module = Name(); - copied->base = Name(); - copied->body = builder.makeUnreachable(); - module->addExport(builder.makeExport( - func->base, copied->name, ExternalKind::Function)); + auto stubbedFunc = builder.makeUnreachableFunction(func->name); + module->maybeAddExport(Builder::makeExport( + func->base, stubbedFunc->name, ExternalKind::Function)); } void operator()(Tag* tag) { // no-op diff --git a/src/wasm-builder.h b/src/wasm-builder.h index d14e716f12b..c41370648a9 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -43,11 +43,19 @@ class Builder { // make* functions create an expression instance. + std::unique_ptr makeUnreachableFunction(Name name) { + auto func = std::make_unique(); + func->name = name; + func->type = Type::unreachable; + func->body = makeUnreachable(); + return func; + } + static std::unique_ptr makeFunction(Name name, Type type, std::vector&& vars, Expression* body = nullptr) { - assert(type.isSignature() && type.isNonNullable()); + // assert(type.isSignature() && type.isNonNullable()); auto func = std::make_unique(); func->name = name; func->type = type; diff --git a/src/wasm.h b/src/wasm.h index 605c7025395..92329ecbe0b 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -2596,6 +2596,7 @@ class Module { Tag* addTag(Tag* curr); Export* addExport(std::unique_ptr&& curr); + Export* maybeAddExport(std::unique_ptr&& curr); Function* addFunction(std::unique_ptr&& curr); Table* addTable(std::unique_ptr&& curr); ElementSegment* addElementSegment(std::unique_ptr&& curr); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 44c1daea622..c1eb92711e4 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1829,6 +1829,22 @@ Elem* addModuleElement(Vector& v, return ret; } +template +Elem* maybeAddModuleElement(Vector& v, + Map& m, + std::unique_ptr curr, + std::string funcName) { + if (!curr->name.is()) { + Fatal() << "Module::" << funcName << ": empty name"; + } + if (getModuleElementOrNull(m, curr->name)) { + return nullptr; + } + auto* ret = m[curr->name] = curr.get(); + v.push_back(std::move(curr)); + return ret; +} + Export* Module::addExport(Export* curr) { return addModuleElement(exports, exportsMap, curr, "addExport"); } @@ -1849,6 +1865,11 @@ Export* Module::addExport(std::unique_ptr&& curr) { return addModuleElement(exports, exportsMap, std::move(curr), "addExport"); } +Export* Module::maybeAddExport(std::unique_ptr&& curr) { + return maybeAddModuleElement( + exports, exportsMap, std::move(curr), "addExport"); +} + Function* Module::addFunction(std::unique_ptr&& curr) { return addModuleElement( functions, functionsMap, std::move(curr), "addFunction"); diff --git a/test/ctor-eval/repeated-import.wast b/test/ctor-eval/repeated-import.wast new file mode 100644 index 00000000000..3d947a2fb94 --- /dev/null +++ b/test/ctor-eval/repeated-import.wast @@ -0,0 +1,9 @@ +(module + (import "import" "log" (func $logi32 (param i32))) + (import "import" "log" (func $logi64 (param i64))) + (export "foo" (func $0)) + (func $0 (param $0 i32) + (local.get $0) + (call $logi32) + ) +) diff --git a/test/ctor-eval/repeated-import.wast.ctors b/test/ctor-eval/repeated-import.wast.ctors new file mode 100644 index 00000000000..257cc5642cb --- /dev/null +++ b/test/ctor-eval/repeated-import.wast.ctors @@ -0,0 +1 @@ +foo diff --git a/test/ctor-eval/repeated-import.wast.out b/test/ctor-eval/repeated-import.wast.out new file mode 100644 index 00000000000..493f068620f --- /dev/null +++ b/test/ctor-eval/repeated-import.wast.out @@ -0,0 +1,10 @@ +(module + (type $0 (func (param i32))) + (import "import" "log" (func $logi32 (type $0) (param i32))) + (export "foo" (func $0)) + (func $0 (type $0) (param $0 i32) + (call $logi32 + (local.get $0) + ) + ) +)