diff options
-rw-r--r-- | src/asm2wasm.h | 2 | ||||
-rw-r--r-- | src/passes/Print.cpp | 15 | ||||
-rw-r--r-- | src/wasm-binary.h | 4 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 9 | ||||
-rw-r--r-- | src/wasm-validator.h | 3 | ||||
-rw-r--r-- | src/wasm.h | 3 | ||||
-rw-r--r-- | test/table-import.wast | 9 | ||||
-rw-r--r-- | test/table-import.wast.fromBinary | 10 | ||||
-rw-r--r-- | test/table-import.wast.fromBinary.noDebugInfo | 10 |
9 files changed, 52 insertions, 13 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index acf973a69..b2e7f5512 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1003,6 +1003,8 @@ void Asm2WasmBuilder::processAsm(Ref ast) { tableImport->base = TABLE; tableImport->kind = ExternalKind::Table; wasm.addImport(tableImport.release()); + wasm.table.exists = true; + wasm.table.imported = true; // Import memory offset { diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 0a2026f25..33b5f5d16 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -620,19 +620,12 @@ struct PrintSExpression : public Visitor<PrintSExpression> { } void visitTable(Table *curr) { // if table wasn't imported, declare it - bool found = false; - for (auto& import : currModule->imports) { - if (import->kind == ExternalKind::Table) { - found = true; - break; - } - } - if (!found) { + if (!curr->imported) { doIndent(o, indent); printTableHeader(curr); + o << maybeNewLine; } if (curr->segments.empty()) return; - if (!found) o << '\n'; doIndent(o, indent); for (auto& segment : curr->segments) { // Don't print empty segments @@ -645,6 +638,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> { } o << ')'; } + o << maybeNewLine; } void printMemoryHeader(Memory* curr) { printOpening(o, "memory") << ' '; @@ -712,8 +706,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> { o << maybeNewLine; } if (curr->table.exists) { - visitTable(&curr->table); - o << maybeNewLine; + visitTable(&curr->table); // Prints its own newlines } visitMemory(&curr->memory); for (auto& child : curr->globals) { diff --git a/src/wasm-binary.h b/src/wasm-binary.h index dcbe7d6db..eef315fda 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -845,7 +845,7 @@ public: } void writeFunctionTableDeclaration() { - if (!wasm->table.exists) return; // or is imported!! + if (!wasm->table.exists || wasm->table.imported) return; if (debug) std::cerr << "== writeFunctionTableDeclaration" << std::endl; auto start = startSection(BinaryConsts::Section::Table); o << U32LEB(1); // Declare 1 table. @@ -1639,6 +1639,7 @@ public: WASM_UNUSED(elementType); if (elementType != BinaryConsts::ElementType::AnyFunc) throw ParseException("Imported table type is not AnyFunc"); wasm.table.exists = true; + wasm.table.imported = true; getResizableLimits(wasm.table.initial, &wasm.table.max); break; } @@ -1892,6 +1893,7 @@ public: if (debug) std::cerr << "== readFunctionTableDeclaration" << std::endl; auto numTables = getU32LEB(); if (numTables != 1) throw ParseException("Only 1 table definition allowed in MVP"); + if (wasm.table.exists) throw ParseException("Table cannot be both imported and defined"); wasm.table.exists = true; auto elemType = getU32LEB(); if (elemType != BinaryConsts::ElementType::AnyFunc) throw ParseException("ElementType must be AnyFunc in MVP"); diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 7f5afe8f7..3e09d4f6f 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -1591,6 +1591,7 @@ private: im->kind = ExternalKind::Table; if (wasm.table.exists) throw ParseException("more than one table"); wasm.table.exists = true; + wasm.table.imported = true; } else if ((*s[3])[0]->str() == GLOBAL) { im->kind = ExternalKind::Global; } else { @@ -1765,6 +1766,7 @@ private: void parseTable(Element& s, bool preParseImport = false) { if (wasm.table.exists) throw ParseException("more than one table"); wasm.table.exists = true; + wasm.table.imported = preParseImport; Index i = 1; if (i == s.size()) return; // empty table in old notation if (s[i]->dollared()) { @@ -1785,6 +1787,13 @@ private: } else if (inner[0]->str() == IMPORT) { importModule = inner[1]->str(); importBase = inner[2]->str(); + assert(preParseImport); + auto im = make_unique<Import>(); + im->kind = ExternalKind::Table; + im->module = importModule; + im->base = importBase; + im->name = importModule;// + "." + importBase; + wasm.addImport(im.release()); i++; } else { WASM_UNREACHABLE(); diff --git a/src/wasm-validator.h b/src/wasm-validator.h index cb226a924..d01e61407 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -384,6 +384,9 @@ public: } } } + if (curr->kind == ExternalKind::Table) { + shouldBeTrue(getModule()->table.imported, curr->name, "Table import record exists but table is not marked as imported"); + } } void visitExport(Export* curr) { diff --git a/src/wasm.h b/src/wasm.h index ca9392d98..0f542294c 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1469,11 +1469,12 @@ public: // Currently the wasm object always 'has' one Table. It 'exists' if it has been defined or imported. // The table can exist but be empty and have no defined initial or max size. bool exists; + bool imported; Name name; Address initial, max; std::vector<Segment> segments; - Table() : exists(false), initial(0), max(kMaxSize) { + Table() : exists(false), imported(false), initial(0), max(kMaxSize) { name = Name::fromInt(0); } }; diff --git a/test/table-import.wast b/test/table-import.wast new file mode 100644 index 000000000..6d40941e2 --- /dev/null +++ b/test/table-import.wast @@ -0,0 +1,9 @@ +(module + (type $0 (func)) + (import "env" "table" (table 1 1 anyfunc)) + (elem (i32.const 0) $foo) + (memory $0 0) + (func $foo (type $0) + (nop) + ) +) diff --git a/test/table-import.wast.fromBinary b/test/table-import.wast.fromBinary new file mode 100644 index 000000000..38efc07a4 --- /dev/null +++ b/test/table-import.wast.fromBinary @@ -0,0 +1,10 @@ +(module + (type $0 (func)) + (import "env" "table" (table 1 1 anyfunc)) + (elem (i32.const 0) $foo) + (memory $0 0) + (func $foo (type $0) + (nop) + ) +) + diff --git a/test/table-import.wast.fromBinary.noDebugInfo b/test/table-import.wast.fromBinary.noDebugInfo new file mode 100644 index 000000000..52852faf8 --- /dev/null +++ b/test/table-import.wast.fromBinary.noDebugInfo @@ -0,0 +1,10 @@ +(module + (type $0 (func)) + (import "env" "table" (table 1 1 anyfunc)) + (elem (i32.const 0) $0) + (memory $0 0) + (func $0 (type $0) + (nop) + ) +) + |