diff options
author | Alon Zakai <azakai@google.com> | 2022-01-07 08:21:13 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-07 08:21:13 -0800 |
commit | 260b8ee7f2b4f5fb87e72e99b9543eb524d12c7d (patch) | |
tree | 57aeea023034ddeb1b83393fcc5c6b0014a81898 /src/tools/wasm-ctor-eval.cpp | |
parent | 8c0f53d236f664086405870321e5887aaed39f3f (diff) | |
download | binaryen-260b8ee7f2b4f5fb87e72e99b9543eb524d12c7d.tar.gz binaryen-260b8ee7f2b4f5fb87e72e99b9543eb524d12c7d.tar.bz2 binaryen-260b8ee7f2b4f5fb87e72e99b9543eb524d12c7d.zip |
[ctor-eval] Eval and store changes to globals (#4430)
This is necessary for being able to optimize real-world code, as it lets us
use the stack pointer for example. With this PR we allow changes to
globals, and we simply store the final state of the global in the global at
the end. Basically the same as we do for memory, but for globals.
Remove a test that now fails ("imported2"). Replace it with a nicer test
of saving the values of globals. Also add a test for an imported global,
which we do not allow (we never did, but I don't see a test for it).
Diffstat (limited to 'src/tools/wasm-ctor-eval.cpp')
-rw-r--r-- | src/tools/wasm-ctor-eval.cpp | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 009a91c0b..88b7d18b4 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -62,15 +62,6 @@ public: void seal() { sealed = true; } - // for equality purposes, we just care about the globals - // and whether they have changed - bool operator==(const EvallingGlobalManager& other) { - return globals == other.globals; - } - bool operator!=(const EvallingGlobalManager& other) { - return !(*this == other); - } - Literals& operator[](Name name) { if (dangerousGlobals.count(name) > 0) { std::string extra; @@ -110,6 +101,15 @@ public: } Iterator end() { return Iterator(); } + + // Receives a module and applies the state of globals here into the globals + // in that module. + void applyToModule(Module& wasm) { + Builder builder(wasm); + for (const auto& [name, value] : globals) { + wasm.getGlobal(name)->init = builder.makeConstantExpression(value); + } + } }; class EvallingModuleInstance @@ -220,6 +220,8 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface { if (!memory.empty()) { applyMemoryToModule(); } + + instance->globals.applyToModule(*wasm); } void init(Module& wasm_, EvallingModuleInstance& instance_) override { @@ -499,9 +501,6 @@ void evalCtors(Module& wasm, std::vector<std::string> ctors) { // TODO: if we knew priorities, we could reorder? for (auto& ctor : ctors) { std::cerr << "trying to eval " << ctor << '\n'; - // snapshot globals (note that STACKTOP might be modified, but should - // be returned, so that works out) - auto globalsBefore = instance.globals; Export* ex = wasm.getExportOrNull(ctor); if (!ex) { Fatal() << "export not found: " << ctor; @@ -514,10 +513,6 @@ void evalCtors(Module& wasm, std::vector<std::string> ctors) { std::cerr << " ...stopping since could not eval: " << fail.why << "\n"; return; } - if (instance.globals != globalsBefore) { - std::cerr << " ...stopping since globals modified\n"; - return; - } std::cerr << " ...success on " << ctor << ".\n"; // Success, the entire function was evalled! Apply the results of |