summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir/module-utils.h18
-rw-r--r--src/passes/CMakeLists.txt1
-rw-r--r--src/passes/RoundTrip.cpp71
-rw-r--r--src/passes/pass.cpp3
-rw-r--r--src/passes/passes.h1
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();