summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2018-12-03 18:26:16 -0800
committerGitHub <noreply@github.com>2018-12-03 18:26:16 -0800
commit6b6e89d0c8feeead83d6d83fa94e17fc9f75e0f8 (patch)
tree5b343da66f58c7fff1fbcd401dcec3e913ea49ff /src/tools
parent99cad87cea463fc3b978850a1d1416d9b338a14c (diff)
downloadbinaryen-6b6e89d0c8feeead83d6d83fa94e17fc9f75e0f8.tar.gz
binaryen-6b6e89d0c8feeead83d6d83fa94e17fc9f75e0f8.tar.bz2
binaryen-6b6e89d0c8feeead83d6d83fa94e17fc9f75e0f8.zip
Feature options (#1797)
Add feature flags and struct interface. Default feature set has all feature enabled.
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/asm2wasm.cpp5
-rw-r--r--src/tools/feature-options.h81
-rw-r--r--src/tools/fuzzing.h18
-rw-r--r--src/tools/optimization-options.h10
-rw-r--r--src/tools/wasm-as.cpp2
-rw-r--r--src/tools/wasm-opt.cpp19
-rw-r--r--src/tools/wasm-reduce.cpp2
-rw-r--r--src/tools/wasm-shell.cpp10
8 files changed, 107 insertions, 40 deletions
diff --git a/src/tools/asm2wasm.cpp b/src/tools/asm2wasm.cpp
index d5e5827c5..a001c08a6 100644
--- a/src/tools/asm2wasm.cpp
+++ b/src/tools/asm2wasm.cpp
@@ -115,9 +115,6 @@ int main(int argc, const char *argv[]) {
.add("--emit-text", "-S", "Emit text instead of binary for the output file",
Options::Arguments::Zero,
[&](Options *o, const std::string& argument) { emitBinary = false; })
- .add("--enable-threads", "-a", "Enable the Atomics wasm feature",
- Options::Arguments::Zero,
- [&](Options *o, const std::string& argument) { options.passOptions.features |= Feature::Atomics; })
.add_positional("INFILE", Options::Arguments::One,
[](Options *o, const std::string& argument) {
o->extra["infile"] = argument;
@@ -188,7 +185,7 @@ int main(int argc, const char *argv[]) {
if (memInit != options.extra.end()) {
if (options.runningDefaultOptimizationPasses()) {
PassRunner runner(&wasm);
- runner.setFeatures(options.features);
+ runner.setFeatures(options.getFeatures());
runner.add("memory-packing");
runner.run();
}
diff --git a/src/tools/feature-options.h b/src/tools/feature-options.h
new file mode 100644
index 000000000..3b35656fc
--- /dev/null
+++ b/src/tools/feature-options.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#include "support/command-line.h"
+#include "pass.h"
+
+//
+// Shared optimization options for commandline tools
+//
+
+namespace wasm {
+
+struct FeatureOptions : public Options {
+ PassOptions passOptions;
+
+ FeatureOptions(const std::string& command, const std::string& description)
+ : Options(command, description) {
+ (*this)
+ .add("--mvp-features", "-mvp", "Disable all non-MVP features (default)",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features = FeatureSet::MVP;
+ })
+ .add("--all-features", "-all", "Enable all features",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features = FeatureSet::All;
+ })
+ .add("--enable-threads", "", "Enable atomic operations",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features.setAtomics();
+ })
+ .add("--disable-threads", "", "Disable atomic operations",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features.setAtomics(false);
+ })
+ .add("--enable-mutable-globals", "", "Enable mutable globals",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features.setMutableGlobals();
+ })
+ .add("--disable-mutable-globals", "", "Disable mutable globals",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features.setMutableGlobals(false);
+ })
+ .add("--enable-nontrapping-float-to-int", "",
+ "Enable nontrapping float-to-int operations",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features.setTruncSat();
+ })
+ .add("--disable-nontrapping-float-to-int", "",
+ "Disable nontrapping float-to-int operations",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features.setTruncSat(false);
+ });
+ }
+
+ FeatureSet getFeatures() const {
+ return passOptions.features;
+ }
+};
+
+} // namespace wasm
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 7954229c7..8f7123a78 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -123,8 +123,8 @@ public:
std::cout << "shrink level: " << options.passOptions.shrinkLevel << '\n';
}
- void build(bool initEmitAtomics = true) {
- emitAtomics = initEmitAtomics;
+ void build(FeatureSet features_) {
+ features = features_;
setupMemory();
setupTable();
setupGlobals();
@@ -179,8 +179,8 @@ private:
// cross-VM comparisons harder)
static const bool DE_NAN = true;
- // Whether to emit atomics
- bool emitAtomics = true;
+ // Features allowed to be emitted
+ FeatureSet features = FeatureSet::All;
// Whether to emit atomic waits (which in single-threaded mode, may hang...)
static const bool ATOMIC_WAITS = false;
@@ -1118,7 +1118,7 @@ private:
Expression* makeLoad(Type type) {
auto* ret = makeNonAtomicLoad(type);
if (type != i32 && type != i64) return ret;
- if (!emitAtomics || oneIn(2)) return ret;
+ if (!features.hasAtomics() || oneIn(2)) return ret;
// make it atomic
wasm.memory.shared = true;
ret->isAtomic = true;
@@ -1181,7 +1181,7 @@ private:
Store* makeStore(Type type) {
auto* ret = makeNonAtomicStore(type);
if (ret->value->type != i32 && ret->value->type != i64) return ret;
- if (!emitAtomics || oneIn(2)) return ret;
+ if (!features.hasAtomics() || oneIn(2)) return ret;
// make it atomic
wasm.memory.shared = true;
ret->isAtomic = true;
@@ -1314,7 +1314,7 @@ private:
case i32: {
switch (upTo(4)) {
case 0: {
- if (emitAtomics) {
+ if (features.hasAtomics()) {
return makeUnary({ pick(EqZInt32, ClzInt32, CtzInt32, PopcntInt32, ExtendS8Int32, ExtendS16Int32), make(i32) });
} else {
return makeUnary({ pick(EqZInt32, ClzInt32, CtzInt32, PopcntInt32), make(i32) });
@@ -1330,7 +1330,7 @@ private:
case i64: {
switch (upTo(4)) {
case 0: {
- if (emitAtomics) {
+ if (features.hasAtomics()) {
return makeUnary({ pick(ClzInt64, CtzInt64, PopcntInt64, ExtendS8Int64, ExtendS16Int64, ExtendS32Int64), make(i64) });
} else {
return makeUnary({ pick(ClzInt64, CtzInt64, PopcntInt64), make(i64) });
@@ -1465,7 +1465,7 @@ private:
}
Expression* makeAtomic(Type type) {
- if (!emitAtomics || (type != i32 && type != i64)) return makeTrivial(type);
+ if (!features.hasAtomics() || (type != i32 && type != i64)) return makeTrivial(type);
wasm.memory.shared = true;
if (type == i32 && oneIn(2)) {
if (ATOMIC_WAITS && oneIn(2)) {
diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h
index abe3bcd6d..7849be375 100644
--- a/src/tools/optimization-options.h
+++ b/src/tools/optimization-options.h
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "support/command-line.h"
+#include "feature-options.h"
//
// Shared optimization options for commandline tools
@@ -22,14 +22,12 @@
namespace wasm {
-struct OptimizationOptions : public Options {
+struct OptimizationOptions : public FeatureOptions {
static constexpr const char* DEFAULT_OPT_PASSES = "O";
std::vector<std::string> passes;
- PassOptions passOptions;
- FeatureSet features = Feature::Atomics;
- OptimizationOptions(const std::string& command, const std::string& description) : Options(command, description) {
+ OptimizationOptions(const std::string& command, const std::string& description) : FeatureOptions(command, description) {
(*this).add("", "-O", "execute default optimization passes",
Options::Arguments::Zero,
[this](Options*, const std::string&) {
@@ -132,7 +130,7 @@ struct OptimizationOptions : public Options {
void runPasses(Module& wasm) {
PassRunner passRunner(&wasm, passOptions);
if (debug) passRunner.setDebug(true);
- passRunner.setFeatures(features);
+ passRunner.setFeatures(passOptions.features);
for (auto& pass : passes) {
if (pass == DEFAULT_OPT_PASSES) {
passRunner.addDefaultOptimizationPasses();
diff --git a/src/tools/wasm-as.cpp b/src/tools/wasm-as.cpp
index 46885dec0..c504c2a81 100644
--- a/src/tools/wasm-as.cpp
+++ b/src/tools/wasm-as.cpp
@@ -93,7 +93,7 @@ int main(int argc, const char *argv[]) {
if (options.extra["validate"] != "none") {
if (options.debug) std::cerr << "Validating..." << std::endl;
- if (!wasm::WasmValidator().validate(wasm, Feature::All,
+ if (!wasm::WasmValidator().validate(wasm, FeatureSet::All,
WasmValidator::Globally | (options.extra["validate"] == "web" ? WasmValidator::Web : 0))) {
WasmPrinter::printModule(&wasm);
Fatal() << "Error: input module is not valid.\n";
diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp
index 421bcca59..3e04fc644 100644
--- a/src/tools/wasm-opt.cpp
+++ b/src/tools/wasm-opt.cpp
@@ -69,7 +69,6 @@ int main(int argc, const char* argv[]) {
bool fuzzBinary = false;
std::string extraFuzzCommand;
bool translateToFuzz = false;
- bool fuzzAtomics = true;
bool fuzzPasses = false;
std::string emitJSWrapper;
std::string emitSpecWrapper;
@@ -106,9 +105,6 @@ int main(int argc, const char* argv[]) {
.add("--translate-to-fuzz", "-ttf", "Translate the input into a valid wasm module *somehow*, useful for fuzzing",
Options::Arguments::Zero,
[&](Options *o, const std::string& arguments) { translateToFuzz = true; })
- .add("--no-fuzz-atomics", "-nfa", "Disable generation of atomic opcodes with translate-to-fuzz (on by default)",
- Options::Arguments::Zero,
- [&](Options *o, const std::string& arguments) { fuzzAtomics = false; })
.add("--fuzz-passes", "-fp", "Pick a random set of passes to run, useful for fuzzing. this depends on translate-to-fuzz (it picks the passes from the input)",
Options::Arguments::Zero,
[&](Options *o, const std::string& arguments) { fuzzPasses = true; })
@@ -134,11 +130,6 @@ int main(int argc, const char* argv[]) {
options.parse(argc, argv);
Module wasm;
- // It should be safe to just always enable atomics in wasm-opt, because we
- // don't expect any passes to accidentally generate atomic ops
- FeatureSet features = Feature::Atomics;
- // Same for MutableGlobals
- features |= Feature::MutableGlobals;
if (options.debug) std::cerr << "reading...\n";
@@ -160,7 +151,7 @@ int main(int argc, const char* argv[]) {
}
if (options.passOptions.validate) {
- if (!WasmValidator().validate(wasm, features)) {
+ if (!WasmValidator().validate(wasm, options.getFeatures())) {
WasmPrinter::printModule(&wasm);
Fatal() << "error in validating input";
}
@@ -171,9 +162,9 @@ int main(int argc, const char* argv[]) {
if (fuzzPasses) {
reader.pickPasses(options);
}
- reader.build(fuzzAtomics);
+ reader.build(options.getFeatures());
if (options.passOptions.validate) {
- if (!WasmValidator().validate(wasm, features)) {
+ if (!WasmValidator().validate(wasm, options.getFeatures())) {
WasmPrinter::printModule(&wasm);
std::cerr << "translate-to-fuzz must always generate a valid module";
abort();
@@ -226,7 +217,7 @@ int main(int argc, const char* argv[]) {
WasmBinaryBuilder parser(other, input, false);
parser.read();
if (options.passOptions.validate) {
- bool valid = WasmValidator().validate(other, features);
+ bool valid = WasmValidator().validate(other, options.getFeatures());
if (!valid) {
WasmPrinter::printModule(&other);
}
@@ -240,7 +231,7 @@ int main(int argc, const char* argv[]) {
auto runPasses = [&]() {
options.runPasses(*curr);
if (options.passOptions.validate) {
- bool valid = WasmValidator().validate(*curr, features);
+ bool valid = WasmValidator().validate(*curr, options.getFeatures());
if (!valid) {
WasmPrinter::printModule(&*curr);
}
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 5c1f98d88..8c5df7a1b 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -797,7 +797,7 @@ struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor<
FunctionReferenceRemover referenceRemover(names);
referenceRemover.walkModule(module.get());
- if (WasmValidator().validate(*module, Feature::All, WasmValidator::Globally | WasmValidator::Quiet) &&
+ if (WasmValidator().validate(*module, FeatureSet::All, WasmValidator::Globally | WasmValidator::Quiet) &&
writeAndTestReduction()) {
std::cerr << "| removed " << names.size() << " functions\n";
return true;
diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp
index 9ad1fa799..d8cd11f41 100644
--- a/src/tools/wasm-shell.cpp
+++ b/src/tools/wasm-shell.cpp
@@ -23,9 +23,9 @@
#include <memory>
#include "execution-results.h"
+#include "feature-options.h"
#include "pass.h"
#include "shell-interface.h"
-#include "support/command-line.h"
#include "support/file.h"
#include "wasm-interpreter.h"
#include "wasm-printing.h"
@@ -233,14 +233,14 @@ int main(int argc, const char* argv[]) {
Name entry;
std::set<size_t> skipped;
- Options options("wasm-shell", "Execute .wast files");
+ FeatureOptions options("wasm-shell", "Execute .wast files");
options
.add(
- "--entry", "-e", "call the entry point after parsing the module",
+ "--entry", "-e", "Call the entry point after parsing the module",
Options::Arguments::One,
[&entry](Options*, const std::string& argument) { entry = argument; })
.add(
- "--skip", "-s", "skip input on certain lines (comma-separated-list)",
+ "--skip", "-s", "Skip input on certain lines (comma-separated-list)",
Options::Arguments::One,
[&skipped](Options*, const std::string& argument) {
size_t i = 0;
@@ -292,7 +292,7 @@ int main(int argc, const char* argv[]) {
builders[moduleName].swap(builder);
modules[moduleName].swap(module);
i++;
- bool valid = WasmValidator().validate(*modules[moduleName]);
+ bool valid = WasmValidator().validate(*modules[moduleName], options.getFeatures());
if (!valid) {
WasmPrinter::printModule(modules[moduleName].get());
}