diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/DeadArgumentElimination.cpp | 7 | ||||
-rw-r--r-- | src/passes/Inlining.cpp | 14 | ||||
-rw-r--r-- | src/passes/opt-utils.h | 9 | ||||
-rw-r--r-- | src/wasm-traversal.h | 19 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 14 |
5 files changed, 44 insertions, 19 deletions
diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp index c4de07d81..975b291b0 100644 --- a/src/passes/DeadArgumentElimination.cpp +++ b/src/passes/DeadArgumentElimination.cpp @@ -279,16 +279,15 @@ struct DAE : public Pass { for (auto& func : module->functions) { infoMap[func->name]; } - // Check the influence of the table and exports. + DAEScanner scanner(&infoMap); + scanner.walkModuleCode(module); for (auto& curr : module->exports) { if (curr->kind == ExternalKind::Function) { infoMap[curr->value].hasUnseenCalls = true; } } - ElementUtils::iterAllElementFunctionNames( - module, [&](Name name) { infoMap[name].hasUnseenCalls = true; }); // Scan all the functions. - DAEScanner(&infoMap).run(runner, module); + scanner.run(runner, module); // Combine all the info. std::unordered_map<Name, std::vector<Call*>> allCalls; std::unordered_set<Name> tailCallees; diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index b69d8f7c2..0e6f6abe4 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -344,23 +344,15 @@ struct Inlining : public Pass { infos[func->name]; } PassRunner runner(module); - FunctionInfoScanner(&infos).run(&runner, module); + FunctionInfoScanner scanner(&infos); + scanner.run(&runner, module); // fill in global uses + scanner.walkModuleCode(module); for (auto& ex : module->exports) { if (ex->kind == ExternalKind::Function) { infos[ex->value].usedGlobally = true; } } - ElementUtils::iterAllElementFunctionNames( - module, [&](Name name) { infos[name].usedGlobally = true; }); - - for (auto& global : module->globals) { - if (!global->imported()) { - for (auto* ref : FindAll<RefFunc>(global->init).list) { - infos[ref->func].usedGlobally = true; - } - } - } if (module->start.is()) { infos[module->start].usedGlobally = true; } diff --git a/src/passes/opt-utils.h b/src/passes/opt-utils.h index b333779f7..5f4ab545c 100644 --- a/src/passes/opt-utils.h +++ b/src/passes/opt-utils.h @@ -21,6 +21,7 @@ #include <unordered_set> #include <ir/element-utils.h> +#include <ir/module-utils.h> #include <pass.h> #include <wasm.h> @@ -84,10 +85,10 @@ inline void replaceFunctions(PassRunner* runner, name = iter->second; } }; - // replace direct calls - FunctionRefReplacer(maybeReplace).run(runner, &module); - // replace in table - ElementUtils::iterAllElementFunctionNames(&module, maybeReplace); + // replace direct calls in code both functions and module elements + FunctionRefReplacer replacer(maybeReplace); + replacer.run(runner, &module); + replacer.walkModuleCode(&module); // replace in start if (module.start.is()) { diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index 1f307c318..388584fd6 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -259,6 +259,25 @@ struct Walker : public VisitorType { self->walkMemory(&module->memory); } + // Walks module-level code, that is, code that is not in functions. + void walkModuleCode(Module* module) { + // Dispatch statically through the SubType. + SubType* self = static_cast<SubType*>(this); + for (auto& curr : module->globals) { + if (!curr->imported()) { + self->walk(curr->init); + } + } + for (auto& curr : module->elementSegments) { + if (curr->offset) { + self->walk(curr->offset); + } + for (auto* item : curr->data) { + self->walk(item); + } + } + } + // Walk implementation. We don't use recursion as ASTs may be highly // nested. diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 425792e22..8bc12cadf 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -1998,6 +1998,13 @@ void FunctionValidator::visitRefFunc(RefFunc* curr) { shouldBeTrue(curr->type.isFunction(), curr, "ref.func must have a function reference type"); + // TODO: verify it also has a typed function references type, and the right + // one, + // curr->type.getHeapType().getSignature() + // That is blocked on having the ability to create signature types in the C + // API (for now those users create the type with funcref). This also needs to + // be fixed in LegalizeJSInterface and FuncCastEmulation and other places that + // update function types. // TODO: check for non-nullability } @@ -2843,6 +2850,9 @@ static void validateTables(Module& module, ValidationInfo& info) { auto table = module.getTableOrNull(segment->table); info.shouldBeTrue( table != nullptr, "elem", "elem segment must have a valid table name"); + info.shouldBeTrue(!!segment->offset, + "elem", + "table segment offset should have an offset"); info.shouldBeEqual(segment->offset->type, Type(Type::i32), segment->offset, @@ -2853,6 +2863,10 @@ static void validateTables(Module& module, ValidationInfo& info) { segment->offset, "table segment offset should be reasonable"); validator.validate(segment->offset); + } else { + info.shouldBeTrue(!segment->offset, + "elem", + "non-table segment offset should have no offset"); } // Avoid double checking items if (module.features.hasReferenceTypes()) { |