summaryrefslogtreecommitdiff
path: root/src/wasm-validator.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-validator.h')
-rw-r--r--src/wasm-validator.h91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/wasm-validator.h b/src/wasm-validator.h
new file mode 100644
index 000000000..49e7a6a33
--- /dev/null
+++ b/src/wasm-validator.h
@@ -0,0 +1,91 @@
+
+//
+// Simple WebAssembly module validator.
+//
+
+#include "wasm.h"
+
+namespace wasm {
+
+struct WasmValidator : public WasmWalker {
+ bool valid;
+
+public:
+ bool validate(Module& module) {
+ valid = true;
+ startWalk(&module);
+ return valid;
+ }
+
+ // visitors
+
+ void visitSetLocal(SetLocal *curr) override {
+ shouldBeTrue(curr->type == curr->value->type);
+ }
+ void visitLoad(Load *curr) override {
+ validateAlignment(curr->align);
+ }
+ void visitStore(Store *curr) override {
+ validateAlignment(curr->align);
+ }
+ void visitSwitch(Switch *curr) override {
+ std::set<Name> inTable;
+ for (auto target : curr->targets) {
+ if (target.is()) {
+ inTable.insert(target);
+ }
+ }
+ for (auto& c : curr->cases) {
+ shouldBeFalse(c.name.is() && inTable.find(c.name) == inTable.end());
+ }
+ shouldBeFalse(curr->default_.is() && inTable.find(curr->default_) == inTable.end());
+ }
+ void visitMemory(Memory *curr) override {
+ shouldBeFalse(curr->initial > curr->max);
+ size_t top = 0;
+ for (auto segment : curr->segments) {
+ shouldBeFalse(segment.offset < top);
+ top = segment.offset + segment.size;
+ }
+ shouldBeFalse(top > curr->initial);
+ }
+ void visitModule(Module *curr) override {
+ for (auto& exp : curr->exports) {
+ Name name = exp->name;
+ bool found = false;
+ for (auto& func : curr->functions) {
+ if (func->name == name) {
+ found = true;
+ break;
+ }
+ }
+ shouldBeTrue(found);
+ }
+ }
+
+private:
+ // helpers
+
+ void shouldBeTrue(bool result) {
+ if (!result) valid = false;
+ }
+ void shouldBeFalse(bool result) {
+ if (result) valid = false;
+ }
+
+ void validateAlignment(size_t align) {
+ switch (align) {
+ case 1:
+ case 2:
+ case 4:
+ case 8: break;
+ default:{
+ valid = false;
+ break;
+ }
+ }
+ }
+};
+
+} // namespace wasm
+