summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-validator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r--src/wasm/wasm-validator.cpp19
1 files changed, 12 insertions, 7 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index 819602608..e30661e8f 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -62,7 +62,7 @@ void WasmValidator::visitBlock(Block *curr) {
}
if (curr->list.size() > 1) {
for (Index i = 0; i < curr->list.size() - 1; i++) {
- if (!shouldBeTrue(!isConcreteWasmType(curr->list[i]->type), curr, "non-final block elements returning a value must be drop()ed (binaryen's autodrop option might help you)")) {
+ if (!shouldBeTrue(!isConcreteWasmType(curr->list[i]->type), curr, "non-final block elements returning a value must be drop()ed (binaryen's autodrop option might help you)") && !quiet) {
std::cerr << "(on index " << i << ":\n" << curr->list[i] << "\n), type: " << curr->list[i]->type << "\n";
}
}
@@ -170,14 +170,14 @@ void WasmValidator::visitCall(Call *curr) {
if (!validateGlobally) return;
auto* target = getModule()->getFunctionOrNull(curr->target);
if (!shouldBeTrue(!!target, curr, "call target must exist")) {
- if (getModule()->getImportOrNull(curr->target)) {
+ if (getModule()->getImportOrNull(curr->target) && !quiet) {
std::cerr << "(perhaps it should be a CallImport instead of Call?)\n";
}
return;
}
if (!shouldBeTrue(curr->operands.size() == target->params.size(), curr, "call param number must match")) return;
for (size_t i = 0; i < curr->operands.size(); i++) {
- if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, target->params[i], curr, "call param types must match")) {
+ if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, target->params[i], curr, "call param types must match") && !quiet) {
std::cerr << "(on argument " << i << ")\n";
}
}
@@ -190,7 +190,7 @@ void WasmValidator::visitCallImport(CallImport *curr) {
auto* type = getModule()->getFunctionType(import->functionType);
if (!shouldBeTrue(curr->operands.size() == type->params.size(), curr, "call param number must match")) return;
for (size_t i = 0; i < curr->operands.size(); i++) {
- if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, type->params[i], curr, "call param types must match")) {
+ if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, type->params[i], curr, "call param types must match") && !quiet) {
std::cerr << "(on argument " << i << ")\n";
}
}
@@ -202,7 +202,7 @@ void WasmValidator::visitCallIndirect(CallIndirect *curr) {
shouldBeEqualOrFirstIsUnreachable(curr->target->type, i32, curr, "indirect call target must be an i32");
if (!shouldBeTrue(curr->operands.size() == type->params.size(), curr, "call param number must match")) return;
for (size_t i = 0; i < curr->operands.size(); i++) {
- if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, type->params[i], curr, "call param types must match")) {
+ if (!shouldBeEqualOrFirstIsUnreachable(curr->operands[i]->type, type->params[i], curr, "call param types must match") && !quiet) {
std::cerr << "(on argument " << i << ")\n";
}
}
@@ -534,7 +534,7 @@ void WasmValidator::visitGlobal(Global* curr) {
if (!validateGlobally) return;
shouldBeTrue(curr->init != nullptr, curr->name, "global init must be non-null");
shouldBeTrue(curr->init->is<Const>() || curr->init->is<GetGlobal>(), curr->name, "global init must be valid");
- if (!shouldBeEqual(curr->type, curr->init->type, curr->init, "global init must have correct type")) {
+ if (!shouldBeEqual(curr->type, curr->init->type, curr->init, "global init must have correct type") && !quiet) {
std::cerr << "(on global " << curr->name << ")\n";
}
}
@@ -548,7 +548,7 @@ void WasmValidator::visitFunction(Function *curr) {
if (returnType != unreachable) {
shouldBeEqual(curr->result, returnType, curr->body, "function result must match, if function has returns");
}
- if (!shouldBeTrue(namedBreakTargets.empty(), curr->body, "all named break targets must exist (even if not taken)")) {
+ if (!shouldBeTrue(namedBreakTargets.empty(), curr->body, "all named break targets must exist (even if not taken)") && !quiet) {
std::cerr << "(on label " << *namedBreakTargets.begin() << ")\n";
}
returnType = unreachable;
@@ -592,6 +592,9 @@ void WasmValidator::visitTable(Table* curr) {
for (auto& segment : curr->segments) {
shouldBeEqual(segment.offset->type, i32, segment.offset, "segment offset should be i32");
shouldBeTrue(checkOffset(segment.offset, segment.data.size(), getModule()->table.initial * Table::kPageSize), segment.offset, "segment offset should be reasonable");
+ for (auto name : segment.data) {
+ shouldBeTrue(getModule()->getFunctionOrNull(name) || getModule()->getImportOrNull(name), name, "segment name should be valid");
+ }
}
}
void WasmValidator::visitModule(Module *curr) {
@@ -698,11 +701,13 @@ void WasmValidator::validateBinaryenIR(Module& wasm) {
template <typename T, typename S>
std::ostream& WasmValidator::fail(S text, T curr) {
valid = false;
+ if (quiet) return std::cerr;
auto& ret = printFailureHeader() << text << ", on \n";
return printModuleComponent(curr, ret);
}
std::ostream& WasmValidator::printFailureHeader() {
+ if (quiet) return std::cerr;
Colors::red(std::cerr);
if (getFunction()) {
std::cerr << "[wasm-validator error in function ";