@@ -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,17 +137,16 @@ 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).
144- void * self;
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).
143+ uintptr_t self;
145144
146145 // A way to execute this function. We use this when it is called.
147146 using Call = std::function<Flow(const Literals&)>;
148147 Call call;
149148
150- FuncData (Name name, void * self = nullptr , Call call = {})
149+ FuncData (Name name, uintptr_t self = 0 , Call call = {})
151150 : name(name), self(self), call(call) {}
152151
153152 bool operator ==(const FuncData& other) const {
@@ -362,10 +361,8 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
362361 Literal makeFuncData (Name name, Type type) {
363362 // Identify the interpreter, but do not provide a way to actually call the
364363 // function.
365- auto allocation = std::make_shared<FuncData>(name, this );
366- #if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
367- __lsan_ignore_object (allocation.get ());
368- #endif
364+ auto allocation =
365+ std::make_shared<FuncData>(name, reinterpret_cast <uintptr_t >(this ));
369366 return Literal (allocation, type);
370367 }
371368
@@ -2917,7 +2914,9 @@ using GlobalValueSet = std::map<Name, Literals>;
29172914//
29182915
29192916template <typename SubType>
2920- class ModuleRunnerBase : public ExpressionRunner <SubType> {
2917+ class ModuleRunnerBase
2918+ : public ExpressionRunner<SubType>,
2919+ public std::enable_shared_from_this<ModuleRunnerBase<SubType>> {
29212920public:
29222921 //
29232922 // You need to implement one of these to create a concrete interpreter. The
@@ -3207,9 +3206,10 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
32073206 }
32083207 return Literal (std::make_shared<FuncData>(
32093208 func->name ,
3210- this ,
3211- [this , func](const Literals& arguments) -> Flow {
3212- return callFunction (func->name , arguments);
3209+ reinterpret_cast <uintptr_t >(this ),
3210+ [self = this ->shared_from_this (),
3211+ func](const Literals& arguments) -> Flow {
3212+ return self->callFunction (func->name , arguments);
32133213 }),
32143214 func->type );
32153215 }
@@ -4774,7 +4774,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
47744774 auto func = entry[0 ];
47754775 auto data = func.getFuncData ();
47764776 // We must be in the right module to do the call using that name.
4777- if (data->self != self ()) {
4777+ if (data->self != ( uintptr_t ) self ()) {
47784778 // Restore the entry to the resume stack, as the other module's
47794779 // callFunction() will read it. Then call into the other module. This
47804780 // sets this up as if we called into the proper module in the first
@@ -4866,10 +4866,9 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
48664866 flow.values .pop_back ();
48674867 arguments = flow.values ;
48684868
4869- if (nextData->self != this ) {
4869+ if (nextData->self != ( uintptr_t ) self () ) {
48704870 // This function is in another module. Call from there.
4871- auto other = (decltype (this ))nextData->self ;
4872- flow = other->callFunction (name, arguments);
4871+ flow = nextData->doCall (arguments);
48734872 break ;
48744873 }
48754874 }
@@ -5010,13 +5009,16 @@ class ModuleRunner : public ModuleRunnerBase<ModuleRunner> {
50105009 Literal makeFuncData (Name name, Type type) {
50115010 // As the super's |makeFuncData|, but here we also provide a way to
50125011 // actually call the function.
5013- auto allocation =
5014- std::make_shared<FuncData>(name, this , [this , name](Literals arguments) {
5015- return callFunction (name, arguments);
5012+ auto allocation = std::make_shared<FuncData>(
5013+ name,
5014+ reinterpret_cast <uintptr_t >(this ),
5015+ [moduleRunner = std::static_pointer_cast<ModuleRunner>(
5016+ std::enable_shared_from_this<
5017+ ModuleRunnerBase<ModuleRunner>>::shared_from_this ()),
5018+ name](Literals arguments) {
5019+ return moduleRunner->callFunction (name, arguments);
50165020 });
5017- #if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
5018- __lsan_ignore_object (allocation.get ());
5019- #endif
5021+
50205022 return Literal (allocation, type);
50215023 }
50225024};
0 commit comments