diff options
Diffstat (limited to 'src/shell-interface.h')
-rw-r--r-- | src/shell-interface.h | 140 |
1 files changed, 117 insertions, 23 deletions
diff --git a/src/shell-interface.h b/src/shell-interface.h index d1cf3290e..98349055b 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -57,8 +57,6 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { static_assert(!(sizeof(T) & (sizeof(T) - 1)), "must be a power of 2"); return 0 == (reinterpret_cast<uintptr_t>(address) & (sizeof(T) - 1)); } - Memory(Memory&) = delete; - Memory& operator=(const Memory&) = delete; public: Memory() = default; @@ -92,14 +90,14 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { return loaded; } } - } memory; + }; + std::map<Name, Memory> memories; std::unordered_map<Name, std::vector<Literal>> tables; std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances; ShellExternalInterface( - std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances_ = {}) - : memory() { + std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances_ = {}) { linkedInstances.swap(linkedInstances_); } virtual ~ShellExternalInterface() = default; @@ -114,9 +112,11 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { } void init(Module& wasm, ModuleRunner& instance) override { - if (wasm.memory.exists && !wasm.memory.imported()) { - memory.resize(wasm.memory.initial * wasm::Memory::kPageSize); - } + ModuleUtils::iterDefinedMemories(wasm, [&](wasm::Memory* memory) { + auto shellMemory = Memory(); + shellMemory.resize(memory->initial * wasm::Memory::kPageSize); + memories[memory->name] = shellMemory; + }); ModuleUtils::iterDefinedTables( wasm, [&](Table* table) { tables[table->name].resize(table->initial); }); } @@ -195,31 +195,119 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { } } - int8_t load8s(Address addr) override { return memory.get<int8_t>(addr); } - uint8_t load8u(Address addr) override { return memory.get<uint8_t>(addr); } - int16_t load16s(Address addr) override { return memory.get<int16_t>(addr); } - uint16_t load16u(Address addr) override { return memory.get<uint16_t>(addr); } - int32_t load32s(Address addr) override { return memory.get<int32_t>(addr); } - uint32_t load32u(Address addr) override { return memory.get<uint32_t>(addr); } - int64_t load64s(Address addr) override { return memory.get<int64_t>(addr); } - uint64_t load64u(Address addr) override { return memory.get<uint64_t>(addr); } - std::array<uint8_t, 16> load128(Address addr) override { + int8_t load8s(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load8s on non-existing memory"); + } + auto& memory = it->second; + return memory.get<int8_t>(addr); + } + uint8_t load8u(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load8u on non-existing memory"); + } + auto& memory = it->second; + return memory.get<uint8_t>(addr); + } + int16_t load16s(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load16s on non-existing memory"); + } + auto& memory = it->second; + return memory.get<int16_t>(addr); + } + uint16_t load16u(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load16u on non-existing memory"); + } + auto& memory = it->second; + return memory.get<uint16_t>(addr); + } + int32_t load32s(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load32s on non-existing memory"); + } + auto& memory = it->second; + return memory.get<int32_t>(addr); + } + uint32_t load32u(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load32u on non-existing memory"); + } + auto& memory = it->second; + return memory.get<uint32_t>(addr); + } + int64_t load64s(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load64s on non-existing memory"); + } + auto& memory = it->second; + return memory.get<int64_t>(addr); + } + uint64_t load64u(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load64u on non-existing memory"); + } + auto& memory = it->second; + return memory.get<uint64_t>(addr); + } + std::array<uint8_t, 16> load128(Address addr, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("load128 on non-existing memory"); + } + auto& memory = it->second; return memory.get<std::array<uint8_t, 16>>(addr); } - void store8(Address addr, int8_t value) override { + void store8(Address addr, int8_t value, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("store8 on non-existing memory"); + } + auto& memory = it->second; memory.set<int8_t>(addr, value); } - void store16(Address addr, int16_t value) override { + void store16(Address addr, int16_t value, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("store16 on non-existing memory"); + } + auto& memory = it->second; memory.set<int16_t>(addr, value); } - void store32(Address addr, int32_t value) override { + void store32(Address addr, int32_t value, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("store32 on non-existing memory"); + } + auto& memory = it->second; memory.set<int32_t>(addr, value); } - void store64(Address addr, int64_t value) override { + void store64(Address addr, int64_t value, Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("store64 on non-existing memory"); + } + auto& memory = it->second; memory.set<int64_t>(addr, value); } - void store128(Address addr, const std::array<uint8_t, 16>& value) override { + void store128(Address addr, + const std::array<uint8_t, 16>& value, + Name memoryName) override { + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("store128 on non-existing memory"); + } + auto& memory = it->second; memory.set<std::array<uint8_t, 16>>(addr, value); } @@ -250,12 +338,18 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { return table[index]; } - bool growMemory(Address /*oldSize*/, Address newSize) override { + bool + growMemory(Name memoryName, Address /*oldSize*/, Address newSize) override { // Apply a reasonable limit on memory size, 1GB, to avoid DOS on the // interpreter. if (newSize > 1024 * 1024 * 1024) { return false; } + auto it = memories.find(memoryName); + if (it == memories.end()) { + trap("growMemory on non-existing memory"); + } + auto& memory = it->second; memory.resize(newSize); return true; } |