Skip to content

Commit a0f2b9c

Browse files
Add importing logic
1 parent fb1f2d7 commit a0f2b9c

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
@@ -3208,6 +3208,8 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
32083208

32093209
std::unordered_map<Name, Tag*> allTags;
32103210

3211+
std::unordered_map<Name, RuntimeMemory*> allMemories;
3212+
32113213
using CreateTableFunc = std::unique_ptr<RuntimeTable>(Literal, Table);
32123214

32133215
ModuleRunnerBase(
@@ -3321,6 +3323,19 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
33213323
return iter->second;
33223324
}
33233325

3326+
RuntimeMemory* getExportedMemoryOrNull(Name name) {
3327+
Export* export_ = wasm.getExportOrNull(name);
3328+
if (!export_ || export_->kind != ExternalKind::Memory) {
3329+
return nullptr;
3330+
}
3331+
Name internalName = *export_->getInternalName();
3332+
auto iter = allMemories.find(internalName);
3333+
if (iter == allMemories.end()) {
3334+
return nullptr;
3335+
}
3336+
return iter->second;
3337+
}
3338+
33243339
Literals& getExportedGlobalOrTrap(Name name) {
33253340
auto* global = getExportedGlobalOrNull(name);
33263341
if (!global) {
@@ -3372,6 +3387,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
33723387
std::vector<Literals> definedGlobals;
33733388
std::vector<std::unique_ptr<RuntimeTable>> definedTables;
33743389
std::vector<Tag> definedTags;
3390+
std::vector<std::unique_ptr<RuntimeMemory>> definedMemories;
33753391

33763392
// Keep a record of call depth, to guard against excessive recursion.
33773393
size_t callDepth = 0;
@@ -3595,6 +3611,37 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
35953611
});
35963612
}
35973613

3614+
void initializeMemories() {
3615+
int definedMemoryCount = 0;
3616+
ModuleUtils::iterDefinedMemories(
3617+
wasm, [&definedMemoryCount](auto&& _) { ++definedMemoryCount; });
3618+
definedMemories.reserve(definedMemoryCount);
3619+
3620+
for (auto& memory : wasm.memories) {
3621+
if (memory->imported()) {
3622+
auto importNames = memory->importNames();
3623+
auto* importedMemory =
3624+
importResolver->getMemoryOrNull(importNames, *memory);
3625+
if (!importedMemory) {
3626+
externalInterface->trap((std::stringstream()
3627+
<< "Imported memory " << importNames
3628+
<< " not found.")
3629+
.str());
3630+
}
3631+
[[maybe_unused]] auto [_, inserted] =
3632+
allMemories.try_emplace(memory->name, importedMemory);
3633+
// parsing/validation checked this already.
3634+
assert(inserted && "Unexpected repeated memory name");
3635+
} else {
3636+
auto& runtimeMemory = definedMemories.emplace_back(
3637+
std::make_unique<RealRuntimeMemory>(memory));
3638+
[[maybe_unused]] auto [_, inserted] =
3639+
allMemories.try_emplace(memory->name, runtimeMemory.get());
3640+
assert(inserted && "Unexpected repeated memory name");
3641+
}
3642+
}
3643+
}
3644+
35983645
struct MemoryInstanceInfo {
35993646
// The ModuleRunner instance in which the memory is defined.
36003647
SubType* instance;

0 commit comments

Comments
 (0)