Skip to content

Commit 7d9c79e

Browse files
Add importing logic
1 parent 506fb97 commit 7d9c79e

5 files changed

Lines changed: 83 additions & 5 deletions

File tree

src/ir/import-utils.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define wasm_ir_import_h
1919

2020
#include "ir/import-names.h"
21+
#include "ir/runtime-memory.h"
2122
#include "ir/runtime-table.h"
2223
#include "literal.h"
2324
#include "wasm-type.h"
@@ -137,12 +138,19 @@ class ImportResolver {
137138
virtual Literals*
138139
getGlobalOrNull(ImportNames name, Type type, bool mut) const = 0;
139140

140-
// Returns null if the imported table does not exist. The returned
141-
// RuntimeTable* lives as long as the ImportResolver instance.
141+
// Returns null if the `name` wasn't found. The returned RuntimeTable lives
142+
// as long as the ImportResolver instance.
142143
virtual RuntimeTable* getTableOrNull(ImportNames name,
143144
const Table& type) const = 0;
144145

146+
// Returns null if the `name` wasn't found. The returned Tag lives
147+
// as long as the ImportResolver instance.
145148
virtual Tag* getTagOrNull(ImportNames name, const Signature& type) const = 0;
149+
150+
// Returns null if the `name` wasn't found. The returned RuntimeMemory lives
151+
// as long as the ImportResolver instance.
152+
virtual RuntimeMemory* getMemoryOrNull(ImportNames name,
153+
const Memory& type) const = 0;
146154
};
147155

148156
// Looks up imports from the given `linkedInstances`.
@@ -185,6 +193,17 @@ class LinkedInstancesImportResolver : public ImportResolver {
185193
return instance->getExportedTagOrNull(name.name);
186194
}
187195

196+
RuntimeMemory* getMemoryOrNull(ImportNames name,
197+
const Memory& type) const override {
198+
auto it = linkedInstances.find(name.module);
199+
if (it == linkedInstances.end()) {
200+
return nullptr;
201+
}
202+
203+
ModuleRunnerType* instance = it->second.get();
204+
return instance->getExportedMemoryOrNull(name.name);
205+
}
206+
188207
private:
189208
const std::map<Name, std::shared_ptr<ModuleRunnerType>> linkedInstances;
190209
};

src/ir/runtime-memory.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,23 @@ namespace wasm {
2323

2424
// TODO split into pure virtual class
2525
class RuntimeMemory {
26+
public:
2627
RuntimeMemory(Memory memory) : memoryDefinition(memory) {}
2728

29+
virtual ~RuntimeMemory() = default;
30+
2831
// variants for load8 etc?
2932
// Do we care about the order here?
30-
Literal load(Address addr) const { return {}; }
33+
virtual Literal load(Address addr) const { return {}; }
3134

3235
const Memory* getDefinition() const { return &memoryDefinition; }
3336

34-
private:
37+
protected:
3538
const Memory memoryDefinition;
3639
};
3740

41+
class RealRuntimeMemory : public RuntimeMemory {};
42+
3843
} // namespace wasm
3944

4045
#endif // wasm_ir_runtime_memory_h

src/ir/runtime-table.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ namespace wasm {
3030
// out-of-bounds access.
3131
class RuntimeTable {
3232
public:
33-
RuntimeTable(Table table) : tableDefinition(table) {}
3433
virtual ~RuntimeTable() = default;
3534

3635
virtual void set(Address i, Literal l) = 0;
@@ -54,6 +53,8 @@ class RuntimeTable {
5453
const Table* getDefinition() const { return &tableDefinition; }
5554

5655
protected:
56+
RuntimeTable(Table table) : tableDefinition(table) {}
57+
5758
const Table tableDefinition;
5859
};
5960

src/tools/wasm-ctor-eval.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ class EvallingImportResolver : public ImportResolver {
9595
return &it->second;
9696
}
9797

98+
RuntimeMemory* getMemoryOrNull(ImportNames name,
99+
const Memory& memory) const override {
100+
Fatal() << "todo";
101+
return nullptr;
102+
}
103+
98104
private:
99105
mutable Literals stubLiteral;
100106
mutable std::unordered_map<ImportNames, Tag> importedTags;

src/wasm-interpreter.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3183,6 +3183,8 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
31833183

31843184
std::unordered_map<Name, Tag*> allTags;
31853185

3186+
std::unordered_map<Name, RuntimeMemory*> allMemories;
3187+
31863188
using CreateTableFunc = std::unique_ptr<RuntimeTable>(Literal, Table);
31873189

31883190
ModuleRunnerBase(
@@ -3296,6 +3298,19 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
32963298
return iter->second;
32973299
}
32983300

3301+
RuntimeMemory* getExportedMemoryOrNull(Name name) {
3302+
Export* export_ = wasm.getExportOrNull(name);
3303+
if (!export_ || export_->kind != ExternalKind::Memory) {
3304+
return nullptr;
3305+
}
3306+
Name internalName = *export_->getInternalName();
3307+
auto iter = allMemories.find(internalName);
3308+
if (iter == allMemories.end()) {
3309+
return nullptr;
3310+
}
3311+
return iter->second;
3312+
}
3313+
32993314
Literals& getExportedGlobalOrTrap(Name name) {
33003315
auto* global = getExportedGlobalOrNull(name);
33013316
if (!global) {
@@ -3347,6 +3362,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
33473362
std::vector<Literals> definedGlobals;
33483363
std::vector<std::unique_ptr<RuntimeTable>> definedTables;
33493364
std::vector<Tag> definedTags;
3365+
std::vector<std::unique_ptr<RuntimeMemory>> definedMemories;
33503366

33513367
// Keep a record of call depth, to guard against excessive recursion.
33523368
size_t callDepth = 0;
@@ -3570,6 +3586,37 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
35703586
});
35713587
}
35723588

3589+
void initializeMemories() {
3590+
int definedMemoryCount = 0;
3591+
ModuleUtils::iterDefinedMemories(
3592+
wasm, [&definedMemoryCount](auto&& _) { ++definedMemoryCount; });
3593+
definedMemories.reserve(definedMemoryCount);
3594+
3595+
for (auto& memory : wasm.memories) {
3596+
if (memory->imported()) {
3597+
auto importNames = memory->importNames();
3598+
auto* importedMemory =
3599+
importResolver->getMemoryOrNull(importNames, *memory);
3600+
if (!importedMemory) {
3601+
externalInterface->trap((std::stringstream()
3602+
<< "Imported memory " << importNames
3603+
<< " not found.")
3604+
.str());
3605+
}
3606+
[[maybe_unused]] auto [_, inserted] =
3607+
allMemories.try_emplace(memory->name, importedMemory);
3608+
// parsing/validation checked this already.
3609+
assert(inserted && "Unexpected repeated memory name");
3610+
} else {
3611+
auto& runtimeMemory = definedMemories.emplace_back(
3612+
std::make_unique<RealRuntimeMemory>(memory));
3613+
[[maybe_unused]] auto [_, inserted] =
3614+
allMemories.try_emplace(memory->name, runtimeMemory.get());
3615+
assert(inserted && "Unexpected repeated memory name");
3616+
}
3617+
}
3618+
}
3619+
35733620
struct MemoryInstanceInfo {
35743621
// The ModuleRunner instance in which the memory is defined.
35753622
SubType* instance;

0 commit comments

Comments
 (0)