summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Bouvier <public@benj.me>2016-10-13 19:41:59 +0200
committerAlon Zakai <alonzakai@gmail.com>2016-10-13 10:41:59 -0700
commit95d00d699c9e05b8a04885d019a09d8d2eebd0b5 (patch)
tree7a8426152e015ba1f614f5492472e0d0084d81f6
parentb4d7c60d82fc336e401026e7ba6dd67138259ae2 (diff)
downloadbinaryen-95d00d699c9e05b8a04885d019a09d8d2eebd0b5.tar.gz
binaryen-95d00d699c9e05b8a04885d019a09d8d2eebd0b5.tar.bz2
binaryen-95d00d699c9e05b8a04885d019a09d8d2eebd0b5.zip
Don't create a memory section for an imported memory; fixes #772 (#773)
-rw-r--r--src/asm2wasm.h2
-rw-r--r--src/passes/Print.cpp9
-rw-r--r--src/wasm-binary.h6
-rw-r--r--src/wasm-s-parser.h26
-rw-r--r--src/wasm-validator.h3
-rw-r--r--src/wasm.h6
-rw-r--r--test/memory-import.wast9
-rw-r--r--test/memory-import.wast.fromBinary10
-rw-r--r--test/memory-import.wast.fromBinary.noDebugInfo10
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)
+ )
+ )
+)
+