summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/fuzz_opt.py23
-rw-r--r--src/ir/module-utils.h13
-rw-r--r--src/passes/RoundTrip.cpp43
-rw-r--r--src/tools/wasm-opt.cpp39
-rw-r--r--test/passes/roundtrip.txt4
-rw-r--r--test/passes/strip-target-features_roundtrip_print-features_all-features.txt22
-rw-r--r--test/passes/strip-target-features_roundtrip_print-features_all-features.wast14
7 files changed, 74 insertions, 84 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py
index bc3b9fd5d..b3310cad0 100755
--- a/scripts/fuzz_opt.py
+++ b/scripts/fuzz_opt.py
@@ -450,7 +450,7 @@ class CompareVMs(TestCaseHandler):
class FuzzExec(TestCaseHandler):
def get_commands(self, wasm, opts, random_seed):
return [
- '%(MAX_INTERPRETER_ENV_VAR)s=%(MAX_INTERPRETER_DEPTH)d %(wasm_opt)s --fuzz-exec --fuzz-binary %(opts)s %(wasm)s' % {
+ '%(MAX_INTERPRETER_ENV_VAR)s=%(MAX_INTERPRETER_DEPTH)d %(wasm_opt)s --fuzz-exec %(opts)s %(wasm)s' % {
'MAX_INTERPRETER_ENV_VAR': MAX_INTERPRETER_ENV_VAR,
'MAX_INTERPRETER_DEPTH': MAX_INTERPRETER_DEPTH,
'wasm_opt': in_bin('wasm-opt'),
@@ -764,16 +764,25 @@ opt_choices = [
def randomize_opt_flags():
- ret = []
+ flag_groups = []
+ has_flatten = False
# core opts
while 1:
choice = random.choice(opt_choices)
- if '--flatten' in ret and '--flatten' in choice:
- print('avoiding multiple --flatten in a single command, due to exponential overhead')
- else:
- ret += choice
- if len(ret) > 20 or random.random() < 0.3:
+ if '--flatten' in choice:
+ if has_flatten:
+ print('avoiding multiple --flatten in a single command, due to exponential overhead')
+ continue
+ else:
+ has_flatten = True
+ flag_groups.append(choice)
+ if len(flag_groups) > 20 or random.random() < 0.3:
break
+ # maybe add an extra round trip
+ if random.random() < 0.5:
+ pos = random.randint(0, len(flag_groups))
+ flag_groups = flag_groups[:pos] + [['--roundtrip']] + flag_groups[pos:]
+ ret = [flag for group in flag_groups for flag in group]
# modifiers (if not already implied by a -O? option)
if '-O' not in str(ret):
if random.random() < 0.5:
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index e589f5052..ab23649f7 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -99,17 +99,8 @@ inline void copyModule(const Module& in, Module& out) {
}
inline void clearModule(Module& wasm) {
- wasm.exports.clear();
- wasm.functions.clear();
- wasm.globals.clear();
- wasm.events.clear();
- wasm.table.clear();
- wasm.memory.clear();
- wasm.start = Name();
- wasm.userSections.clear();
- wasm.debugInfoFileNames.clear();
- wasm.updateMaps();
- wasm.allocator.clear();
+ wasm.~Module();
+ new (&wasm) Module;
}
// Renaming
diff --git a/src/passes/RoundTrip.cpp b/src/passes/RoundTrip.cpp
index 5410ad87b..754881fe4 100644
--- a/src/passes/RoundTrip.cpp
+++ b/src/passes/RoundTrip.cpp
@@ -20,17 +20,9 @@
// 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-binary.h"
#include "wasm.h"
using namespace std;
@@ -39,28 +31,19 @@ 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
+ BufferWithRandomAccess buffer;
+ // Save features, which would not otherwise make it through a round trip if
+ // the target features section has been stripped.
+ auto features = module->features;
+ // Write, clear, and read the module
+ WasmBinaryWriter(module, buffer).write();
ModuleUtils::clearModule(*module);
- ModuleReader reader;
- reader.setDWARF(runner->options.debugInfo);
- reader.read(tempName, *module);
- // Clean up
- std::remove(tempName.c_str());
+ auto input = buffer.getAsChars();
+ WasmBinaryBuilder parser(*module, input);
+ parser.setDWARF(runner->options.debugInfo);
+ parser.read();
+ // Reapply features
+ module->features = features;
}
};
diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp
index 6fd3b7c8d..a215aca32 100644
--- a/src/tools/wasm-opt.cpp
+++ b/src/tools/wasm-opt.cpp
@@ -79,7 +79,6 @@ int main(int argc, const char* argv[]) {
bool converge = false;
bool fuzzExecBefore = false;
bool fuzzExecAfter = false;
- bool fuzzBinary = false;
std::string extraFuzzCommand;
bool translateToFuzz = false;
bool fuzzPasses = false;
@@ -127,12 +126,6 @@ int main(int argc, const char* argv[]) {
[&](Options* o, const std::string& arguments) {
fuzzExecBefore = fuzzExecAfter = true;
})
- .add("--fuzz-binary",
- "-fb",
- "Convert to binary and back after optimizations and before fuzz-exec, "
- "helping fuzzing find binary format bugs",
- Options::Arguments::Zero,
- [&](Options* o, const std::string& arguments) { fuzzBinary = true; })
.add("--extra-fuzz-command",
"-efc",
"An extra command to run on the output before and after optimizing. "
@@ -328,28 +321,6 @@ int main(int argc, const char* argv[]) {
std::cout << "[extra-fuzz-command first output:]\n" << firstOutput << '\n';
}
- Module* curr = &wasm;
- Module other;
-
- if (fuzzExecAfter && fuzzBinary) {
- BufferWithRandomAccess buffer;
- // write the binary
- WasmBinaryWriter writer(&wasm, buffer);
- writer.write();
- // read the binary
- auto input = buffer.getAsChars();
- WasmBinaryBuilder parser(other, input);
- parser.read();
- options.applyFeatures(other);
- if (options.passOptions.validate) {
- bool valid = WasmValidator().validate(other);
- if (!valid) {
- Fatal() << "fuzz-binary must always generate a valid module";
- }
- }
- curr = &other;
- }
-
if (!options.runningPasses()) {
if (!options.quiet) {
std::cerr << "warning: no passes specified, not doing any work\n";
@@ -357,9 +328,9 @@ int main(int argc, const char* argv[]) {
} else {
BYN_TRACE("running passes...\n");
auto runPasses = [&]() {
- options.runPasses(*curr);
+ options.runPasses(wasm);
if (options.passOptions.validate) {
- bool valid = WasmValidator().validate(*curr);
+ bool valid = WasmValidator().validate(wasm);
if (!valid) {
exitOnInvalidWasm("error after opts");
}
@@ -371,7 +342,7 @@ int main(int argc, const char* argv[]) {
// size no longer decreasing.
auto getSize = [&]() {
BufferWithRandomAccess buffer;
- WasmBinaryWriter writer(curr, buffer);
+ WasmBinaryWriter writer(&wasm, buffer);
writer.write();
return buffer.size();
};
@@ -389,7 +360,7 @@ int main(int argc, const char* argv[]) {
}
if (fuzzExecAfter) {
- results.check(*curr);
+ results.check(wasm);
}
if (options.extra.count("output") == 0) {
@@ -407,7 +378,7 @@ int main(int argc, const char* argv[]) {
writer.setSourceMapFilename(outputSourceMapFilename);
writer.setSourceMapUrl(outputSourceMapUrl);
}
- writer.write(*curr, options.extra["output"]);
+ writer.write(wasm, options.extra["output"]);
if (extraFuzzCommand.size() > 0) {
auto secondOutput = runCommand(extraFuzzCommand);
diff --git a/test/passes/roundtrip.txt b/test/passes/roundtrip.txt
index 508676657..c2a19480d 100644
--- a/test/passes/roundtrip.txt
+++ b/test/passes/roundtrip.txt
@@ -6,6 +6,6 @@
)
)
(module
- (memory $ 1 1)
- (table $ 0 funcref)
+ (memory $0 1 1)
+ (table $0 0 funcref)
)
diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.txt b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
new file mode 100644
index 000000000..c8d989c93
--- /dev/null
+++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.txt
@@ -0,0 +1,22 @@
+--enable-threads
+--enable-mutable-globals
+--enable-nontrapping-float-to-int
+--enable-simd
+--enable-bulk-memory
+--enable-sign-ext
+--enable-exception-handling
+--enable-tail-call
+--enable-reference-types
+--enable-multivalue
+(module
+ (type $none_=>_v128_anyref (func (result v128 anyref)))
+ (func $foo (result v128 anyref)
+ (tuple.make
+ (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
+ (ref.null)
+ )
+ )
+ (func $bar (result v128 anyref)
+ (return_call $foo)
+ )
+)
diff --git a/test/passes/strip-target-features_roundtrip_print-features_all-features.wast b/test/passes/strip-target-features_roundtrip_print-features_all-features.wast
new file mode 100644
index 000000000..214289904
--- /dev/null
+++ b/test/passes/strip-target-features_roundtrip_print-features_all-features.wast
@@ -0,0 +1,14 @@
+;; Test that features enabled on the IR Module survive a round trip
+;; even if the target features section is stripped first
+
+(module
+ (func $foo (result v128 anyref )
+ (tuple.make
+ (v128.const i32x4 0 0 0 0)
+ (ref.null)
+ )
+ )
+ (func $bar (result v128 anyref)
+ (return_call $foo)
+ )
+)