summaryrefslogtreecommitdiff
path: root/src/tools/wasm-ctor-eval.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/wasm-ctor-eval.cpp')
-rw-r--r--src/tools/wasm-ctor-eval.cpp100
1 files changed, 63 insertions, 37 deletions
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp
index 6150441cd..91128471c 100644
--- a/src/tools/wasm-ctor-eval.cpp
+++ b/src/tools/wasm-ctor-eval.cpp
@@ -122,14 +122,11 @@ std::unique_ptr<Module> buildEnvModule(Module& wasm) {
// create an exported memory with the same initial and max size
ModuleUtils::iterImportedMemories(wasm, [&](Memory* memory) {
if (memory->module == env->name) {
- env->memory.name = wasm.memory.name;
- env->memory.exists = true;
- env->memory.initial = memory->initial;
- env->memory.max = memory->max;
- env->memory.shared = memory->shared;
- env->memory.indexType = memory->indexType;
+ auto* copied = ModuleUtils::copyMemory(memory, *env);
+ copied->module = Name();
+ copied->base = Name();
env->addExport(Builder(*env).makeExport(
- wasm.memory.base, wasm.memory.name, ExternalKind::Memory));
+ memory->base, copied->name, ExternalKind::Memory));
}
});
@@ -147,7 +144,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
std::map<Name, std::shared_ptr<EvallingModuleRunner>> linkedInstances;
// A representation of the contents of wasm memory as we execute.
- std::vector<char> memory;
+ std::unordered_map<Name, std::vector<char>> memories;
CtorEvalExternalInterface(
std::map<Name, std::shared_ptr<EvallingModuleRunner>> linkedInstances_ =
@@ -160,8 +157,8 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
void applyToModule() {
clearApplyState();
- // If nothing was ever written to memory then there is nothing to update.
- if (!memory.empty()) {
+ // If nothing was ever written to memories then there is nothing to update.
+ if (!memories.empty()) {
applyMemoryToModule();
}
@@ -171,6 +168,12 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
void init(Module& wasm_, EvallingModuleRunner& instance_) override {
wasm = &wasm_;
instance = &instance_;
+ for (auto& memory : wasm->memories) {
+ if (!memory->imported()) {
+ std::vector<char> data;
+ memories[memory->name] = data;
+ }
+ }
}
void importGlobals(GlobalValueSet& globals, Module& wasm_) override {
@@ -204,7 +207,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
}
// Write out a count of i32(0) and return __WASI_ERRNO_SUCCESS (0).
- store32(arguments[0].geti32(), 0);
+ store32(arguments[0].geti32(), 0, wasm->memories[0]->name);
return {Literal(int32_t(0))};
}
@@ -225,7 +228,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
}
// Write out an argc of i32(0) and return a __WASI_ERRNO_SUCCESS (0).
- store32(arguments[0].geti32(), 0);
+ store32(arguments[0].geti32(), 0, wasm->memories[0]->name);
return {Literal(int32_t(0))};
}
@@ -336,29 +339,47 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
// called during initialization
void tableStore(Name tableName, Index index, const Literal& value) override {}
- int8_t load8s(Address addr) override { return doLoad<int8_t>(addr); }
- uint8_t load8u(Address addr) override { return doLoad<uint8_t>(addr); }
- int16_t load16s(Address addr) override { return doLoad<int16_t>(addr); }
- uint16_t load16u(Address addr) override { return doLoad<uint16_t>(addr); }
- int32_t load32s(Address addr) override { return doLoad<int32_t>(addr); }
- uint32_t load32u(Address addr) override { return doLoad<uint32_t>(addr); }
- int64_t load64s(Address addr) override { return doLoad<int64_t>(addr); }
- uint64_t load64u(Address addr) override { return doLoad<uint64_t>(addr); }
+ int8_t load8s(Address addr, Name memoryName) override {
+ return doLoad<int8_t>(addr, memoryName);
+ }
+ uint8_t load8u(Address addr, Name memoryName) override {
+ return doLoad<uint8_t>(addr, memoryName);
+ }
+ int16_t load16s(Address addr, Name memoryName) override {
+ return doLoad<int16_t>(addr, memoryName);
+ }
+ uint16_t load16u(Address addr, Name memoryName) override {
+ return doLoad<uint16_t>(addr, memoryName);
+ }
+ int32_t load32s(Address addr, Name memoryName) override {
+ return doLoad<int32_t>(addr, memoryName);
+ }
+ uint32_t load32u(Address addr, Name memoryName) override {
+ return doLoad<uint32_t>(addr, memoryName);
+ }
+ int64_t load64s(Address addr, Name memoryName) override {
+ return doLoad<int64_t>(addr, memoryName);
+ }
+ uint64_t load64u(Address addr, Name memoryName) override {
+ return doLoad<uint64_t>(addr, memoryName);
+ }
- void store8(Address addr, int8_t value) override {
- doStore<int8_t>(addr, value);
+ void store8(Address addr, int8_t value, Name memoryName) override {
+ doStore<int8_t>(addr, value, memoryName);
}
- void store16(Address addr, int16_t value) override {
- doStore<int16_t>(addr, value);
+ void store16(Address addr, int16_t value, Name memoryName) override {
+ doStore<int16_t>(addr, value, memoryName);
}
- void store32(Address addr, int32_t value) override {
- doStore<int32_t>(addr, value);
+ void store32(Address addr, int32_t value, Name memoryName) override {
+ doStore<int32_t>(addr, value, memoryName);
}
- void store64(Address addr, int64_t value) override {
- doStore<int64_t>(addr, value);
+ void store64(Address addr, int64_t value, Name memoryName) override {
+ doStore<int64_t>(addr, value, memoryName);
}
- bool growMemory(Address /*oldSize*/, Address /*newSize*/) override {
+ bool growMemory(Name memoryName,
+ Address /*oldSize*/,
+ Address /*newSize*/) override {
throw FailToEvalException("grow memory");
}
@@ -385,8 +406,12 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
private:
// TODO: handle unaligned too, see shell-interface
-
- template<typename T> T* getMemory(Address address) {
+ template<typename T> T* getMemory(Address address, Name memoryName) {
+ auto it = memories.find(memoryName);
+ if (it == memories.end()) {
+ Fatal() << "memory not found: " << memoryName;
+ }
+ auto& memory = it->second;
// resize the memory buffer as needed.
auto max = address + sizeof(T);
if (max > memory.size()) {
@@ -395,15 +420,15 @@ private:
return (T*)(&memory[address]);
}
- template<typename T> void doStore(Address address, T value) {
+ template<typename T> void doStore(Address address, T value, Name memoryName) {
// do a memcpy to avoid undefined behavior if unaligned
- memcpy(getMemory<T>(address), &value, sizeof(T));
+ memcpy(getMemory<T>(address, memoryName), &value, sizeof(T));
}
- template<typename T> T doLoad(Address address) {
+ template<typename T> T doLoad(Address address, Name memoryName) {
// do a memcpy to avoid undefined behavior if unaligned
T ret;
- memcpy(&ret, getMemory<T>(address), sizeof(T));
+ memcpy(&ret, getMemory<T>(address, memoryName), sizeof(T));
return ret;
}
@@ -431,14 +456,15 @@ private:
auto curr = builder.makeDataSegment();
curr->offset = builder.makeConst(int32_t(0));
curr->setName(Name::fromInt(0), false);
- wasm->dataSegments.push_back(std::move(curr));
+ curr->memory = wasm->memories[0]->name;
+ wasm->addDataSegment(std::move(curr));
}
auto& segment = wasm->dataSegments[0];
assert(segment->offset->cast<Const>()->value.getInteger() == 0);
// Copy the current memory contents after execution into the Module's
// memory.
- segment->data = memory;
+ segment->data = memories[wasm->memories[0]->name];
}
// Serializing GC data requires more work than linear memory, because