Skip to content

Commit 48ef9fc

Browse files
Use shared_from_this to avoid lifetime issues with ModuleRunner
1 parent 28e849b commit 48ef9fc

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

scripts/test/shared.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ def get_tests(test_dir, extensions=[], recursive=False):
477477
'imports0.wast', # Missing memory type validation on instantiation
478478
'imports2.wast', # Missing memory type validation on instantiation
479479
'imports3.wast', # Missing memory type validation on instantiation
480-
'linking0.wast', # Missing memory type validation on instantiation
480+
# 'linking0.wast', # Missing memory type validation on instantiation
481481
'linking3.wast', # Fatal error on missing table.
482482
'i16x8_relaxed_q15mulr_s.wast', # Requires wast `either` support
483483
'i32x4_relaxed_trunc.wast', # Requires wast `either` support

src/wasm-interpreter.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class Flow {
8686
}
8787

8888
Literals values;
89-
Name breakTo; // if non-null, a break is going on
89+
Name breakTo; // if non-null, a break is going on
9090
Tag* suspendTag = nullptr; // if non-null, breakTo must be SUSPEND_FLOW, and
9191
// this is the tag being suspended
9292

@@ -137,10 +137,9 @@ struct FuncData {
137137

138138
// The interpreter instance this function closes over, if any. (There might
139139
// not be an interpreter instance if this is a host function or an import from
140-
// an unknown source.) This is only used for equality comparisons, as two
141-
// functions are equal iff they have the same name and are defined by the same
142-
// instance (in particular, we do *not* compare the |call| field below, which
143-
// is an execution detail).
140+
// an unknown source.) Two functions are equal iff they have the same name and
141+
// are defined by the same instance (in particular, we do *not* compare the
142+
// |call| field below, which is an execution detail).
144143
void* self;
145144

146145
// A way to execute this function. We use this when it is called.
@@ -4999,24 +4998,25 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
49994998
std::map<Name, std::shared_ptr<SubType>> linkedInstances;
50004999
};
50015000

5002-
class ModuleRunner : public ModuleRunnerBase<ModuleRunner> {
5001+
class ModuleRunner : public ModuleRunnerBase<ModuleRunner>,
5002+
public std::enable_shared_from_this<ModuleRunner> {
50035003
public:
50045004
ModuleRunner(
50055005
Module& wasm,
50065006
ExternalInterface* externalInterface,
50075007
std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances = {})
50085008
: ModuleRunnerBase(wasm, externalInterface, linkedInstances) {}
50095009

5010+
// As the super's |makeFuncData|, but here we also provide a way to
5011+
// actually call the function.
50105012
Literal makeFuncData(Name name, Type type) {
5011-
// As the super's |makeFuncData|, but here we also provide a way to
5012-
// actually call the function.
5013-
auto allocation =
5014-
std::make_shared<FuncData>(name, this, [this, name](Literals arguments) {
5015-
return callFunction(name, arguments);
5013+
// This function may outlive the ModuleRunner in the case that instantiation
5014+
// fails. Use shared_from_this() to extend this ModuleRunner's lifetime.
5015+
auto allocation = std::make_shared<FuncData>(
5016+
name, this, [self = shared_from_this(), name](Literals arguments) {
5017+
return self->callFunction(name, arguments);
50165018
});
5017-
#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
5018-
__lsan_ignore_object(allocation.get());
5019-
#endif
5019+
50205020
return Literal(allocation, type);
50215021
}
50225022
};

0 commit comments

Comments
 (0)