summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-s-parser.h30
-rw-r--r--src/wasm-validator.h10
-rw-r--r--test/passes/dce.wast3
-rw-r--r--test/passes/duplicate-function-elimination.wast12
-rw-r--r--test/passes/remove-unused-functions.wast3
-rw-r--r--test/passes/remove-unused-names_merge-blocks.wast3
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)
)