diff options
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/asm2wasm.cpp | 6 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 31 | ||||
-rw-r--r-- | src/tools/optimization-options.h | 1 | ||||
-rw-r--r-- | src/tools/tool-options.h | 40 | ||||
-rw-r--r-- | src/tools/wasm-as.cpp | 4 | ||||
-rw-r--r-- | src/tools/wasm-ctor-eval.cpp | 3 | ||||
-rw-r--r-- | src/tools/wasm-emscripten-finalize.cpp | 4 | ||||
-rw-r--r-- | src/tools/wasm-opt.cpp | 12 | ||||
-rw-r--r-- | src/tools/wasm-reduce.cpp | 2 | ||||
-rw-r--r-- | src/tools/wasm-shell.cpp | 7 | ||||
-rw-r--r-- | src/tools/wasm2js.cpp | 4 |
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"; } |