diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/module-utils.h | 18 | ||||
-rw-r--r-- | src/passes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/passes/RoundTrip.cpp | 71 | ||||
-rw-r--r-- | src/passes/pass.cpp | 3 | ||||
-rw-r--r-- | src/passes/passes.h | 1 |
5 files changed, 92 insertions, 2 deletions
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h index f2fda908c..e212ae8dc 100644 --- a/src/ir/module-utils.h +++ b/src/ir/module-utils.h @@ -105,8 +105,8 @@ inline Event* copyEvent(Event* event, Module& out) { return ret; } -inline void copyModule(Module& in, Module& out) { - // we use names throughout, not raw points, so simple copying is fine +inline void copyModule(const Module& in, Module& out) { + // we use names throughout, not raw pointers, so simple copying is fine // for everything *but* expressions for (auto& curr : in.functionTypes) { out.addFunctionType(make_unique<FunctionType>(*curr)); @@ -136,6 +136,20 @@ inline void copyModule(Module& in, Module& out) { out.debugInfoFileNames = in.debugInfoFileNames; } +inline void clearModule(Module& wasm) { + wasm.functionTypes.clear(); + wasm.exports.clear(); + wasm.functions.clear(); + wasm.globals.clear(); + wasm.events.clear(); + wasm.table.segments.clear(); + wasm.memory.segments.clear(); + wasm.start = Name(); + wasm.userSections.clear(); + wasm.debugInfoFileNames.clear(); + wasm.updateMaps(); +} + // Renaming // Rename functions along with all their uses. diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index a3dd1c26a..7ec9054d7 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -47,6 +47,7 @@ set(passes_SOURCES PrintCallGraph.cpp PrintFeatures.cpp PrintFunctionMap.cpp + RoundTrip.cpp StackIR.cpp Strip.cpp StripTargetFeatures.cpp diff --git a/src/passes/RoundTrip.cpp b/src/passes/RoundTrip.cpp new file mode 100644 index 000000000..626c469d5 --- /dev/null +++ b/src/passes/RoundTrip.cpp @@ -0,0 +1,71 @@ +/* + * Copyright 2019 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Write the module to binary, and load it from there. This is useful in +// testing to check for the effects of roundtripping in a single wasm-opt +// parameter. +// + +#ifdef _WIN32 +#include <io.h> +#endif + +#include <cstdlib> +#include <vector> + +#include "ir/module-utils.h" +#include "pass.h" +#include "support/file.h" +#include "wasm-io.h" +#include "wasm.h" + +using namespace std; + +namespace wasm { + +struct RoundTrip : public Pass { + void run(PassRunner* runner, Module* module) override { + std::string templateName = "byn_round_trip_XXXXXX"; + std::vector<char> buffer(templateName.begin(), templateName.end()); + buffer.push_back(0); +#ifndef _WIN32 + auto fd = mkstemp(buffer.data()); + WASM_UNUSED(fd); + std::string tempName(buffer.begin(), buffer.end()); +#else + std::string tempName = _mktemp(buffer.data()); +#endif + // Write + ModuleWriter writer; + writer.setBinary(true); + writer.setDebugInfo(runner->options.debugInfo); + writer.write(*module, tempName); + // Read + Module newModule; + ModuleReader reader; + reader.read(tempName, newModule); + // Clean up + std::remove(tempName.c_str()); + // Swap in + ModuleUtils::clearModule(*module); + ModuleUtils::copyModule(newModule, *module); + } +}; + +Pass* createRoundTripPass() { return new RoundTrip(); } + +} // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 4b3021764..5dd39a453 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -276,6 +276,9 @@ void PassRegistry::registerPasses() { createReReloopPass); registerPass( "rse", "remove redundant local.sets", createRedundantSetEliminationPass); + registerPass("roundtrip", + "write the module to binary, then read it", + createRoundTripPass); registerPass("safe-heap", "instrument loads and stores to check for invalid behavior", createSafeHeapPass); diff --git a/src/passes/passes.h b/src/passes/passes.h index 98c7d374d..33a0b26da 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -94,6 +94,7 @@ Pass* createReorderFunctionsPass(); Pass* createReorderLocalsPass(); Pass* createReReloopPass(); Pass* createRedundantSetEliminationPass(); +Pass* createRoundTripPass(); Pass* createSafeHeapPass(); Pass* createSimplifyLocalsPass(); Pass* createSimplifyGlobalsPass(); |