diff options
-rw-r--r-- | src/wasm-s-parser.h | 30 | ||||
-rw-r--r-- | src/wasm-validator.h | 10 | ||||
-rw-r--r-- | test/passes/dce.wast | 3 | ||||
-rw-r--r-- | test/passes/duplicate-function-elimination.wast | 12 | ||||
-rw-r--r-- | test/passes/remove-unused-functions.wast | 3 | ||||
-rw-r--r-- | test/passes/remove-unused-names_merge-blocks.wast | 3 |
6 files changed, 42 insertions, 19 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 0f11bd521..abe0c4700 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -212,6 +212,10 @@ private: if (depth == 0) { break; } + } else if (input[0] == '\n') { + line++; + lineStart = input; + input++; } else { input++; } @@ -442,9 +446,11 @@ private: i++; } } +#if 0 if (exportName.is() && !name.is()) { name = exportName; // useful for debugging } +#endif return i; } @@ -461,6 +467,7 @@ private: ex->name = exportName; ex->value = name; ex->kind = Export::Function; + if (wasm.checkExport(ex->name)) throw ParseException("duplicate export", s.line, s.col); wasm.addExport(ex.release()); } functionCounter++; @@ -1394,6 +1401,7 @@ private: ex->name = inner[1]->str(); ex->value = wasm.memory.name; ex->kind = Export::Memory; + if (wasm.checkExport(ex->name)) throw ParseException("duplicate export", s.line, s.col); wasm.addExport(ex.release()); i++; } else { @@ -1461,32 +1469,27 @@ private: ex->name = s[1]->str(); if (s[2]->isList()) { auto& inner = *s[2]; + ex->value = inner[1]->str(); if (inner[0]->str() == FUNC) { - ex->value = inner[1]->str(); ex->kind = Export::Function; } else if (inner[0]->str() == MEMORY) { if (!hasMemory) throw ParseException("memory exported but no memory"); - ex->value = Name::fromInt(0); ex->kind = Export::Memory; } else if (inner[0]->str() == TABLE) { - ex->value = Name::fromInt(0); ex->kind = Export::Table; } else if (inner[0]->str() == GLOBAL) { - ex->value = inner[1]->str(); ex->kind = Export::Global; } else { WASM_UNREACHABLE(); } } else if (!s[2]->dollared() && !std::isdigit(s[2]->str()[0])) { + ex->value = s[3]->str(); if (s[2]->str() == MEMORY) { if (!hasMemory) throw ParseException("memory exported but no memory"); - ex->value = Name::fromInt(0); ex->kind = Export::Memory; } else if (s[2]->str() == TABLE) { - ex->value = Name::fromInt(0); ex->kind = Export::Table; } else if (s[2]->str() == GLOBAL) { - ex->value = s[3]->str(); ex->kind = Export::Global; } else { WASM_UNREACHABLE(); @@ -1496,6 +1499,7 @@ private: ex->value = s[2]->str(); ex->kind = Export::Function; } + if (wasm.checkExport(ex->name)) throw ParseException("duplicate export", s.line, s.col); wasm.addExport(ex.release()); } @@ -1591,6 +1595,7 @@ private: ex->name = inner[1]->str(); ex->value = global->name; ex->kind = Export::Global; + if (wasm.checkExport(ex->name)) throw ParseException("duplicate export", s.line, s.col); wasm.addExport(ex.release()); i++; } else { @@ -1609,11 +1614,9 @@ private: seenTable = true; Index i = 1; if (i == s.size()) return; // empty table in old notation -#if 0 // TODO: new table notation if (s[i]->dollared()) { wasm.table.name = s[i++]->str(); } -#endif if (i == s.size()) return; if (s[i]->isList()) { auto& inner = *s[i]; @@ -1622,6 +1625,7 @@ private: ex->name = inner[1]->str(); ex->value = wasm.table.name; ex->kind = Export::Table; + if (wasm.checkExport(ex->name)) throw ParseException("duplicate export", s.line, s.col); wasm.addExport(ex.release()); i++; } else { @@ -1639,8 +1643,12 @@ private: // first element isn't dollared, and isn't anyfunc. this could be old syntax for (table 0 1) which means function 0 and 1, or it could be (table initial max? type), look for type if (s[s.size() - 1]->str() == ANYFUNC) { // (table initial max? type) - wasm.table.initial = atoi(s[i]->c_str()); - wasm.table.max = atoi(s[i + 1]->c_str()); + if (i < s.size() - 1) { + wasm.table.initial = atoi(s[i++]->c_str()); + } + if (i < s.size() - 1) { + wasm.table.max = atoi(s[i++]->c_str()); + } return; } } diff --git a/src/wasm-validator.h b/src/wasm-validator.h index e23221337..1d3b5c41b 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -394,7 +394,15 @@ public: break; } } - shouldBeTrue(found, name, "module exports must be found"); + shouldBeTrue(found, name, "module function exports must be found"); + } else if (exp->kind == Export::Global) { + shouldBeTrue(curr->checkGlobal(name), name, "module global exports must be found"); + } else if (exp->kind == Export::Table) { + shouldBeTrue(name == Name("0") || name == curr->table.name, name, "module table exports must be found"); + } else if (exp->kind == Export::Memory) { + shouldBeTrue(name == Name("0") || name == curr->memory.name, name, "module memory exports must be found"); + } else { + WASM_UNREACHABLE(); } Name exportName = exp->name; shouldBeFalse(exportNames.count(exportName) > 0, exportName, "module exports must be unique"); diff --git a/test/passes/dce.wast b/test/passes/dce.wast index 61b3138e5..9795bda80 100644 --- a/test/passes/dce.wast +++ b/test/passes/dce.wast @@ -2,7 +2,8 @@ (memory 10) (type $ii (func (param i32 i32))) (type $1 (func)) - (table $call-me) + (table 1 1 anyfunc) + (elem (i32.const 0) $call-me) (func $call-me (type $ii) (param $0 i32) (param $1 i32) (nop) ) diff --git a/test/passes/duplicate-function-elimination.wast b/test/passes/duplicate-function-elimination.wast index 959737f40..fcd2378e1 100644 --- a/test/passes/duplicate-function-elimination.wast +++ b/test/passes/duplicate-function-elimination.wast @@ -54,7 +54,8 @@ (type $0 (func)) (export "keep2" $keep2) (export "other" $other) - (table $keep2 $other $caller) + (table 3 3 anyfunc) + (elem (i32.const 0) $keep2 $other $caller) (func $keep2 (type $0) (nop) ) @@ -460,7 +461,8 @@ (module (memory 0) (type $T (func)) - (table $erase $other) + (table 2 2 anyfunc) + (elem (i32.const 0) $erase $other) (func $erase (type $T) (call_indirect $T (i32.const 0) @@ -475,7 +477,8 @@ (module (memory 0) (type $T (func)) - (table $keep2 $other) + (table 2 2 anyfunc) + (elem (i32.const 0) $keep2 $other) (func $keep2 (type $T) (call_indirect $T (i32.const 0) @@ -491,7 +494,8 @@ (memory 0) (type $T (func)) (type $S (func)) - (table $keep2 $other) + (table 2 2 anyfunc) + (elem (i32.const 0) $keep2 $other) (func $keep2 (type $T) (call_indirect $T (i32.const 0) diff --git a/test/passes/remove-unused-functions.wast b/test/passes/remove-unused-functions.wast index 9449a25cb..19b72f2ac 100644 --- a/test/passes/remove-unused-functions.wast +++ b/test/passes/remove-unused-functions.wast @@ -3,7 +3,8 @@ (start $start) (type $0 (func)) (export "exported" $exported) - (table $called_indirect) + (table 1 1 anyfunc) + (elem (i32.const 0) $called_indirect) (func $start (type $0) (call $called0) ) diff --git a/test/passes/remove-unused-names_merge-blocks.wast b/test/passes/remove-unused-names_merge-blocks.wast index 562c5bbba..64bc8ab7f 100644 --- a/test/passes/remove-unused-names_merge-blocks.wast +++ b/test/passes/remove-unused-names_merge-blocks.wast @@ -4,7 +4,8 @@ (type $ii (func (param i32 i32))) (type $iii (func (param i32 i32 i32))) (type $3 (func)) - (table $call-i) + (table 1 1 anyfunc) + (elem (i32.const 0) $call-i) (func $call-i (type $i) (param $0 i32) (nop) ) |