summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/asm2wasm.cpp6
-rw-r--r--src/tools/fuzzing.h31
-rw-r--r--src/tools/optimization-options.h1
-rw-r--r--src/tools/tool-options.h40
-rw-r--r--src/tools/wasm-as.cpp4
-rw-r--r--src/tools/wasm-ctor-eval.cpp3
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp4
-rw-r--r--src/tools/wasm-opt.cpp12
-rw-r--r--src/tools/wasm-reduce.cpp2
-rw-r--r--src/tools/wasm-shell.cpp7
-rw-r--r--src/tools/wasm2js.cpp4
11 files changed, 49 insertions, 65 deletions
diff --git a/src/tools/asm2wasm.cpp b/src/tools/asm2wasm.cpp
index 9ec083db2..547bf4ab1 100644
--- a/src/tools/asm2wasm.cpp
+++ b/src/tools/asm2wasm.cpp
@@ -177,6 +177,9 @@ int main(int argc, const char *argv[]) {
wasm.memory.segments.emplace_back(init, data);
}
+ // set up the module's features, needed by optimization and validation passes
+ options.applyFeatures(wasm);
+
// compile the code
Asm2WasmBuilder asm2wasm(wasm, pre, options.debug, trapMode, options.passOptions, legalizeJavaScriptFFI, options.runningDefaultOptimizationPasses(), wasmOnly);
asm2wasm.processAsm(asmjs);
@@ -185,7 +188,6 @@ int main(int argc, const char *argv[]) {
if (memInit != options.extra.end()) {
if (options.runningDefaultOptimizationPasses()) {
PassRunner runner(&wasm);
- runner.setFeatures(options.passOptions.features);
runner.add("memory-packing");
runner.run();
}
@@ -213,7 +215,7 @@ int main(int argc, const char *argv[]) {
}
if (options.passOptions.validate) {
- if (!WasmValidator().validate(wasm, options.passOptions.features)) {
+ if (!WasmValidator().validate(wasm)) {
WasmPrinter::printModule(&wasm);
Fatal() << "error in validating output";
}
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 7b47dea8f..b7056f964 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -124,10 +124,6 @@ public:
std::cout << "shrink level: " << options.passOptions.shrinkLevel << '\n';
}
- void setFeatures(FeatureSet features_) {
- features = features_;
- }
-
void setAllowNaNs(bool allowNaNs_) {
allowNaNs = allowNaNs_;
}
@@ -197,9 +193,6 @@ private:
// Whether to emit memory operations like loads and stores.
bool allowMemory = 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;
@@ -257,7 +250,7 @@ private:
void setupMemory() {
// Add memory itself
MemoryUtils::ensureExists(wasm.memory);
- if (features.hasBulkMemory()) {
+ if (wasm.features.hasBulkMemory()) {
size_t memCovered = 0;
// need at least one segment for memory.inits
size_t numSegments = upTo(8) + 1;
@@ -1198,7 +1191,7 @@ private:
return builder.makeLoad(8, false, offset, pick(1, 2, 4, 8), ptr, type);
}
case v128: {
- if (!features.hasSIMD()) {
+ if (!wasm.features.hasSIMD()) {
return makeTrivial(type);
}
return builder.makeLoad(16, false, offset, pick(1, 2, 4, 8, 16), ptr, type);
@@ -1213,7 +1206,7 @@ private:
if (!allowMemory) return makeTrivial(type);
auto* ret = makeNonAtomicLoad(type);
if (type != i32 && type != i64) return ret;
- if (!features.hasAtomics() || oneIn(2)) return ret;
+ if (!wasm.features.hasAtomics() || oneIn(2)) return ret;
// make it atomic
auto* load = ret->cast<Load>();
wasm.memory.shared = true;
@@ -1270,7 +1263,7 @@ private:
return builder.makeStore(8, offset, pick(1, 2, 4, 8), ptr, value, type);
}
case v128: {
- if (!features.hasSIMD()) {
+ if (!wasm.features.hasSIMD()) {
return makeTrivial(type);
}
return builder.makeStore(16, offset, pick(1, 2, 4, 8, 16), ptr, value, type);
@@ -1287,7 +1280,7 @@ private:
auto* store = ret->dynCast<Store>();
if (!store) return ret;
if (store->value->type != i32 && store->value->type != i64) return store;
- if (!features.hasAtomics() || oneIn(2)) return store;
+ if (!wasm.features.hasAtomics() || oneIn(2)) return store;
// make it atomic
wasm.memory.shared = true;
store->isAtomic = true;
@@ -1482,7 +1475,7 @@ private:
return buildUnary({ op, make(f64) });
}
case v128: {
- assert(features.hasSIMD());
+ assert(wasm.features.hasSIMD());
return buildUnary({ pick(AnyTrueVecI8x16, AllTrueVecI8x16, AnyTrueVecI16x8, AllTrueVecI16x8,
AnyTrueVecI32x4, AllTrueVecI32x4, AnyTrueVecI64x2, AllTrueVecI64x2),
make(v128) });
@@ -1541,7 +1534,7 @@ private:
WASM_UNREACHABLE();
}
case v128: {
- assert(features.hasSIMD());
+ assert(wasm.features.hasSIMD());
switch (upTo(5)) {
case 0: return buildUnary({ pick(SplatVecI8x16, SplatVecI16x8, SplatVecI32x4), make(i32) });
case 1: return buildUnary({ SplatVecI64x2, make(i64) });
@@ -1594,7 +1587,7 @@ private:
return makeDeNanOp(buildBinary({ pick(AddFloat64, SubFloat64, MulFloat64, DivFloat64, CopySignFloat64, MinFloat64, MaxFloat64), make(f64), make(f64) }));
}
case v128: {
- assert(features.hasSIMD());
+ assert(wasm.features.hasSIMD());
return buildBinary({
pick(EqVecI8x16, NeVecI8x16, LtSVecI8x16, LtUVecI8x16, GtSVecI8x16, GtUVecI8x16, LeSVecI8x16, LeUVecI8x16, GeSVecI8x16, GeUVecI8x16,
EqVecI16x8, NeVecI16x8, LtSVecI16x8, LtUVecI16x8, GtSVecI16x8, GtUVecI16x8, LeSVecI16x8, LeUVecI16x8, GeSVecI16x8, GeUVecI16x8,
@@ -1669,7 +1662,7 @@ private:
}
Expression* makeAtomic(Type type) {
- assert(features.hasAtomics());
+ assert(wasm.features.hasAtomics());
if (!allowMemory) return makeTrivial(type);
wasm.memory.shared = true;
if (type == i32 && oneIn(2)) {
@@ -1722,7 +1715,7 @@ private:
}
Expression* makeSIMD(Type type) {
- assert(features.hasSIMD());
+ assert(wasm.features.hasSIMD());
if (type != v128) {
return makeSIMDExtract(type);
}
@@ -1809,7 +1802,7 @@ private:
Expression* makeBulkMemory(Type type) {
if (!allowMemory) return makeTrivial(type);
- assert(features.hasBulkMemory());
+ assert(wasm.features.hasBulkMemory());
assert(type == none);
switch (upTo(4)) {
case 0: return makeMemoryInit();
@@ -1988,7 +1981,7 @@ private:
const T pick(FeatureOptions<T>& picker) {
std::vector<T> matches;
for (const auto& item : picker.options) {
- if (features.has(item.first)) {
+ if (wasm.features.has(item.first)) {
matches.reserve(matches.size() + item.second.size());
matches.insert(matches.end(), item.second.begin(), item.second.end());
}
diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h
index dfc61b0e3..cf7c612ea 100644
--- a/src/tools/optimization-options.h
+++ b/src/tools/optimization-options.h
@@ -141,7 +141,6 @@ struct OptimizationOptions : public ToolOptions {
void runPasses(Module& wasm) {
PassRunner passRunner(&wasm, passOptions);
if (debug) passRunner.setDebug(true);
- passRunner.setFeatures(passOptions.features);
for (auto& pass : passes) {
if (pass == DEFAULT_OPT_PASSES) {
passRunner.addDefaultOptimizationPasses();
diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h
index 6c2613407..dd585612f 100644
--- a/src/tools/tool-options.h
+++ b/src/tools/tool-options.h
@@ -34,24 +34,18 @@ struct ToolOptions : public Options {
Arguments::Zero,
[this](Options*, const std::string&) {
hasFeatureOptions = true;
- passOptions.features.makeMVP();
enabledFeatures.makeMVP();
disabledFeatures.setAll();
})
- .add("--all-features", "-all", "Enable all features "
- "(default if there is no target features section"
- " or if any feature options are provided)",
+ .add("--all-features", "-all", "Enable all features",
Arguments::Zero,
[this](Options*, const std::string&) {
hasFeatureOptions = true;
- passOptions.features.setAll();
enabledFeatures.setAll();
disabledFeatures.makeMVP();
})
.add("--detect-features", "",
- "Use features from the target features section"
- "(default if there is a target features section"
- " and no feature options are provided)",
+ "Use features from the target features section, or MVP (default)",
Arguments::Zero,
[this](Options*, const std::string&) {
hasFeatureOptions = true;
@@ -76,13 +70,11 @@ struct ToolOptions : public Options {
ToolOptions& addFeature(FeatureSet::Feature feature,
const std::string& description) {
-
(*this)
.add(std::string("--enable-") + FeatureSet::toString(feature), "",
std::string("Enable ") + description, Arguments::Zero,
[=](Options*, const std::string&) {
hasFeatureOptions = true;
- passOptions.features.set(feature, true);
enabledFeatures.set(feature, true);
disabledFeatures.set(feature, false);
})
@@ -91,36 +83,32 @@ struct ToolOptions : public Options {
std::string("Disable ") + description, Arguments::Zero,
[=](Options*, const std::string&) {
hasFeatureOptions = true;
- passOptions.features.set(feature, false);
enabledFeatures.set(feature, false);
disabledFeatures.set(feature, true);
});
return *this;
}
- void calculateFeatures(const Module& module) {
- FeatureSet wasmFeatures;
- bool wasmHasFeatures =
- ModuleUtils::readFeaturesSection(module, wasmFeatures);
-
+ void applyFeatures(Module& module) {
if (hasFeatureOptions) {
- if (detectFeatures) {
- wasmFeatures.enable(enabledFeatures);
- wasmFeatures.disable(disabledFeatures);
- passOptions.features = wasmFeatures;
- } else if (!(wasmFeatures <= passOptions.features)) {
- Fatal() << "module uses features not explicitly specified, "
- << "use --detect-features to resolve";
+ if (!detectFeatures && module.hasFeaturesSection) {
+ FeatureSet optionsFeatures = FeatureSet::All;
+ optionsFeatures.enable(enabledFeatures);
+ optionsFeatures.disable(disabledFeatures);
+ if (!(module.features <= optionsFeatures)) {
+ Fatal() << "module uses features not explicitly specified, "
+ << "use --detect-features to resolve";
+ }
}
- } else if (wasmHasFeatures) {
- passOptions.features = wasmFeatures;
+ module.features.enable(enabledFeatures);
+ module.features.disable(disabledFeatures);
}
}
private:
bool hasFeatureOptions = false;
bool detectFeatures = false;
- FeatureSet enabledFeatures = FeatureSet::MVP;
+ FeatureSet enabledFeatures = FeatureSet::All;
FeatureSet disabledFeatures = FeatureSet::MVP;
};
diff --git a/src/tools/wasm-as.cpp b/src/tools/wasm-as.cpp
index c504c2a81..fb79eb7cf 100644
--- a/src/tools/wasm-as.cpp
+++ b/src/tools/wasm-as.cpp
@@ -91,9 +91,11 @@ int main(int argc, const char *argv[]) {
Fatal() << "error in parsing input";
}
+ wasm.features = FeatureSet::All;
+
if (options.extra["validate"] != "none") {
if (options.debug) std::cerr << "Validating..." << std::endl;
- if (!wasm::WasmValidator().validate(wasm, FeatureSet::All,
+ if (!wasm::WasmValidator().validate(wasm,
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-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp
index be1de7684..7509eb84f 100644
--- a/src/tools/wasm-ctor-eval.cpp
+++ b/src/tools/wasm-ctor-eval.cpp
@@ -425,7 +425,7 @@ int main(int argc, const char* argv[]) {
}
}
- options.calculateFeatures(wasm);
+ options.applyFeatures(wasm);
if (!WasmValidator().validate(wasm)) {
WasmPrinter::printModule(&wasm);
@@ -444,7 +444,6 @@ int main(int argc, const char* argv[]) {
// Do some useful optimizations after the evalling
{
PassRunner passRunner(&wasm);
- passRunner.setFeatures(options.passOptions.features);
passRunner.add("memory-packing"); // we flattened it, so re-optimize
passRunner.add("remove-unused-names");
passRunner.add("dce");
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp
index e39d9e2d6..46fb0533b 100644
--- a/src/tools/wasm-emscripten-finalize.cpp
+++ b/src/tools/wasm-emscripten-finalize.cpp
@@ -130,7 +130,7 @@ int main(int argc, const char *argv[]) {
Fatal() << "error in parsing wasm source map";
}
- options.calculateFeatures(wasm);
+ options.applyFeatures(wasm);
if (options.debug) {
std::cerr << "Module before:\n";
@@ -210,7 +210,7 @@ int main(int argc, const char *argv[]) {
}
// Substantial changes to the wasm are done, enough to create the metadata.
- std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions, options.passOptions.features);
+ std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions);
// Finally, separate out data segments if relevant (they may have been needed
// for metadata).
diff --git a/src/tools/wasm-opt.cpp b/src/tools/wasm-opt.cpp
index d36459a4a..6fce0f89b 100644
--- a/src/tools/wasm-opt.cpp
+++ b/src/tools/wasm-opt.cpp
@@ -162,26 +162,26 @@ int main(int argc, const char* argv[]) {
Fatal() << "error in building module, std::bad_alloc (possibly invalid request for silly amounts of memory)";
}
- options.calculateFeatures(wasm);
+ options.applyFeatures(wasm);
if (options.passOptions.validate) {
- if (!WasmValidator().validate(wasm, options.passOptions.features)) {
+ if (!WasmValidator().validate(wasm)) {
WasmPrinter::printModule(&wasm);
Fatal() << "error in validating input";
}
}
} else {
// translate-to-fuzz
+ options.applyFeatures(wasm);
TranslateToFuzzReader reader(wasm, options.extra["infile"]);
if (fuzzPasses) {
reader.pickPasses(options);
}
- reader.setFeatures(options.passOptions.features);
reader.setAllowNaNs(fuzzNaNs);
reader.setAllowMemory(fuzzMemory);
reader.build();
if (options.passOptions.validate) {
- if (!WasmValidator().validate(wasm, options.passOptions.features)) {
+ if (!WasmValidator().validate(wasm)) {
WasmPrinter::printModule(&wasm);
std::cerr << "translate-to-fuzz must always generate a valid module";
abort();
@@ -241,7 +241,7 @@ int main(int argc, const char* argv[]) {
WasmBinaryBuilder parser(other, input, false);
parser.read();
if (options.passOptions.validate) {
- bool valid = WasmValidator().validate(other, options.passOptions.features);
+ bool valid = WasmValidator().validate(other);
if (!valid) {
WasmPrinter::printModule(&other);
}
@@ -256,7 +256,7 @@ int main(int argc, const char* argv[]) {
options.runPasses(*curr);
if (options.passOptions.validate) {
bool valid =
- WasmValidator().validate(*curr, options.passOptions.features);
+ WasmValidator().validate(*curr);
if (!valid) {
WasmPrinter::printModule(&*curr);
}
diff --git a/src/tools/wasm-reduce.cpp b/src/tools/wasm-reduce.cpp
index 36a44b056..1f58da0d5 100644
--- a/src/tools/wasm-reduce.cpp
+++ b/src/tools/wasm-reduce.cpp
@@ -819,7 +819,7 @@ struct Reducer : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor<
FunctionReferenceRemover referenceRemover(names);
referenceRemover.walkModule(module.get());
- if (WasmValidator().validate(*module, FeatureSet::All, WasmValidator::Globally | WasmValidator::Quiet) &&
+ if (WasmValidator().validate(*module, 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 0d7ff61de..0c95b39ea 100644
--- a/src/tools/wasm-shell.cpp
+++ b/src/tools/wasm-shell.cpp
@@ -25,12 +25,12 @@
#include "execution-results.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"
#include "wasm-s-parser.h"
#include "wasm-validator.h"
-#include "tool-options.h"
using namespace cashew;
using namespace wasm;
@@ -233,7 +233,7 @@ int main(int argc, const char* argv[]) {
Name entry;
std::set<size_t> skipped;
- ToolOptions options("wasm-shell", "Execute .wast files");
+ Options options("wasm-shell", "Execute .wast files");
options
.add(
"--entry", "-e", "Call the entry point after parsing the module",
@@ -292,7 +292,8 @@ int main(int argc, const char* argv[]) {
builders[moduleName].swap(builder);
modules[moduleName].swap(module);
i++;
- bool valid = WasmValidator().validate(*modules[moduleName], options.passOptions.features);
+ modules[moduleName]->features = FeatureSet::All;
+ bool valid = WasmValidator().validate(*modules[moduleName]);
if (!valid) {
WasmPrinter::printModule(modules[moduleName].get());
}
diff --git a/src/tools/wasm2js.cpp b/src/tools/wasm2js.cpp
index 8704dbf49..67a5d33b6 100644
--- a/src/tools/wasm2js.cpp
+++ b/src/tools/wasm2js.cpp
@@ -407,7 +407,7 @@ int main(int argc, const char *argv[]) {
ModuleReader reader;
reader.setDebug(options.debug);
reader.read(input, wasm, "");
- options.calculateFeatures(wasm);
+ options.applyFeatures(wasm);
} else {
auto input(
read_file<std::vector<char>>(options.extra["infile"], Flags::Text, options.debug ? Flags::Debug : Flags::Release));
@@ -426,7 +426,7 @@ int main(int argc, const char *argv[]) {
}
if (options.passOptions.validate) {
- if (!WasmValidator().validate(wasm, options.passOptions.features)) {
+ if (!WasmValidator().validate(wasm)) {
WasmPrinter::printModule(&wasm);
Fatal() << "error in validating input";
}