summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/DeadArgumentElimination.cpp7
-rw-r--r--src/passes/Inlining.cpp14
-rw-r--r--src/passes/opt-utils.h9
-rw-r--r--src/wasm-traversal.h19
-rw-r--r--src/wasm/wasm-validator.cpp14
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()) {