@@ -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
@@ -140,17 +140,18 @@ struct FuncData {
140140 // an unknown source.) Two functions are equal iff they have the same name and
141141 // are defined by the same instance (in particular, we do *not* compare the
142142 // |call| field below, which is an execution detail).
143- void * self ;
143+ uintptr_t instanceId ;
144144
145145 // A way to execute this function. We use this when it is called.
146146 using Call = std::function<Flow(const Literals&)>;
147147 Call call;
148148
149- FuncData (Name name, void * self = nullptr , Call call = {})
150- : name(name), self(self), call(call) {}
149+ // todo?
150+ FuncData (Name name, uintptr_t instanceId = 0 , Call call = {})
151+ : name(name), instanceId(instanceId), call(call) {}
151152
152153 bool operator ==(const FuncData& other) const {
153- return name == other.name && self == other.self ;
154+ return name == other.name && instanceId == other.instanceId ;
154155 }
155156
156157 Flow doCall (const Literals& arguments) {
@@ -361,7 +362,7 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
361362 Literal makeFuncData (Name name, Type type) {
362363 // Identify the interpreter, but do not provide a way to actually call the
363364 // function.
364- auto allocation = std::make_shared<FuncData>(name, this );
365+ auto allocation = std::make_shared<FuncData>(name, ( uintptr_t ) this );
365366#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
366367 __lsan_ignore_object (allocation.get ());
367368#endif
@@ -2916,7 +2917,7 @@ using GlobalValueSet = std::map<Name, Literals>;
29162917//
29172918
29182919template <typename SubType>
2919- class ModuleRunnerBase : public ExpressionRunner <SubType> {
2920+ class ModuleRunnerBase : public ExpressionRunner <SubType>, public std::enable_shared_from_this<ModuleRunnerBase<SubType>> {
29202921public:
29212922 //
29222923 // You need to implement one of these to create a concrete interpreter. The
@@ -3206,9 +3207,9 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
32063207 }
32073208 return Literal (std::make_shared<FuncData>(
32083209 func->name ,
3209- this ,
3210- [this , func](const Literals& arguments) -> Flow {
3211- return callFunction (func->name , arguments);
3210+ reinterpret_cast < uintptr_t >( this ) ,
3211+ [self = this -> shared_from_this () , func](const Literals& arguments) -> Flow {
3212+ return self-> callFunction (func->name , arguments);
32123213 }),
32133214 func->type );
32143215 }
@@ -4773,7 +4774,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
47734774 auto func = entry[0 ];
47744775 auto data = func.getFuncData ();
47754776 // We must be in the right module to do the call using that name.
4776- if (data->self != self ()) {
4777+ if (data->instanceId != ( uintptr_t ) self ()) {
47774778 // Restore the entry to the resume stack, as the other module's
47784779 // callFunction() will read it. Then call into the other module. This
47794780 // sets this up as if we called into the proper module in the first
@@ -4865,10 +4866,9 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
48654866 flow.values .pop_back ();
48664867 arguments = flow.values ;
48674868
4868- if (nextData->self != this ) {
4869+ if (nextData->instanceId != ( uintptr_t ) self () ) {
48694870 // This function is in another module. Call from there.
4870- auto other = (decltype (this ))nextData->self ;
4871- flow = other->callFunction (name, arguments);
4871+ flow = nextData->doCall (arguments);
48724872 break ;
48734873 }
48744874 }
@@ -4998,23 +4998,21 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
49984998 std::map<Name, std::shared_ptr<SubType>> linkedInstances;
49994999};
50005000
5001- class ModuleRunner : public ModuleRunnerBase <ModuleRunner>,
5002- public std::enable_shared_from_this<ModuleRunner> {
5001+ class ModuleRunner : public ModuleRunnerBase <ModuleRunner> {
50035002public:
50045003 ModuleRunner (
50055004 Module& wasm,
50065005 ExternalInterface* externalInterface,
50075006 std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances = {})
50085007 : ModuleRunnerBase(wasm, externalInterface, linkedInstances) {}
50095008
5010- // As the super's |makeFuncData|, but here we also provide a way to
5011- // actually call the function.
50125009 Literal makeFuncData (Name name, Type type) {
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);
5010+ // As the super's |makeFuncData|, but here we also provide a way to
5011+ // actually call the function.
5012+ auto allocation =
5013+ std::make_shared<FuncData>(name, reinterpret_cast <uintptr_t >(this ),
5014+ [moduleRunner = std::static_pointer_cast<ModuleRunner>(std::enable_shared_from_this<ModuleRunnerBase<ModuleRunner>>::shared_from_this ()), name](Literals arguments) {
5015+ return moduleRunner->callFunction (name, arguments);
50185016 });
50195017
50205018 return Literal (allocation, type);
0 commit comments