@@ -501,6 +501,12 @@ struct CollectedFuncInfo {
501501 // when we update the child we can find the parent and handle any special
502502 // behavior we need there.
503503 std::unordered_map<Expression*, Expression*> childParents;
504+
505+ // All functions that might be called from the outside. Any RefFunc suggests
506+ // that, in open world. (We could be more precise and use our flow analysis to
507+ // see which, in fact, flow outside, but it is unclear how useful that would
508+ // be. Anyhow, closed-world is more important to optimize, and avoids this.)
509+ std::unordered_set<Name> calledFromOutside;
504510};
505511
506512// Does a walk while maintaining a map of names of branch targets to those
@@ -528,8 +534,10 @@ struct BreakTargetWalker : public PostWalker<SubType, VisitorType> {
528534struct InfoCollector
529535 : public BreakTargetWalker<InfoCollector, OverriddenVisitor<InfoCollector>> {
530536 CollectedFuncInfo& info;
537+ const PassOptions& options;
531538
532- InfoCollector (CollectedFuncInfo& info) : info(info) {}
539+ InfoCollector (CollectedFuncInfo& info, const PassOptions& options)
540+ : info(info), options(options) {}
533541
534542 // Check if a type is relevant for us. If not, we can ignore it entirely.
535543 bool isRelevant (Type type) {
@@ -665,6 +673,10 @@ struct InfoCollector
665673 info.links .push_back (
666674 {ResultLocation{func, i}, SignatureResultLocation{func->type , i}});
667675 }
676+
677+ if (!options.closedWorld ) {
678+ info.calledFromOutside .insert (curr->func );
679+ }
668680 }
669681 void visitRefEq (RefEq* curr) {
670682 addRoot (curr);
@@ -2092,7 +2104,7 @@ Flower::Flower(Module& wasm, const PassOptions& options)
20922104 // First, collect information from each function.
20932105 ModuleUtils::ParallelFunctionAnalysis<CollectedFuncInfo> analysis (
20942106 wasm, [&](Function* func, CollectedFuncInfo& info) {
2095- InfoCollector finder (info);
2107+ InfoCollector finder (info, options );
20962108
20972109 if (func->imported ()) {
20982110 // Imports return unknown values.
@@ -2114,7 +2126,7 @@ Flower::Flower(Module& wasm, const PassOptions& options)
21142126 // Also walk the global module code (for simplicity, also add it to the
21152127 // function map, using a "function" key of nullptr).
21162128 auto & globalInfo = analysis.map [nullptr ];
2117- InfoCollector finder (globalInfo);
2129+ InfoCollector finder (globalInfo, options );
21182130 finder.walkModuleCode (&wasm);
21192131
21202132#ifdef POSSIBLE_CONTENTS_DEBUG
@@ -2153,6 +2165,16 @@ Flower::Flower(Module& wasm, const PassOptions& options)
21532165 // above.
21542166 InsertOrderedMap<Location, PossibleContents> roots;
21552167
2168+ // Any function that may be called from the outside, like an export, is a
2169+ // root, since they can be called with unknown parameters.
2170+ auto calledFromOutside = [&](Name funcName) {
2171+ auto * func = wasm.getFunction (funcName);
2172+ auto params = func->getParams ();
2173+ for (Index i = 0 ; i < func->getParams ().size (); i++) {
2174+ roots[ParamLocation{func, i}] = PossibleContents::fromType (params[i]);
2175+ }
2176+ };
2177+
21562178 for (auto & [func, info] : analysis.map ) {
21572179 for (auto & link : info.links ) {
21582180 links.insert (getIndexes (link));
@@ -2171,6 +2193,10 @@ Flower::Flower(Module& wasm, const PassOptions& options)
21712193 childParents[getIndex (ExpressionLocation{child, 0 })] =
21722194 getIndex (ExpressionLocation{parent, 0 });
21732195 }
2196+
2197+ for (auto func : info.calledFromOutside ) {
2198+ calledFromOutside (func);
2199+ }
21742200 }
21752201
21762202 // We no longer need the function-level info.
@@ -2180,16 +2206,7 @@ Flower::Flower(Module& wasm, const PassOptions& options)
21802206 std::cout << " external phase\n " ;
21812207#endif
21822208
2183- // Parameters of exported functions are roots, since exports can have callers
2184- // that we can't see, so anything might arrive there.
2185- auto calledFromOutside = [&](Name funcName) {
2186- auto * func = wasm.getFunction (funcName);
2187- auto params = func->getParams ();
2188- for (Index i = 0 ; i < func->getParams ().size (); i++) {
2189- roots[ParamLocation{func, i}] = PossibleContents::fromType (params[i]);
2190- }
2191- };
2192-
2209+ // Exports can be modified from the outside.
21932210 for (auto & ex : wasm.exports ) {
21942211 if (ex->kind == ExternalKind::Function) {
21952212 calledFromOutside (ex->value );
0 commit comments