Skip to content

Commit f54556b

Browse files
committed
Require unique_ptr to Module::addFunctionType()
This fixes the memory leak in WasmBinaryBuilder::readSignatures() caused probably the exception thrown there before the FunctionType object is safe. This also makes it clear that the Module becomes the owner of the FunctionType objects.
1 parent 559c16e commit f54556b

File tree

9 files changed

+28
-28
lines changed

9 files changed

+28
-28
lines changed

src/asmjs/asm_v_wasm.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,13 @@ FunctionType* ensureFunctionType(std::string sig, Module* wasm) {
9999
return wasm->getFunctionType(name);
100100
}
101101
// add new type
102-
auto type = new FunctionType;
102+
auto type = make_unique<FunctionType>();
103103
type->name = name;
104104
type->result = sigToType(sig[0]);
105105
for (size_t i = 1; i < sig.size(); i++) {
106106
type->params.push_back(sigToType(sig[i]));
107107
}
108-
wasm->addFunctionType(type);
109-
return type;
108+
return wasm->addFunctionType(std::move(type));
110109
}
111110

112111
Expression* ensureDouble(Expression* expr, MixedArena& allocator) {

src/binaryen-c.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -190,41 +190,40 @@ void BinaryenModuleDispose(BinaryenModuleRef module) {
190190

191191
// Function types
192192

193-
BinaryenFunctionTypeRef BinaryenAddFunctionType(BinaryenModuleRef module, const char* name, BinaryenType result, BinaryenType* paramTypes, BinaryenIndex numParams) {
193+
BinaryenFunctionTypeRef BinaryenAddFunctionType(BinaryenModuleRef module, const char* name,
194+
BinaryenType result, BinaryenType* paramTypes, BinaryenIndex numParams) {
194195
auto* wasm = (Module*)module;
195-
auto* ret = new FunctionType;
196+
auto ret = make_unique<FunctionType>();
196197
if (name) ret->name = name;
197198
else ret->name = Name::fromInt(wasm->functionTypes.size());
198199
ret->result = Type(result);
199200
for (BinaryenIndex i = 0; i < numParams; i++) {
200201
ret->params.push_back(Type(paramTypes[i]));
201202
}
202203

203-
// Lock. This can be called from multiple threads at once, and is a
204-
// point where they all access and modify the module.
205-
{
206-
std::lock_guard<std::mutex> lock(BinaryenFunctionTypeMutex);
207-
wasm->addFunctionType(ret);
208-
}
209-
210204
if (tracing) {
211205
std::cout << " {\n";
212206
std::cout << " BinaryenType paramTypes[] = { ";
213207
for (BinaryenIndex i = 0; i < numParams; i++) {
214-
if (i > 0) std::cout << ", ";
208+
if (i > 0)
209+
std::cout << ", ";
215210
std::cout << paramTypes[i];
216211
}
217-
if (numParams == 0) std::cout << "0"; // ensure the array is not empty, otherwise a compiler error on VS
212+
if (numParams == 0)
213+
std::cout << "0"; // ensure the array is not empty, otherwise a compiler error on VS
218214
std::cout << " };\n";
219215
size_t id = functionTypes.size();
220216
std::cout << " functionTypes[" << id << "] = BinaryenAddFunctionType(the_module, ";
221-
functionTypes[ret] = id;
217+
functionTypes[ret.get()] = id;
222218
traceNameOrNULL(name);
223219
std::cout << ", " << result << ", paramTypes, " << numParams << ");\n";
224220
std::cout << " }\n";
225221
}
226222

227-
return ret;
223+
// Lock. This can be called from multiple threads at once, and is a
224+
// point where they all access and modify the module.
225+
std::lock_guard<std::mutex> lock(BinaryenFunctionTypeMutex);
226+
return wasm->addFunctionType(std::move(ret));
228227
}
229228
void BinaryenRemoveFunctionType(BinaryenModuleRef module, const char* name) {
230229
if (tracing) {

src/ir/module-utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ inline void copyModule(Module& in, Module& out) {
7373
// we use names throughout, not raw points, so simple copying is fine
7474
// for everything *but* expressions
7575
for (auto& curr : in.functionTypes) {
76-
out.addFunctionType(new FunctionType(*curr));
76+
out.addFunctionType(make_unique<FunctionType>(*curr));
7777
}
7878
for (auto& curr : in.imports) {
7979
out.addImport(new Import(*curr));

src/passes/LegalizeJSInterface.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ struct LegalizeJSInterface : public Pass {
181181
// wasm calls the import, so it must call a stub that calls the actual legal JS import
182182
Import* makeLegalStub(Import* im, Module* module, Name& funcName) {
183183
Builder builder(*module);
184-
auto* type = new FunctionType();
184+
auto type = make_unique<FunctionType>();
185185
type->name = Name(std::string("legaltype$") + im->name.str);
186186
auto* legal = new Import();
187187
legal->name = Name(std::string("legalimport$") + im->name.str);
@@ -233,7 +233,7 @@ struct LegalizeJSInterface : public Pass {
233233
func->result = imFunctionType->result;
234234

235235
module->addFunction(func);
236-
module->addFunctionType(type);
236+
module->addFunctionType(std::move(type));
237237
return legal;
238238
}
239239

src/tools/wasm-merge.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ struct InputMergeable : public ExpressionStackWalker<InputMergeable, Visitor<Inp
446446

447447
// copy in the data
448448
for (auto& curr : wasm.functionTypes) {
449-
outputMergeable.wasm.addFunctionType(curr.release());
449+
outputMergeable.wasm.addFunctionType(std::move(curr));
450450
}
451451
for (auto& curr : wasm.imports) {
452452
if (curr->kind == ExternalKind::Memory || curr->kind == ExternalKind::Table) {

src/wasm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ class Module {
786786
Function* getFunctionOrNull(Name name);
787787
Global* getGlobalOrNull(Name name);
788788

789-
void addFunctionType(FunctionType* curr);
789+
FunctionType* addFunctionType(std::unique_ptr<FunctionType> curr);
790790
void addImport(Import* curr);
791791
void addExport(Export* curr);
792792
void addFunction(Function* curr);

src/wasm/wasm-binary.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ void WasmBinaryBuilder::readSignatures() {
909909
if (debug) std::cerr << "num: " << numTypes << std::endl;
910910
for (size_t i = 0; i < numTypes; i++) {
911911
if (debug) std::cerr << "read one" << std::endl;
912-
auto curr = new FunctionType;
912+
auto curr = make_unique<FunctionType>();
913913
auto form = getS32LEB();
914914
if (form != BinaryConsts::EncodedType::Func) {
915915
throwError("bad signature form " + std::to_string(form));
@@ -929,7 +929,7 @@ void WasmBinaryBuilder::readSignatures() {
929929
curr->result = getType();
930930
}
931931
curr->name = Name::fromInt(wasm.functionTypes.size());
932-
wasm.addFunctionType(curr);
932+
wasm.addFunctionType(std::move(curr));
933933
}
934934
}
935935

src/wasm/wasm-s-parser.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ void SExpressionWasmBuilder::preParseFunctionType(Element& s) {
419419
functionType->name = Name::fromInt(wasm.functionTypes.size());
420420
functionTypeNames.push_back(functionType->name);
421421
if (wasm.getFunctionTypeOrNull(functionType->name)) throw ParseException("duplicate function type", s.line, s.col);
422-
wasm.addFunctionType(functionType.release());
422+
wasm.addFunctionType(std::move(functionType));
423423
}
424424
}
425425
}
@@ -1967,7 +1967,7 @@ void SExpressionWasmBuilder::parseType(Element& s) {
19671967
}
19681968
functionTypeNames.push_back(type->name);
19691969
if (wasm.getFunctionTypeOrNull(type->name)) throw ParseException("duplicate function type", s.line, s.col);
1970-
wasm.addFunctionType(type.release());
1970+
wasm.addFunctionType(std::move(type));
19711971
}
19721972

19731973
} // namespace wasm

src/wasm/wasm.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -722,15 +722,17 @@ Global* Module::getGlobalOrNull(Name name) {
722722
return iter->second;
723723
}
724724

725-
void Module::addFunctionType(FunctionType* curr) {
725+
FunctionType* Module::addFunctionType(std::unique_ptr<FunctionType> curr) {
726726
if (!curr->name.is()) {
727727
Fatal() << "Module::addFunctionType: empty name";
728728
}
729729
if (getFunctionTypeOrNull(curr->name)) {
730730
Fatal() << "Module::addFunctionType: " << curr->name << " already exists";
731731
}
732-
functionTypes.push_back(std::unique_ptr<FunctionType>(curr));
733-
functionTypesMap[curr->name] = curr;
732+
auto p = curr.get();
733+
functionTypes.emplace_back(std::move(curr));
734+
functionTypesMap[p->name] = p;
735+
return p;
734736
}
735737

736738
void Module::addImport(Import* curr) {

0 commit comments

Comments
 (0)