summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-11-06 09:20:46 -0800
committerAlon Zakai <alonzakai@gmail.com>2015-11-06 09:20:46 -0800
commitec70dbcb17d8acace08e8abe9cc0ea30e0c825d1 (patch)
treefaf13b02284568c306077d37d3c25e95f1a82e09
parent38b6e18b5b563ee235f426d695a89c20cb08ada5 (diff)
downloadbinaryen-ec70dbcb17d8acace08e8abe9cc0ea30e0c825d1.tar.gz
binaryen-ec70dbcb17d8acace08e8abe9cc0ea30e0c825d1.tar.bz2
binaryen-ec70dbcb17d8acace08e8abe9cc0ea30e0c825d1.zip
more module validation
-rwxr-xr-xcheck.py2
-rw-r--r--src/wasm.h39
2 files changed, 40 insertions, 1 deletions
diff --git a/check.py b/check.py
index 869b0886a..a2353ad54 100755
--- a/check.py
+++ b/check.py
@@ -84,7 +84,7 @@ if len(requested) == 0:
# 'address' : filed issue, test looks invalid
# 'exports', 'int_literals' : has a "return" https://github.com/WebAssembly/spec/issues/164
# 'switch': todo once stable
- spec_tests = [os.path.join('spec', t + '.wast') for t in ['conversions', 'endianness', 'f32_cmp', 'f32', 'f64_cmp', 'f64', 'float_exprs', 'forward', 'func_ptrs', 'functions', 'has_feature', 'i32', 'i64', 'imports', 'int_exprs', 'left-to-right', 'memory_redundancy']]
+ spec_tests = [os.path.join('spec', t + '.wast') for t in ['conversions', 'endianness', 'f32_cmp', 'f32', 'f64_cmp', 'f64', 'float_exprs', 'forward', 'func_ptrs', 'functions', 'has_feature', 'i32', 'i64', 'imports', 'int_exprs', 'left-to-right', 'memory_redundancy', 'memory_trap']]
else:
spec_tests = requested[:]
diff --git a/src/wasm.h b/src/wasm.h
index 0104e45df..5991f88e3 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -983,6 +983,13 @@ public:
}
bool validate() {
+ if (memory.initial > memory.max) return false;
+ size_t top = 0;
+ for (auto segment : memory.segments) {
+ if (segment.offset < top) return false;
+ top = segment.offset + segment.size;
+ }
+ if (top > memory.initial) return false;
for (auto& exp : exports) {
Name name = exp->name;
bool found = false;
@@ -994,9 +1001,14 @@ public:
}
if (!found) return false;
}
+ for (auto& curr : functions) {
+ if (!validateFunction(curr)) return false;
+ }
return true;
}
+ bool validateFunction(Function *func);
+
private:
size_t functionTypeIndex, importIndex, exportIndex, functionIndex;
};
@@ -1243,6 +1255,33 @@ struct WasmWalker : public WasmVisitor<void> {
}
};
+bool Module::validateFunction(Function *func) {
+ struct Validator : public WasmWalker {
+ bool valid = true;
+
+ void visitLoad(Load *curr) override {
+ if (!validateAlignment(curr->align)) valid = false;
+ }
+ void visitStore(Store *curr) override {
+ if (!validateAlignment(curr->align)) valid = false;
+ }
+
+ bool validateAlignment(size_t align) {
+ switch (align) {
+ case 1:
+ case 2:
+ case 4:
+ case 8: return true;
+ default: return false;
+ }
+ }
+ };
+
+ Validator validator;
+ validator.walk(func->body);
+ return validator.valid;
+}
+
} // namespace wasm
#endif // __wasm_h__