summaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/fuzzing.h41
-rw-r--r--src/tools/tool-options.h16
-rw-r--r--src/tools/wasm-emscripten-finalize.cpp15
3 files changed, 64 insertions, 8 deletions
diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h
index 56c633f14..63e7dca43 100644
--- a/src/tools/fuzzing.h
+++ b/src/tools/fuzzing.h
@@ -727,6 +727,9 @@ private:
&Self::makeSelect,
&Self::makeGetGlobal)
.add(FeatureSet::SIMD, &Self::makeSIMD);
+ if (type == none) {
+ options.add(FeatureSet::BulkMemory, &Self::makeBulkMemory);
+ }
if (type == i32 || type == i64) {
options.add(FeatureSet::Atomics, &Self::makeAtomic);
}
@@ -1713,6 +1716,44 @@ private:
return builder.makeSIMDShift(op, vec, shift);
}
+ Expression* makeBulkMemory(Type type) {
+ assert(features.hasBulkMemory());
+ assert(type == none);
+ switch (upTo(4)) {
+ case 0: return makeMemoryInit();
+ case 1: return makeDataDrop();
+ case 2: return makeMemoryCopy();
+ case 3: return makeMemoryFill();
+ }
+ WASM_UNREACHABLE();
+ }
+
+ Expression* makeMemoryInit() {
+ auto segment = uint32_t(get32());
+ Expression* dest = make(i32);
+ Expression* offset = make(i32);
+ Expression* size = make(i32);
+ return builder.makeMemoryInit(segment, dest, offset, size);
+ }
+
+ Expression* makeDataDrop() {
+ return builder.makeDataDrop(get32());
+ }
+
+ Expression* makeMemoryCopy() {
+ Expression* dest = make(i32);
+ Expression* source = make(i32);
+ Expression* size = make(i32);
+ return builder.makeMemoryCopy(dest, source, size);
+ }
+
+ Expression* makeMemoryFill() {
+ Expression* dest = make(i32);
+ Expression* value = make(i32);
+ Expression* size = make(i32);
+ return builder.makeMemoryFill(dest, value, size);
+ }
+
// special makers
Expression* makeLogging() {
diff --git a/src/tools/tool-options.h b/src/tools/tool-options.h
index 9aff8e619..5620883ec 100644
--- a/src/tools/tool-options.h
+++ b/src/tools/tool-options.h
@@ -72,17 +72,29 @@ struct ToolOptions : public Options {
passOptions.features.setTruncSat(false);
})
.add("--enable-simd", "",
- "Enable nontrapping float-to-int operations",
+ "Enable SIMD operations and types",
Options::Arguments::Zero,
[this](Options *o, const std::string& arguments) {
passOptions.features.setSIMD();
})
.add("--disable-simd", "",
- "Disable nontrapping float-to-int operations",
+ "Disable SIMD operations and types",
Options::Arguments::Zero,
[this](Options *o, const std::string& arguments) {
passOptions.features.setSIMD(false);
})
+ .add("--enable-bulk-memory", "",
+ "Enable bulk memory operations",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features.setBulkMemory();
+ })
+ .add("--disable-bulk-memory", "",
+ "Disable bulk memory operations",
+ Options::Arguments::Zero,
+ [this](Options *o, const std::string& arguments) {
+ passOptions.features.setBulkMemory(false);
+ })
.add("--no-validation", "-n", "Disables validation, assumes inputs are correct",
Options::Arguments::Zero,
[this](Options* o, const std::string& argument) {
diff --git a/src/tools/wasm-emscripten-finalize.cpp b/src/tools/wasm-emscripten-finalize.cpp
index d0b664c0c..f2c74221d 100644
--- a/src/tools/wasm-emscripten-finalize.cpp
+++ b/src/tools/wasm-emscripten-finalize.cpp
@@ -204,12 +204,8 @@ int main(int argc, const char *argv[]) {
generator.generateDynCallThunks();
generator.generateJSCallThunks(numReservedFunctionPointers);
- if (!dataSegmentFile.empty()) {
- Output memInitFile(dataSegmentFile, Flags::Binary, Flags::Release);
- generator.separateDataSegments(&memInitFile);
- }
- // Finally, legalize the wasm.
+ // Legalize the wasm.
{
PassRunner passRunner(&wasm);
passRunner.setDebug(options.debug);
@@ -221,9 +217,16 @@ int main(int argc, const char *argv[]) {
passRunner.run();
}
- // All changes to the wasm are done, create the metadata.
+ // Substantial changes to the wasm are done, enough to create the metadata.
std::string metadata = generator.generateEmscriptenMetadata(dataSize, initializerFunctions, numReservedFunctionPointers);
+ // Finally, separate out data segments if relevant (they may have been needed
+ // for metadata).
+ if (!dataSegmentFile.empty()) {
+ Output memInitFile(dataSegmentFile, Flags::Binary, Flags::Release);
+ generator.separateDataSegments(&memInitFile);
+ }
+
if (options.debug) {
std::cerr << "Module after:\n";
WasmPrinter::printModule(&wasm, std::cerr);