diff options
-rw-r--r-- | src/asm2wasm.h | 2 | ||||
-rw-r--r-- | src/passes/Print.cpp | 9 | ||||
-rw-r--r-- | src/wasm-binary.h | 6 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 26 | ||||
-rw-r--r-- | src/wasm-validator.h | 3 | ||||
-rw-r--r-- | src/wasm.h | 6 | ||||
-rw-r--r-- | test/memory-import.wast | 9 | ||||
-rw-r--r-- | test/memory-import.wast.fromBinary | 10 | ||||
-rw-r--r-- | test/memory-import.wast.fromBinary.noDebugInfo | 10 |
9 files changed, 61 insertions, 20 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 9bf677e6f..836b8044a 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -998,6 +998,8 @@ void Asm2WasmBuilder::processAsm(Ref ast) { memoryImport->module = ENV; memoryImport->base = MEMORY; memoryImport->kind = ExternalKind::Memory; + wasm.memory.exists = true; + wasm.memory.imported = true; wasm.addImport(memoryImport.release()); // import table diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 075d013e5..c6fca0256 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -649,14 +649,7 @@ struct PrintSExpression : public Visitor<PrintSExpression> { } void visitMemory(Memory* curr) { // if memory wasn't imported, declare it - bool found = false; - for (auto& import : currModule->imports) { - if (import->kind == ExternalKind::Memory) { - found = true; - break; - } - } - if (!found) { + if (!curr->imported) { doIndent(o, indent); printMemoryHeader(curr); o << '\n'; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 43a43b5c4..bdde2121e 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -586,7 +586,7 @@ public: } void writeMemory() { - if (wasm->memory.max == 0) return; + if (!wasm->memory.exists || wasm->memory.imported) return; if (debug) std::cerr << "== writeMemory" << std::endl; auto start = startSection(BinaryConsts::Section::Memory); o << U32LEB(1); // Define 1 memory @@ -1559,6 +1559,8 @@ public: auto numMemories = getU32LEB(); if (!numMemories) return; assert(numMemories == 1); + if (wasm.memory.exists) throw ParseException("Memory cannot be both imported and defined"); + wasm.memory.exists = true; getResizableLimits(wasm.memory.initial, wasm.memory.max, Memory::kMaxSize); } @@ -1641,6 +1643,8 @@ public: break; } case ExternalKind::Memory: { + wasm.memory.exists = true; + wasm.memory.imported = true; getResizableLimits(wasm.memory.initial, wasm.memory.max, Memory::kMaxSize); break; } diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index fda413f80..7946134cd 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -1447,11 +1447,10 @@ private: data.resize(actual); } - bool hasMemory = false; - void parseMemory(Element& s, bool preParseImport = false) { - if (hasMemory) throw ParseException("too many memories"); - hasMemory = true; + if (wasm.memory.exists) throw ParseException("too many memories"); + wasm.memory.exists = true; + wasm.memory.imported = preParseImport; Index i = 1; if (s[i]->dollared()) { wasm.memory.name = s[i++]->str(); @@ -1470,6 +1469,12 @@ private: } else if (inner[0]->str() == IMPORT) { importModule = inner[1]->str(); importBase = inner[2]->str(); + auto im = make_unique<Import>(); + im->kind = ExternalKind::Memory; + im->module = importModule; + im->base = importBase; + im->name = importModule; + wasm.addImport(im.release()); i++; } else { assert(inner.size() > 0 ? inner[0]->str() != IMPORT : true); @@ -1512,7 +1517,7 @@ private: } void parseData(Element& s) { - if (!hasMemory) throw ParseException("data but no memory"); + if (!wasm.memory.exists) throw ParseException("data but no memory"); Index i = 1; if (!s[i]->isList()) { // the memory is named @@ -1545,7 +1550,7 @@ private: if (inner[0]->str() == FUNC) { ex->kind = ExternalKind::Function; } else if (inner[0]->str() == MEMORY) { - if (!hasMemory) throw ParseException("memory exported but no memory"); + if (!wasm.memory.exists) throw ParseException("memory exported but no memory"); ex->kind = ExternalKind::Memory; } else if (inner[0]->str() == TABLE) { ex->kind = ExternalKind::Table; @@ -1558,7 +1563,7 @@ private: } 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"); + if (!wasm.memory.exists) throw ParseException("memory exported but no memory"); ex->kind = ExternalKind::Memory; } else if (s[2]->str() == TABLE) { ex->kind = ExternalKind::Table; @@ -1585,8 +1590,9 @@ private: im->kind = ExternalKind::Function; } else if ((*s[3])[0]->str() == MEMORY) { im->kind = ExternalKind::Memory; - if (hasMemory) throw ParseException("too many memories"); - hasMemory = true; + if (wasm.memory.exists) throw ParseException("more than one memory"); + wasm.memory.exists = true; + wasm.memory.imported = true; } else if ((*s[3])[0]->str() == TABLE) { im->kind = ExternalKind::Table; if (wasm.table.exists) throw ParseException("more than one table"); @@ -1790,7 +1796,7 @@ private: im->kind = ExternalKind::Table; im->module = importModule; im->base = importBase; - im->name = importModule;// + "." + importBase; + im->name = importModule; wasm.addImport(im.release()); i++; } else { diff --git a/src/wasm-validator.h b/src/wasm-validator.h index d01e61407..ad2b7e1a3 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -387,6 +387,9 @@ public: if (curr->kind == ExternalKind::Table) { shouldBeTrue(getModule()->table.imported, curr->name, "Table import record exists but table is not marked as imported"); } + if (curr->kind == ExternalKind::Memory) { + shouldBeTrue(getModule()->memory.imported, curr->name, "Memory import record exists but memory is not marked as imported"); + } } void visitExport(Export* curr) { diff --git a/src/wasm.h b/src/wasm.h index 0f542294c..44326948b 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1502,7 +1502,11 @@ public: Address initial, max; // sizes are in pages std::vector<Segment> segments; - Memory() : initial(0), max(kMaxSize) { + // See comment in Table. + bool exists; + bool imported; + + Memory() : initial(0), max(kMaxSize), exists(false), imported(false) { name = Name::fromInt(0); } }; diff --git a/test/memory-import.wast b/test/memory-import.wast new file mode 100644 index 000000000..d7e6e3770 --- /dev/null +++ b/test/memory-import.wast @@ -0,0 +1,9 @@ +(module + (type $0 (func (result i32))) + (import "env" "memory" (memory $0 1 1)) + (func $foo (type $0) (result i32) + (i32.load offset=13 + (i32.const 37) + ) + ) +) diff --git a/test/memory-import.wast.fromBinary b/test/memory-import.wast.fromBinary new file mode 100644 index 000000000..1ba3cb0f3 --- /dev/null +++ b/test/memory-import.wast.fromBinary @@ -0,0 +1,10 @@ +(module + (type $0 (func (result i32))) + (import "env" "memory" (memory $0 1 1)) + (func $foo (type $0) (result i32) + (i32.load offset=13 + (i32.const 37) + ) + ) +) + diff --git a/test/memory-import.wast.fromBinary.noDebugInfo b/test/memory-import.wast.fromBinary.noDebugInfo new file mode 100644 index 000000000..2ddf90ce9 --- /dev/null +++ b/test/memory-import.wast.fromBinary.noDebugInfo @@ -0,0 +1,10 @@ +(module + (type $0 (func (result i32))) + (import "env" "memory" (memory $0 1 1)) + (func $0 (type $0) (result i32) + (i32.load offset=13 + (i32.const 37) + ) + ) +) + |