diff options
88 files changed, 2346 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f7ba5c71d..6c75b5688 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,16 @@ SET_PROPERTY(TARGET wasm-opt PROPERTY CXX_STANDARD 11) SET_PROPERTY(TARGET wasm-opt PROPERTY CXX_STANDARD_REQUIRED ON) INSTALL(TARGETS wasm-opt DESTINATION ${CMAKE_INSTALL_BINDIR}) +SET(wasm-merge_SOURCES + src/tools/wasm-merge.cpp +) +ADD_EXECUTABLE(wasm-merge + ${wasm-merge_SOURCES}) +TARGET_LINK_LIBRARIES(wasm-merge wasm asmjs emscripten-optimizer ${all_passes} ast support) +SET_PROPERTY(TARGET wasm-merge PROPERTY CXX_STANDARD 11) +SET_PROPERTY(TARGET wasm-merge PROPERTY CXX_STANDARD_REQUIRED ON) +INSTALL(TARGETS wasm-merge DESTINATION bin) + SET(asm2wasm_SOURCES src/tools/asm2wasm.cpp src/wasm-emscripten.cpp diff --git a/auto_update_tests.py b/auto_update_tests.py index 9f569d14d..76cd02cbb 100755 --- a/auto_update_tests.py +++ b/auto_update_tests.py @@ -193,6 +193,26 @@ for t in os.listdir('test'): open(t + '.fromBinary', 'w').write(actual) +print '\n[ checking wasm-merge... ]\n' + +for t in os.listdir(os.path.join('test', 'merge')): + if t.endswith(('.wast', '.wasm')): + print '..', t + t = os.path.join('test', 'merge', t) + u = t + '.toMerge' + for finalize in [0, 1]: + for opt in [0, 1]: + cmd = [os.path.join('bin', 'wasm-merge'), t, u, '-o', 'a.wast', '-S', '--verbose'] + if finalize: cmd += ['--finalize-memory-base=1024', '--finalize-table-base=8'] + if opt: cmd += ['-O'] + stdout = run_command(cmd) + actual = open('a.wast').read() + out = t + '.combined' + if finalize: out += '.finalized' + if opt: out += '.opt' + with open(out, 'w') as o: o.write(actual) + with open(out + '.stdout', 'w') as o: o.write(stdout) + print '\n[ checking binaryen.js testcases... ]\n' for s in sorted(os.listdir(os.path.join('test', 'binaryen.js'))): @@ -215,6 +215,28 @@ for t in tests: if actual != expected: fail(actual, expected) +print '\n[ checking wasm-merge... ]\n' + +for t in os.listdir(os.path.join('test', 'merge')): + if t.endswith(('.wast', '.wasm')): + print '..', t + t = os.path.join('test', 'merge', t) + u = t + '.toMerge' + for finalize in [0, 1]: + for opt in [0, 1]: + cmd = [os.path.join('bin', 'wasm-merge'), t, u, '-o', 'a.wast', '-S', '--verbose'] + if finalize: cmd += ['--finalize-memory-base=1024', '--finalize-table-base=8'] + if opt: cmd += ['-O'] + stdout = run_command(cmd) + actual = open('a.wast').read() + out = t + '.combined' + if finalize: out += '.finalized' + if opt: out += '.opt' + with open(out) as f: + fail_if_not_identical(f.read(), actual) + with open(out + '.stdout') as f: + fail_if_not_identical(f.read(), stdout) + print '\n[ checking wasm-shell spec testcases... ]\n' if len(requested) == 0: diff --git a/src/shared-constants.h b/src/shared-constants.h index 923ccc7de..a3d8e4fda 100644 --- a/src/shared-constants.h +++ b/src/shared-constants.h @@ -14,9 +14,15 @@ * limitations under the License. */ +#ifndef wasm_shared_constants_h + +#include "wasm.h" + namespace wasm { extern Name GROW_WASM_MEMORY, + MEMORY_BASE, + TABLE_BASE, NEW_SIZE, MODULE, START, @@ -54,3 +60,5 @@ extern Name GROW_WASM_MEMORY, } // namespace wasm +#endif // wasm_shared_constants_h + diff --git a/src/tools/wasm-merge.cpp b/src/tools/wasm-merge.cpp new file mode 100644 index 000000000..766beac8f --- /dev/null +++ b/src/tools/wasm-merge.cpp @@ -0,0 +1,639 @@ +/* + * Copyright 2017 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. + */ + +// +// A WebAssembly merger: loads multiple files, smashes them together, +// and emits the result. +// +// This is *not* a real linker. It just does naive merging. +// + +#include <memory> + +#include "parsing.h" +#include "pass.h" +#include "shared-constants.h" +#include "asmjs/shared-constants.h" +#include "asm_v_wasm.h" +#include "support/command-line.h" +#include "support/file.h" +#include "wasm-io.h" +#include "wasm-binary.h" +#include "wasm-builder.h" +#include "wasm-validator.h" + +using namespace wasm; + +// Calls note() on every import that has form "env".(base) +static void findImportsByBase(Module& wasm, Name base, std::function<void (Name)> note) { + for (auto& curr : wasm.imports) { + if (curr->module == ENV) { + if (curr->base == base) { + note(curr->name); + } + } + } +} + +// Ensure a memory or table is of at least a size +template<typename T> +static void ensureSize(T& what, Index size) { + // ensure the size is sufficient + while (what.initial * what.kPageSize < size) { + what.initial = what.initial + 1; + } + what.max = std::max(what.initial, what.max); +} + +// A mergeable unit. This class contains basic logic to prepare for merging +// of two modules. +struct Mergeable { + Mergeable(Module& wasm) : wasm(wasm) { + // scan the module + findSizes(); + findImports(); + standardizeSegments(); + } + + // The module we are working on + Module& wasm; + + // Total sizes of the memory and table data, including things + // link a bump from the dylink section + Index totalMemorySize, totalTableSize; + + // The names of the imported globals for the memory and table bases + // (sets, as each may be imported more than once) + std::set<Name> memoryBaseGlobals, tableBaseGlobals; + + // Imported functions and globals provided by the other mergeable + // are fused together. We track those here, then remove them + std::map<Name, Name> implementedFunctionImports; + std::map<Name, Name> implementedGlobalImports; + + // setups + + // find the memory and table sizes. if there are relocatable sections for them, + // that is the base size, and a dylink section may increase things further + void findSizes() { + totalMemorySize = 0; + totalTableSize = 0; + for (auto& segment : wasm.memory.segments) { + Expression* offset = segment.offset; + if (offset->is<GetGlobal>()) { + totalMemorySize = segment.data.size(); + break; + } + } + for (auto& segment : wasm.table.segments) { + Expression* offset = segment.offset; + if (offset->is<GetGlobal>()) { + totalTableSize = segment.data.size(); + break; + } + } + for (auto& section : wasm.userSections) { + if (section.name == "dylink") { + WasmBinaryBuilder builder(wasm, section.data, false); + totalMemorySize = std::max(totalMemorySize, builder.getU32LEB()); + totalTableSize = std::max(totalTableSize, builder.getU32LEB()); + break; // there can be only one + } + } + // align them + while (totalMemorySize % 16 != 0) totalMemorySize++; + while (totalTableSize % 2 != 0) totalTableSize++; + } + + void findImports() { + findImportsByBase(wasm, MEMORY_BASE, [&](Name name) { + memoryBaseGlobals.insert(name); + }); + if (memoryBaseGlobals.size() == 0) { + Fatal() << "no memory base was imported"; + } + findImportsByBase(wasm, TABLE_BASE, [&](Name name) { + tableBaseGlobals.insert(name); + }); + if (tableBaseGlobals.size() == 0) { + Fatal() << "no table base was imported"; + } + } + + void standardizeSegments() { + standardizeSegment<Memory, char, Memory::Segment>(wasm, wasm.memory, totalMemorySize, 0, *memoryBaseGlobals.begin()); + // if there are no functions, and we need one, we need to add one as the zero + if (totalTableSize > 0 && wasm.functions.empty()) { + auto func = new Function; + func->name = Name("binaryen$merge-zero"); + func->body = Builder(wasm).makeNop(); + func->type = ensureFunctionType("v", &wasm)->name; + wasm.addFunction(func); + } + Name zero; + if (totalTableSize > 0) { + zero = wasm.functions.begin()->get()->name; + } + standardizeSegment<Table, Name, Table::Segment>(wasm, wasm.table, totalTableSize, zero, *tableBaseGlobals.begin()); + } + + // utilities + + Name getNonColliding(Name initial, std::function<bool (Name)> checkIfCollides) { + if (!checkIfCollides(initial)) { + return initial; + } + int x = 0; + while (1) { + auto curr = Name(std::string(initial.str) + '$' + std::to_string(x)); + if (!checkIfCollides(curr)) { + return curr; + } + x++; + } + } + + // ensure a relocatable segment exists, of the proper size, including + // the dylink bump applied into it, standardized into the form of + // not using a dylink section and instead having enough zeros at + // the end. this makes linking much simpler. + template<typename T, typename U, typename Segment> + void standardizeSegment(Module& wasm, T& what, Index size, U zero, Name globalName) { + Segment* relocatable = nullptr; + for (auto& segment : what.segments) { + Expression* offset = segment.offset; + if (offset->is<GetGlobal>()) { + // this is the relocatable one. + relocatable = &segment; + break; + } + } + if (!relocatable) { + // none existing, add one + what.segments.resize(what.segments.size() + 1); + relocatable = &what.segments.back(); + relocatable->offset = Builder(wasm).makeGetGlobal(globalName, i32); + } + // make sure it is the right size + while (relocatable->data.size() < size) { + relocatable->data.push_back(zero); + } + ensureSize(what, relocatable->data.size()); + } + + // copies a relocatable segment from the input to the output + template<typename T, typename V> + void copySegment(T& output, T& input, V updater) { + for (auto& inputSegment : input.segments) { + Expression* inputOffset = inputSegment.offset; + if (inputOffset->is<GetGlobal>()) { + // this is the relocatable one. find the output's relocatable + for (auto& segment : output.segments) { + Expression* offset = segment.offset; + if (offset->is<GetGlobal>()) { + // copy our data in + for (auto item : inputSegment.data) { + segment.data.push_back(updater(item)); + } + ensureSize(output, segment.data.size()); + return; // there can be only one + } + } + WASM_UNREACHABLE(); // we must find a relocatable one in the output, as we standardized + } + } + } +}; + +// A mergeable that is an output, that is, that we merge into. This adds +// logic to update it for the new data, namely, when an import is provided +// by the other merged unit, we resolve to access that value directly. +struct OutputMergeable : public PostWalker<OutputMergeable, Visitor<OutputMergeable>>, public Mergeable { + OutputMergeable(Module& wasm) : Mergeable(wasm) {} + + void visitCallImport(CallImport* curr) { + auto iter = implementedFunctionImports.find(curr->target); + if (iter != implementedFunctionImports.end()) { + // this import is now in the module - call it + replaceCurrent(Builder(*getModule()).makeCall(iter->second, curr->operands, curr->type)); + } + } + + void visitGetGlobal(GetGlobal* curr) { + auto iter = implementedGlobalImports.find(curr->name); + if (iter != implementedGlobalImports.end()) { + // this global is now in the module - get it + curr->name = iter->second; + assert(curr->name.is()); + } + } + + void visitModule(Module* curr) { + // remove imports that are being implemented + for (auto& pair : implementedFunctionImports) { + curr->removeImport(pair.first); + } + for (auto& pair : implementedGlobalImports) { + curr->removeImport(pair.first); + } + } +}; + +// A mergeable that is an input, that is, that we merge into another. +// This adds logic to disambiguate its names from the other, and to +// perform all other merging operations. +struct InputMergeable : public ExpressionStackWalker<InputMergeable, Visitor<InputMergeable>>, public Mergeable { + InputMergeable(Module& wasm, OutputMergeable& outputMergeable) : Mergeable(wasm), outputMergeable(outputMergeable) {} + + // The unit we are being merged into + OutputMergeable& outputMergeable; + + // mappings (after disambiguating with the other mergeable), old name => new name + std::map<Name, Name> ftNames; // function types + std::map<Name, Name> eNames; // exports + std::map<Name, Name> fNames; // functions + std::map<Name, Name> gNames; // globals + + void visitCall(Call* curr) { + curr->target = fNames[curr->target]; + assert(curr->target.is()); + } + + void visitCallImport(CallImport* curr) { + auto iter = implementedFunctionImports.find(curr->target); + if (iter != implementedFunctionImports.end()) { + // this import is now in the module - call it + replaceCurrent(Builder(*getModule()).makeCall(iter->second, curr->operands, curr->type)); + return; + } + curr->target = fNames[curr->target]; + assert(curr->target.is()); + } + + void visitCallIndirect(CallIndirect* curr) { + curr->fullType = ftNames[curr->fullType]; + assert(curr->fullType.is()); + } + + void visitGetGlobal(GetGlobal* curr) { + auto iter = implementedGlobalImports.find(curr->name); + if (iter != implementedGlobalImports.end()) { + // this import is now in the module - use it + curr->name = iter->second; + return; + } + curr->name = gNames[curr->name]; + assert(curr->name.is()); + // if this is the memory or table base, add the bump + if (memoryBaseGlobals.count(curr->name)) { + addBump(outputMergeable.totalMemorySize); + } else if (tableBaseGlobals.count(curr->name)) { + addBump(outputMergeable.totalTableSize); + } + } + + void visitSetGlobal(SetGlobal* curr) { + curr->name = gNames[curr->name]; + assert(curr->name.is()); + } + + void merge() { + // find function imports in us that are implemented in the output + // TODO make maps, avoid N^2 + for (auto& imp : wasm.imports) { + // per wasm dynamic library rules, we expect to see exports on 'env' + if ((imp->kind == ExternalKind::Function || imp->kind == ExternalKind::Global) && imp->module == ENV) { + // seek an export on the other side that matches + for (auto& exp : outputMergeable.wasm.exports) { + if (exp->kind == imp->kind && exp->name == imp->base) { + // fits! + if (imp->kind == ExternalKind::Function) { + implementedFunctionImports[imp->name] = exp->value; + } else { + implementedGlobalImports[imp->name] = exp->value; + } + break; + } + } + } + } + // remove the unneeded ones + for (auto& pair : implementedFunctionImports) { + wasm.removeImport(pair.first); + } + for (auto& pair : implementedGlobalImports) { + wasm.removeImport(pair.first); + } + + // find new names + for (auto& curr : wasm.functionTypes) { + curr->name = ftNames[curr->name] = getNonColliding(curr->name, [&](Name name) -> bool { + return outputMergeable.wasm.getFunctionTypeOrNull(name); + }); + } + for (auto& curr : wasm.imports) { + if (curr->kind == ExternalKind::Function) { + curr->name = fNames[curr->name] = getNonColliding(curr->name, [&](Name name) -> bool { + return !!outputMergeable.wasm.getImportOrNull(name) || !!outputMergeable.wasm.getFunctionOrNull(name); + }); + } else if (curr->kind == ExternalKind::Global) { + curr->name = gNames[curr->name] = getNonColliding(curr->name, [&](Name name) -> bool { + return !!outputMergeable.wasm.getImportOrNull(name) || !!outputMergeable.wasm.getGlobalOrNull(name); + }); + } + } + for (auto& curr : wasm.functions) { + curr->name = fNames[curr->name] = getNonColliding(curr->name, [&](Name name) -> bool { + return outputMergeable.wasm.getFunctionOrNull(name); + }); + } + for (auto& curr : wasm.globals) { + curr->name = gNames[curr->name] = getNonColliding(curr->name, [&](Name name) -> bool { + return outputMergeable.wasm.getGlobalOrNull(name); + }); + } + + // update global names in input + { + auto temp = memoryBaseGlobals; + memoryBaseGlobals.clear(); + for (auto x : temp) { + memoryBaseGlobals.insert(gNames[x]); + } + } + { + auto temp = tableBaseGlobals; + tableBaseGlobals.clear(); + for (auto x : temp) { + tableBaseGlobals.insert(gNames[x]); + } + } + + // find function imports in output that are implemented in the input + for (auto& imp : outputMergeable.wasm.imports) { + if ((imp->kind == ExternalKind::Function || imp->kind == ExternalKind::Global) && imp->module == ENV) { + for (auto& exp : wasm.exports) { + if (exp->kind == imp->kind && exp->name == imp->base) { + if (imp->kind == ExternalKind::Function) { + outputMergeable.implementedFunctionImports[imp->name] = fNames[exp->value]; + } else { + outputMergeable.implementedGlobalImports[imp->name] = gNames[exp->value]; + } + break; + } + } + } + } + + // update the output before bringing anything in. avoid doing so when possible, as in the + // common case the output module is very large. + if (outputMergeable.implementedFunctionImports.size() + outputMergeable.implementedGlobalImports.size() > 0) { + outputMergeable.walkModule(&outputMergeable.wasm); + } + + // memory&table: we place the new memory segments at a higher position. after the existing ones. + copySegment(outputMergeable.wasm.memory, wasm.memory, [](char x) -> char { return x; }); + copySegment(outputMergeable.wasm.table, wasm.table, [&](Name x) -> Name { return fNames[x]; }); + + // update the new contents about to be merged in + walkModule(&wasm); + + // handle the dylink post-instantiate. this is special, as if it exists in both, we must in fact call both + Name POST_INSTANTIATE("__post_instantiate"); + if (fNames.find(POST_INSTANTIATE) != fNames.end() && + outputMergeable.wasm.getExportOrNull(POST_INSTANTIATE)) { + // indeed, both exist. add a call to the second (wasm spec does not give an order requirement) + auto* func = outputMergeable.wasm.getFunction(outputMergeable.wasm.getExport(POST_INSTANTIATE)->value); + Builder builder(outputMergeable.wasm); + func->body = builder.makeSequence( + builder.makeCall(fNames[POST_INSTANTIATE], {}, none), + func->body + ); + } + + // copy in the data + for (auto& curr : wasm.functionTypes) { + outputMergeable.wasm.addFunctionType(curr.release()); + } + for (auto& curr : wasm.imports) { + if (curr->kind == ExternalKind::Memory || curr->kind == ExternalKind::Table) { + continue; // wasm has just 1 of each, they must match + } + // update and add + if (curr->functionType.is()) { + curr->functionType = ftNames[curr->functionType]; + assert(curr->functionType.is()); + } + outputMergeable.wasm.addImport(curr.release()); + } + for (auto& curr : wasm.exports) { + if (curr->kind == ExternalKind::Memory || curr->kind == ExternalKind::Table) { + continue; // wasm has just 1 of each, they must match + } + // if an export would collide, do not add the new one, ignore it + // TODO: warning/error mode? + if (!outputMergeable.wasm.getExportOrNull(curr->name)) { + if (curr->kind == ExternalKind::Function) { + curr->value = fNames[curr->value]; + outputMergeable.wasm.addExport(curr.release()); + } else if (curr->kind == ExternalKind::Global) { + curr->value = gNames[curr->value]; + outputMergeable.wasm.addExport(curr.release()); + } else { + WASM_UNREACHABLE(); + } + } + } + for (auto& curr : wasm.functions) { + curr->type = ftNames[curr->type]; + assert(curr->type.is()); + outputMergeable.wasm.addFunction(curr.release()); + } + for (auto& curr : wasm.globals) { + outputMergeable.wasm.addGlobal(curr.release()); + } + } + +private: + // add an offset to a get_global. we look above, and if there is already an add, + // we can add into it, avoiding creating a new node + void addBump(Index bump) { + if (expressionStack.size() >= 2) { + auto* parent = expressionStack[expressionStack.size() - 2]; + if (auto* binary = parent->dynCast<Binary>()) { + if (binary->op == AddInt32) { + if (auto* num = binary->right->dynCast<Const>()) { + num->value = num->value.add(Literal(bump)); + return; + } + } + } + } + Builder builder(*getModule()); + replaceCurrent( + builder.makeBinary( + AddInt32, + expressionStack.back(), + builder.makeConst(Literal(int32_t(bump))) + ) + ); + } +}; + +// Finalize the memory/table bases, assinging concrete values into them +void finalizeBases(Module& wasm, Index memory, Index table) { + struct FinalizableMergeable : public Mergeable, public PostWalker<FinalizableMergeable, Visitor<FinalizableMergeable>> { + FinalizableMergeable(Module& wasm, Index memory, Index table) : Mergeable(wasm), memory(memory), table(table) { + walkModule(&wasm); + // ensure memory and table sizes suffice, after finalization we have absolute locations now + for (auto& segment : wasm.memory.segments) { + ensureSize(wasm.memory, memory + segment.data.size()); + } + for (auto& segment : wasm.table.segments) { + ensureSize(wasm.table, table + segment.data.size()); + } + } + + Index memory, table; + + void visitGetGlobal(GetGlobal* curr) { + if (memory != Index(-1) && memoryBaseGlobals.count(curr->name)) { + finalize(memory); + } else if (table != Index(-1) && tableBaseGlobals.count(curr->name)) { + finalize(table); + } + } + + private: + void finalize(Index value) { + replaceCurrent(Builder(*getModule()).makeConst(Literal(int32_t(value)))); + } + }; + FinalizableMergeable mergeable(wasm, memory, table); +} + +// +// main +// + +int main(int argc, const char* argv[]) { + std::vector<std::string> filenames; + bool emitBinary = true; + Index finalizeMemoryBase = Index(-1), + finalizeTableBase = Index(-1); + bool optimize = false; + bool verbose = false; + + Options options("wasm-merge", "Merge wasm files"); + options + .add("--output", "-o", "Output file", + Options::Arguments::One, + [](Options* o, const std::string& argument) { + o->extra["output"] = argument; + Colors::disable(); + }) + .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("--finalize-memory-base", "-fmb", "Finalize the env.memoryBase import", + Options::Arguments::One, + [&](Options* o, const std::string& argument) { + finalizeMemoryBase = atoi(argument.c_str()); + }) + .add("--finalize-table-base", "-fmb", "Finalize the env.tableBase import", + Options::Arguments::One, + [&](Options* o, const std::string& argument) { + finalizeTableBase = atoi(argument.c_str()); + }) + .add("-O", "-O", "Perform merge-time/finalize-time optimizations", + Options::Arguments::Zero, + [&](Options* o, const std::string& argument) { + optimize = true; + }) + .add("--verbose", "-v", "Verbose output", + Options::Arguments::Zero, + [&](Options* o, const std::string& argument) { + verbose = true; + }) + .add_positional("INFILES", Options::Arguments::N, + [&](Options *o, const std::string &argument) { + filenames.push_back(argument); + }); + options.parse(argc, argv); + + Module output; + std::vector<std::unique_ptr<Module>> otherModules; // keep all inputs alive, to save copies + bool first = true; + for (auto& filename : filenames) { + ModuleReader reader; + if (first) { + // read the first right into output, don't waste time merging into an empty module + try { + reader.read(filename, output); + } catch (ParseException& p) { + p.dump(std::cerr); + Fatal() << "error in parsing input"; + } + first = false; + } else { + std::unique_ptr<Module> input = wasm::make_unique<Module>(); + try { + reader.read(filename, *input); + } catch (ParseException& p) { + p.dump(std::cerr); + Fatal() << "error in parsing input"; + } + // perform the merge + OutputMergeable outputMergeable(output); + InputMergeable inputMergeable(*input, outputMergeable); + inputMergeable.merge(); + // retain the linked in module as we may depend on parts of it + otherModules.push_back(std::unique_ptr<Module>(input.release())); + } + } + + if (verbose) { + // memory and table are standardized and merged, so it's easy to dump out some stats + std::cout << "merged total memory size: " << output.memory.segments[0].data.size() << '\n'; + std::cout << "merged total table size: " << output.table.segments[0].data.size() << '\n'; + std::cout << "merged functions: " << output.functions.size() << '\n'; + } + + if (finalizeMemoryBase != Index(-1) || finalizeTableBase != Index(-1)) { + finalizeBases(output, finalizeMemoryBase, finalizeTableBase); + } + + if (optimize) { + // merge-time/finalize-time optimization + // it is beneficial to do global optimizations, as well as precomputing to get rid of finalized constants + PassRunner passRunner(&output); + passRunner.add("precompute"); + passRunner.add("optimize-instructions"); // things now-constant may be further optimized + passRunner.addDefaultGlobalOptimizationPasses(); + passRunner.run(); + } + + if (!WasmValidator().validate(output)) { + Fatal() << "error in validating output"; + } + + if (options.extra.count("output") > 0) { + ModuleWriter writer; + writer.setDebug(options.debug); + writer.setBinary(emitBinary); + writer.write(output, options.extra["output"]); + } +} diff --git a/src/wasm-validator.h b/src/wasm-validator.h index 4d198ac34..4631a63b8 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -426,7 +426,9 @@ public: if (!validateGlobally) return; shouldBeTrue(curr->init != nullptr, curr->name, "global init must be non-null"); shouldBeTrue(curr->init->is<Const>() || curr->init->is<GetGlobal>(), curr->name, "global init must be valid"); - shouldBeEqual(curr->type, curr->init->type, nullptr, "global init must have correct type"); + if (!shouldBeEqual(curr->type, curr->init->type, curr->init, "global init must have correct type")) { + std::cerr << "(on global " << curr->name << '\n'; + } } void visitFunction(Function *curr) { diff --git a/src/wasm.h b/src/wasm.h index b27fe6acb..4804322b6 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -561,6 +561,7 @@ public: class Table { public: + static const Address::address_t kPageSize = 1; static const Index kMaxSize = Index(-1); struct Segment { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 7e75d9178..a983fc943 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -32,6 +32,8 @@ const char* Name = "name"; } Name GROW_WASM_MEMORY("__growWasmMemory"), + MEMORY_BASE("memoryBase"), + TABLE_BASE("tableBase"), NEW_SIZE("newSize"), MODULE("module"), START("start"), diff --git a/test/merge/basics.wast b/test/merge/basics.wast new file mode 100644 index 000000000..7a234584b --- /dev/null +++ b/test/merge/basics.wast @@ -0,0 +1,38 @@ +(module + (type $ii (func (param i32 i32))) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "some-func" (func $some-func)) + (import "env" "some-collide" (func $some-collide)) + (data (get_global $memoryBase) "hello, A!\n") + (global $global-collide i32 (i32.const 0)) + (global $global-collide-mut (mut i32) (i32.const 0)) + (global $global-a i32 (i32.const 1)) + (elem (get_global $tableBase) $only-a $willCollide $some-func $some-collide $only-a) + (export "exp-a" (func $only-a)) + (export "exp-collide" (func $only-a)) + (export "exp-collide2" (func $willCollide)) + (func $only-a + (drop (i32.const 100)) + (call $only-a) + (call_import $some-func) + (call_import $some-collide) + (call_indirect $ii + (i32.const 123) + (i32.const 456) + (i32.const 789) + ) + (drop (get_global $global-collide)) + (drop (get_global $global-a)) + (drop (get_global $memoryBase)) + (drop (get_global $tableBase)) + (set_global $global-collide-mut (i32.const 1234)) + ) + (func $willCollide + (drop (i32.const 200)) + (call $willCollide) + ) +) + diff --git a/test/merge/basics.wast.combined b/test/merge/basics.wast.combined new file mode 100644 index 000000000..f0654ec7a --- /dev/null +++ b/test/merge/basics.wast.combined @@ -0,0 +1,133 @@ +(module + (type $ii (func (param i32 i32))) + (type $FUNCSIG$v (func)) + (type $ii$0 (func (param i32 i32))) + (type $FUNCSIG$v$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 10 anyfunc)) + (import "env" "some-func" (func $some-func)) + (import "env" "some-collide" (func $some-collide)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (import "env" "some-func-b" (func $some-func-b)) + (import "env" "some-collide" (func $some-collide$0)) + (global $global-collide i32 (i32.const 0)) + (global $global-collide-mut (mut i32) (i32.const 0)) + (global $global-a i32 (i32.const 1)) + (global $global-collide$0 i32 (i32.const 0)) + (global $global-collide-mut$0 (mut i32) (i32.const 0)) + (global $global-b i32 (i32.const 1)) + (elem (get_global $tableBase) $only-a $willCollide $some-func $some-collide $only-a $only-a $only-b $willCollide$0 $some-func-b $some-collide$0) + (data (get_global $memoryBase) "hello, A!\n\00\00\00\00\00\00hello, B!\n\00\00\00\00\00\00") + (export "exp-a" (func $only-a)) + (export "exp-collide" (func $only-a)) + (export "exp-collide2" (func $willCollide)) + (export "exp-b" (func $only-b)) + (export "exp-b-nameCollided" (func $willCollide$0)) + (func $only-a (type $FUNCSIG$v) + (drop + (i32.const 100) + ) + (call $only-a) + (call $some-func) + (call $some-collide) + (call_indirect $ii + (i32.const 123) + (i32.const 456) + (i32.const 789) + ) + (drop + (get_global $global-collide) + ) + (drop + (get_global $global-a) + ) + (drop + (get_global $memoryBase) + ) + (drop + (get_global $tableBase) + ) + (set_global $global-collide-mut + (i32.const 1234) + ) + ) + (func $willCollide (type $FUNCSIG$v) + (drop + (i32.const 200) + ) + (call $willCollide) + ) + (func $only-b (type $FUNCSIG$v$0) + (drop + (i32.const 111) + ) + (call $only-b) + (call $some-func-b) + (call $some-collide$0) + (call_indirect $ii$0 + (i32.const 12) + (i32.const 34) + (i32.const 56) + ) + (drop + (get_global $global-collide$0) + ) + (drop + (get_global $global-b) + ) + (drop + (i32.add + (get_global $memoryBase$0) + (i32.const 16) + ) + ) + (drop + (i32.add + (get_global $tableBase$0) + (i32.const 6) + ) + ) + (drop + (i32.add + (get_global $memoryBase$0) + (i32.const 1016) + ) + ) + (drop + (i32.add + (get_global $tableBase$0) + (i32.const 1006) + ) + ) + (drop + (i32.add + (i32.add + (get_global $tableBase$0) + (i32.const 6) + ) + (unreachable) + ) + ) + (drop + (i32.sub + (i32.add + (get_global $tableBase$0) + (i32.const 6) + ) + (i32.const 1000) + ) + ) + (set_global $global-collide-mut$0 + (i32.const 5678) + ) + ) + (func $willCollide$0 (type $FUNCSIG$v$0) + (drop + (i32.const 222) + ) + (call $willCollide$0) + ) +) diff --git a/test/merge/basics.wast.combined.finalized b/test/merge/basics.wast.combined.finalized new file mode 100644 index 000000000..7637b787b --- /dev/null +++ b/test/merge/basics.wast.combined.finalized @@ -0,0 +1,133 @@ +(module + (type $ii (func (param i32 i32))) + (type $FUNCSIG$v (func)) + (type $ii$0 (func (param i32 i32))) + (type $FUNCSIG$v$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 18 anyfunc)) + (import "env" "some-func" (func $some-func)) + (import "env" "some-collide" (func $some-collide)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (import "env" "some-func-b" (func $some-func-b)) + (import "env" "some-collide" (func $some-collide$0)) + (global $global-collide i32 (i32.const 0)) + (global $global-collide-mut (mut i32) (i32.const 0)) + (global $global-a i32 (i32.const 1)) + (global $global-collide$0 i32 (i32.const 0)) + (global $global-collide-mut$0 (mut i32) (i32.const 0)) + (global $global-b i32 (i32.const 1)) + (elem (i32.const 8) $only-a $willCollide $some-func $some-collide $only-a $only-a $only-b $willCollide$0 $some-func-b $some-collide$0) + (data (i32.const 1024) "hello, A!\n\00\00\00\00\00\00hello, B!\n\00\00\00\00\00\00") + (export "exp-a" (func $only-a)) + (export "exp-collide" (func $only-a)) + (export "exp-collide2" (func $willCollide)) + (export "exp-b" (func $only-b)) + (export "exp-b-nameCollided" (func $willCollide$0)) + (func $only-a (type $FUNCSIG$v) + (drop + (i32.const 100) + ) + (call $only-a) + (call $some-func) + (call $some-collide) + (call_indirect $ii + (i32.const 123) + (i32.const 456) + (i32.const 789) + ) + (drop + (get_global $global-collide) + ) + (drop + (get_global $global-a) + ) + (drop + (i32.const 1024) + ) + (drop + (i32.const 8) + ) + (set_global $global-collide-mut + (i32.const 1234) + ) + ) + (func $willCollide (type $FUNCSIG$v) + (drop + (i32.const 200) + ) + (call $willCollide) + ) + (func $only-b (type $FUNCSIG$v$0) + (drop + (i32.const 111) + ) + (call $only-b) + (call $some-func-b) + (call $some-collide$0) + (call_indirect $ii$0 + (i32.const 12) + (i32.const 34) + (i32.const 56) + ) + (drop + (get_global $global-collide$0) + ) + (drop + (get_global $global-b) + ) + (drop + (i32.add + (i32.const 1024) + (i32.const 16) + ) + ) + (drop + (i32.add + (i32.const 8) + (i32.const 6) + ) + ) + (drop + (i32.add + (i32.const 1024) + (i32.const 1016) + ) + ) + (drop + (i32.add + (i32.const 8) + (i32.const 1006) + ) + ) + (drop + (i32.add + (i32.add + (i32.const 8) + (i32.const 6) + ) + (unreachable) + ) + ) + (drop + (i32.sub + (i32.add + (i32.const 8) + (i32.const 6) + ) + (i32.const 1000) + ) + ) + (set_global $global-collide-mut$0 + (i32.const 5678) + ) + ) + (func $willCollide$0 (type $FUNCSIG$v$0) + (drop + (i32.const 222) + ) + (call $willCollide$0) + ) +) diff --git a/test/merge/basics.wast.combined.finalized.opt b/test/merge/basics.wast.combined.finalized.opt new file mode 100644 index 000000000..320ba8fa7 --- /dev/null +++ b/test/merge/basics.wast.combined.finalized.opt @@ -0,0 +1,86 @@ +(module + (type $ii (func (param i32 i32))) + (type $FUNCSIG$v (func)) + (type $ii$0 (func (param i32 i32))) + (type $FUNCSIG$v$0 (func)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 18 anyfunc)) + (import "env" "some-func" (func $some-func)) + (import "env" "some-collide" (func $some-collide)) + (import "env" "some-func-b" (func $some-func-b)) + (import "env" "some-collide" (func $some-collide$0)) + (global $global-collide i32 (i32.const 0)) + (global $global-collide-mut (mut i32) (i32.const 0)) + (global $global-a i32 (i32.const 1)) + (global $global-collide$0 i32 (i32.const 0)) + (global $global-collide-mut$0 (mut i32) (i32.const 0)) + (global $global-b i32 (i32.const 1)) + (elem (i32.const 8) $only-a $willCollide $some-func $some-collide $only-a $only-a $only-b $willCollide$0 $some-func-b $some-collide$0) + (data (i32.const 1024) "hello, A!\n\00\00\00\00\00\00hello, B!\n") + (export "exp-a" (func $only-a)) + (export "exp-collide" (func $only-a)) + (export "exp-collide2" (func $willCollide)) + (export "exp-b" (func $only-b)) + (export "exp-b-nameCollided" (func $willCollide$0)) + (func $only-a (type $FUNCSIG$v) + (nop) + (call $only-a) + (call $some-func) + (call $some-collide) + (call_indirect $ii + (i32.const 123) + (i32.const 456) + (i32.const 789) + ) + (drop + (get_global $global-collide) + ) + (drop + (get_global $global-a) + ) + (nop) + (nop) + (set_global $global-collide-mut + (i32.const 1234) + ) + ) + (func $willCollide (type $FUNCSIG$v) + (nop) + (call $willCollide) + ) + (func $only-b (type $FUNCSIG$v$0) + (nop) + (call $only-b) + (call $some-func-b) + (call $some-collide$0) + (call_indirect $ii$0 + (i32.const 12) + (i32.const 34) + (i32.const 56) + ) + (drop + (get_global $global-collide$0) + ) + (drop + (get_global $global-b) + ) + (nop) + (nop) + (nop) + (nop) + (drop + (i32.add + (unreachable) + (i32.const 14) + ) + ) + (nop) + (set_global $global-collide-mut$0 + (i32.const 5678) + ) + ) + (func $willCollide$0 (type $FUNCSIG$v$0) + (nop) + (call $willCollide$0) + ) +) diff --git a/test/merge/basics.wast.combined.finalized.opt.stdout b/test/merge/basics.wast.combined.finalized.opt.stdout new file mode 100644 index 000000000..18fbdb05e --- /dev/null +++ b/test/merge/basics.wast.combined.finalized.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 32 +merged total table size: 10 +merged functions: 4 diff --git a/test/merge/basics.wast.combined.finalized.stdout b/test/merge/basics.wast.combined.finalized.stdout new file mode 100644 index 000000000..18fbdb05e --- /dev/null +++ b/test/merge/basics.wast.combined.finalized.stdout @@ -0,0 +1,3 @@ +merged total memory size: 32 +merged total table size: 10 +merged functions: 4 diff --git a/test/merge/basics.wast.combined.opt b/test/merge/basics.wast.combined.opt new file mode 100644 index 000000000..ba8ab6220 --- /dev/null +++ b/test/merge/basics.wast.combined.opt @@ -0,0 +1,122 @@ +(module + (type $ii (func (param i32 i32))) + (type $FUNCSIG$v (func)) + (type $ii$0 (func (param i32 i32))) + (type $FUNCSIG$v$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 10 anyfunc)) + (import "env" "some-func" (func $some-func)) + (import "env" "some-collide" (func $some-collide)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (import "env" "some-func-b" (func $some-func-b)) + (import "env" "some-collide" (func $some-collide$0)) + (global $global-collide i32 (i32.const 0)) + (global $global-collide-mut (mut i32) (i32.const 0)) + (global $global-a i32 (i32.const 1)) + (global $global-collide$0 i32 (i32.const 0)) + (global $global-collide-mut$0 (mut i32) (i32.const 0)) + (global $global-b i32 (i32.const 1)) + (elem (get_global $tableBase) $only-a $willCollide $some-func $some-collide $only-a $only-a $only-b $willCollide$0 $some-func-b $some-collide$0) + (data (get_global $memoryBase) "hello, A!\n\00\00\00\00\00\00hello, B!\n") + (export "exp-a" (func $only-a)) + (export "exp-collide" (func $only-a)) + (export "exp-collide2" (func $willCollide)) + (export "exp-b" (func $only-b)) + (export "exp-b-nameCollided" (func $willCollide$0)) + (func $only-a (type $FUNCSIG$v) + (nop) + (call $only-a) + (call $some-func) + (call $some-collide) + (call_indirect $ii + (i32.const 123) + (i32.const 456) + (i32.const 789) + ) + (drop + (get_global $global-collide) + ) + (drop + (get_global $global-a) + ) + (drop + (get_global $memoryBase) + ) + (drop + (get_global $tableBase) + ) + (set_global $global-collide-mut + (i32.const 1234) + ) + ) + (func $willCollide (type $FUNCSIG$v) + (nop) + (call $willCollide) + ) + (func $only-b (type $FUNCSIG$v$0) + (nop) + (call $only-b) + (call $some-func-b) + (call $some-collide$0) + (call_indirect $ii$0 + (i32.const 12) + (i32.const 34) + (i32.const 56) + ) + (drop + (get_global $global-collide$0) + ) + (drop + (get_global $global-b) + ) + (drop + (i32.add + (get_global $memoryBase$0) + (i32.const 16) + ) + ) + (drop + (i32.add + (get_global $tableBase$0) + (i32.const 6) + ) + ) + (drop + (i32.add + (get_global $memoryBase$0) + (i32.const 1016) + ) + ) + (drop + (i32.add + (get_global $tableBase$0) + (i32.const 1006) + ) + ) + (drop + (i32.add + (i32.add + (get_global $tableBase$0) + (i32.const 6) + ) + (unreachable) + ) + ) + (drop + (i32.add + (get_global $tableBase$0) + (i32.const -994) + ) + ) + (set_global $global-collide-mut$0 + (i32.const 5678) + ) + ) + (func $willCollide$0 (type $FUNCSIG$v$0) + (nop) + (call $willCollide$0) + ) +) diff --git a/test/merge/basics.wast.combined.opt.stdout b/test/merge/basics.wast.combined.opt.stdout new file mode 100644 index 000000000..18fbdb05e --- /dev/null +++ b/test/merge/basics.wast.combined.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 32 +merged total table size: 10 +merged functions: 4 diff --git a/test/merge/basics.wast.combined.stdout b/test/merge/basics.wast.combined.stdout new file mode 100644 index 000000000..18fbdb05e --- /dev/null +++ b/test/merge/basics.wast.combined.stdout @@ -0,0 +1,3 @@ +merged total memory size: 32 +merged total table size: 10 +merged functions: 4 diff --git a/test/merge/basics.wast.toMerge b/test/merge/basics.wast.toMerge new file mode 100644 index 000000000..5122afe31 --- /dev/null +++ b/test/merge/basics.wast.toMerge @@ -0,0 +1,63 @@ +(module + (type $ii (func (param i32 i32))) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "some-func-b" (func $some-func-b)) + (import "env" "some-collide" (func $some-collide)) + (data (get_global $memoryBase) "hello, B!\n") + (global $global-collide i32 (i32.const 0)) + (global $global-collide-mut (mut i32) (i32.const 0)) + (global $global-b i32 (i32.const 1)) + (elem (get_global $tableBase) $only-b $willCollide $some-func-b $some-collide) + (export "exp-b" (func $only-b)) + (export "exp-collide" (func $only-b)) + (export "exp-collide2" (func $willCollide)) + (export "exp-b-nameCollided" (func $willCollide)) + (func $only-b + (drop (i32.const 111)) + (call $only-b) + (call $some-func-b) + (call_import $some-collide) + (call_indirect $ii + (i32.const 12) + (i32.const 34) + (i32.const 56) + ) + (drop (get_global $global-collide)) + (drop (get_global $global-b)) + (drop (get_global $memoryBase)) + (drop (get_global $tableBase)) + (drop + (i32.add + (get_global $memoryBase) + (i32.const 1000) + ) + ) + (drop + (i32.add + (get_global $tableBase) + (i32.const 1000) + ) + ) + (drop + (i32.add + (get_global $tableBase) + (unreachable) ;; bad! + ) + ) + (drop + (i32.sub ;; bad! + (get_global $tableBase) + (i32.const 1000) + ) + ) + (set_global $global-collide-mut (i32.const 5678)) + ) + (func $willCollide + (drop (i32.const 222)) + (call $willCollide) + ) +) + diff --git a/test/merge/dylib.wasm b/test/merge/dylib.wasm Binary files differnew file mode 100644 index 000000000..4d86a9483 --- /dev/null +++ b/test/merge/dylib.wasm diff --git a/test/merge/dylib.wasm.combined b/test/merge/dylib.wasm.combined new file mode 100644 index 000000000..0133476a9 --- /dev/null +++ b/test/merge/dylib.wasm.combined @@ -0,0 +1,91 @@ +(module + (type $0 (func (param i32 i32))) + (type $1 (func (param i32) (result i32))) + (type $2 (func (result i32))) + (type $3 (func)) + (type $0$0 (func (param i32 i32))) + (type $1$0 (func (result i32))) + (type $2$0 (func)) + (import "env" "memoryBase" (global $import$0 i32)) + (import "env" "_puts" (func $import$1 (param i32) (result i32))) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "tableBase" (global $import$4 i32)) + (import "env" "memoryBase" (global $import$0$0 i32)) + (import "env" "tableBase" (global $import$4$0 i32)) + (global $global$0 (mut i32) (i32.const 0)) + (global $global$1 (mut i32) (i32.const 0)) + (global $global$2 i32 (i32.const 0)) + (global $global$0$0 (mut i32) (i32.const 0)) + (global $global$1$0 (mut i32) (i32.const 0)) + + (data (get_global $import$0) "hello, world!\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (export "__post_instantiate" (func $__post_instantiate)) + (export "_main" (func $_main)) + (export "runPostSets" (func $runPostSets)) + (export "_str" (global $global$2)) + (export "_foo" (func $_foo)) + (func $_main (type $2) (result i32) + (block $label$0 i32 + (drop + (call $import$1 + (get_global $import$0) + ) + ) + (i32.const 0) + ) + ) + (func $runPostSets (type $3) + (nop) + ) + (func $__post_instantiate (type $3) + (call $__post_instantiate$0) + (block + (block $label$0 + (set_global $global$0 + (i32.add + (get_global $import$0) + (i32.const 16) + ) + ) + (set_global $global$1 + (i32.add + (get_global $global$0) + (i32.const 32) + ) + ) + (call $runPostSets) + ) + ) + ) + (func $_foo (type $1$0) (result i32) + (local $var$0 i32) + (block $label$0 i32 + (set_local $var$0 + (call $_main) + ) + (get_local $var$0) + ) + ) + (func $runPostSets$0 (type $2$0) + (nop) + ) + (func $__post_instantiate$0 (type $2$0) + (block $label$0 + (set_global $global$0$0 + (i32.add + (get_global $import$0$0) + (i32.const 48) + ) + ) + (set_global $global$1$0 + (i32.add + (get_global $global$0$0) + (i32.const 10) + ) + ) + (call $runPostSets$0) + ) + ) + ;; custom section "dylink", size 2 +) diff --git a/test/merge/dylib.wasm.combined.finalized b/test/merge/dylib.wasm.combined.finalized new file mode 100644 index 000000000..c3f64a0b5 --- /dev/null +++ b/test/merge/dylib.wasm.combined.finalized @@ -0,0 +1,91 @@ +(module + (type $0 (func (param i32 i32))) + (type $1 (func (param i32) (result i32))) + (type $2 (func (result i32))) + (type $3 (func)) + (type $0$0 (func (param i32 i32))) + (type $1$0 (func (result i32))) + (type $2$0 (func)) + (import "env" "memoryBase" (global $import$0 i32)) + (import "env" "_puts" (func $import$1 (param i32) (result i32))) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 8 anyfunc)) + (import "env" "tableBase" (global $import$4 i32)) + (import "env" "memoryBase" (global $import$0$0 i32)) + (import "env" "tableBase" (global $import$4$0 i32)) + (global $global$0 (mut i32) (i32.const 0)) + (global $global$1 (mut i32) (i32.const 0)) + (global $global$2 i32 (i32.const 0)) + (global $global$0$0 (mut i32) (i32.const 0)) + (global $global$1$0 (mut i32) (i32.const 0)) + + (data (i32.const 1024) "hello, world!\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") + (export "__post_instantiate" (func $__post_instantiate)) + (export "_main" (func $_main)) + (export "runPostSets" (func $runPostSets)) + (export "_str" (global $global$2)) + (export "_foo" (func $_foo)) + (func $_main (type $2) (result i32) + (block $label$0 i32 + (drop + (call $import$1 + (i32.const 1024) + ) + ) + (i32.const 0) + ) + ) + (func $runPostSets (type $3) + (nop) + ) + (func $__post_instantiate (type $3) + (call $__post_instantiate$0) + (block + (block $label$0 + (set_global $global$0 + (i32.add + (i32.const 1024) + (i32.const 16) + ) + ) + (set_global $global$1 + (i32.add + (get_global $global$0) + (i32.const 32) + ) + ) + (call $runPostSets) + ) + ) + ) + (func $_foo (type $1$0) (result i32) + (local $var$0 i32) + (block $label$0 i32 + (set_local $var$0 + (call $_main) + ) + (get_local $var$0) + ) + ) + (func $runPostSets$0 (type $2$0) + (nop) + ) + (func $__post_instantiate$0 (type $2$0) + (block $label$0 + (set_global $global$0$0 + (i32.add + (i32.const 1024) + (i32.const 48) + ) + ) + (set_global $global$1$0 + (i32.add + (get_global $global$0$0) + (i32.const 10) + ) + ) + (call $runPostSets$0) + ) + ) + ;; custom section "dylink", size 2 +) diff --git a/test/merge/dylib.wasm.combined.finalized.opt b/test/merge/dylib.wasm.combined.finalized.opt new file mode 100644 index 000000000..2d40fb83c --- /dev/null +++ b/test/merge/dylib.wasm.combined.finalized.opt @@ -0,0 +1,81 @@ +(module + (type $0 (func (param i32 i32))) + (type $1 (func (param i32) (result i32))) + (type $2 (func (result i32))) + (type $3 (func)) + (type $0$0 (func (param i32 i32))) + (type $1$0 (func (result i32))) + (type $2$0 (func)) + (import "env" "_puts" (func $import$1 (param i32) (result i32))) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 8 anyfunc)) + (global $global$0 (mut i32) (i32.const 0)) + (global $global$1 (mut i32) (i32.const 0)) + (global $global$2 i32 (i32.const 0)) + (global $global$0$0 (mut i32) (i32.const 0)) + (global $global$1$0 (mut i32) (i32.const 0)) + + (data (i32.const 1024) "hello, world!") + (export "__post_instantiate" (func $__post_instantiate)) + (export "_main" (func $_main)) + (export "runPostSets" (func $runPostSets)) + (export "_str" (global $global$2)) + (export "_foo" (func $_foo)) + (func $_main (type $2) (result i32) + (block $label$0 i32 + (drop + (call $import$1 + (i32.const 1024) + ) + ) + (i32.const 0) + ) + ) + (func $runPostSets (type $3) + (nop) + ) + (func $__post_instantiate (type $3) + (call $__post_instantiate$0) + (block + (block $label$0 + (set_global $global$0 + (i32.const 1040) + ) + (set_global $global$1 + (i32.add + (get_global $global$0) + (i32.const 32) + ) + ) + (call $runPostSets) + ) + ) + ) + (func $_foo (type $1$0) (result i32) + (local $var$0 i32) + (block $label$0 i32 + (set_local $var$0 + (call $_main) + ) + (get_local $var$0) + ) + ) + (func $runPostSets$0 (type $2$0) + (nop) + ) + (func $__post_instantiate$0 (type $2$0) + (block $label$0 + (set_global $global$0$0 + (i32.const 1072) + ) + (set_global $global$1$0 + (i32.add + (get_global $global$0$0) + (i32.const 10) + ) + ) + (call $runPostSets$0) + ) + ) + ;; custom section "dylink", size 2 +) diff --git a/test/merge/dylib.wasm.combined.finalized.opt.stdout b/test/merge/dylib.wasm.combined.finalized.opt.stdout new file mode 100644 index 000000000..fb480861a --- /dev/null +++ b/test/merge/dylib.wasm.combined.finalized.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 64 +merged total table size: 0 +merged functions: 6 diff --git a/test/merge/dylib.wasm.combined.finalized.stdout b/test/merge/dylib.wasm.combined.finalized.stdout new file mode 100644 index 000000000..fb480861a --- /dev/null +++ b/test/merge/dylib.wasm.combined.finalized.stdout @@ -0,0 +1,3 @@ +merged total memory size: 64 +merged total table size: 0 +merged functions: 6 diff --git a/test/merge/dylib.wasm.combined.opt b/test/merge/dylib.wasm.combined.opt new file mode 100644 index 000000000..8c354e34d --- /dev/null +++ b/test/merge/dylib.wasm.combined.opt @@ -0,0 +1,90 @@ +(module + (type $0 (func (param i32 i32))) + (type $1 (func (param i32) (result i32))) + (type $2 (func (result i32))) + (type $3 (func)) + (type $0$0 (func (param i32 i32))) + (type $1$0 (func (result i32))) + (type $2$0 (func)) + (import "env" "memoryBase" (global $import$0 i32)) + (import "env" "_puts" (func $import$1 (param i32) (result i32))) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "tableBase" (global $import$4 i32)) + (import "env" "memoryBase" (global $import$0$0 i32)) + (global $global$0 (mut i32) (i32.const 0)) + (global $global$1 (mut i32) (i32.const 0)) + (global $global$2 i32 (i32.const 0)) + (global $global$0$0 (mut i32) (i32.const 0)) + (global $global$1$0 (mut i32) (i32.const 0)) + + (data (get_global $import$0) "hello, world!") + (export "__post_instantiate" (func $__post_instantiate)) + (export "_main" (func $_main)) + (export "runPostSets" (func $runPostSets)) + (export "_str" (global $global$2)) + (export "_foo" (func $_foo)) + (func $_main (type $2) (result i32) + (block $label$0 i32 + (drop + (call $import$1 + (get_global $import$0) + ) + ) + (i32.const 0) + ) + ) + (func $runPostSets (type $3) + (nop) + ) + (func $__post_instantiate (type $3) + (call $__post_instantiate$0) + (block + (block $label$0 + (set_global $global$0 + (i32.add + (get_global $import$0) + (i32.const 16) + ) + ) + (set_global $global$1 + (i32.add + (get_global $global$0) + (i32.const 32) + ) + ) + (call $runPostSets) + ) + ) + ) + (func $_foo (type $1$0) (result i32) + (local $var$0 i32) + (block $label$0 i32 + (set_local $var$0 + (call $_main) + ) + (get_local $var$0) + ) + ) + (func $runPostSets$0 (type $2$0) + (nop) + ) + (func $__post_instantiate$0 (type $2$0) + (block $label$0 + (set_global $global$0$0 + (i32.add + (get_global $import$0$0) + (i32.const 48) + ) + ) + (set_global $global$1$0 + (i32.add + (get_global $global$0$0) + (i32.const 10) + ) + ) + (call $runPostSets$0) + ) + ) + ;; custom section "dylink", size 2 +) diff --git a/test/merge/dylib.wasm.combined.opt.stdout b/test/merge/dylib.wasm.combined.opt.stdout new file mode 100644 index 000000000..fb480861a --- /dev/null +++ b/test/merge/dylib.wasm.combined.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 64 +merged total table size: 0 +merged functions: 6 diff --git a/test/merge/dylib.wasm.combined.stdout b/test/merge/dylib.wasm.combined.stdout new file mode 100644 index 000000000..fb480861a --- /dev/null +++ b/test/merge/dylib.wasm.combined.stdout @@ -0,0 +1,3 @@ +merged total memory size: 64 +merged total table size: 0 +merged functions: 6 diff --git a/test/merge/dylib.wasm.toMerge b/test/merge/dylib.wasm.toMerge Binary files differnew file mode 100644 index 000000000..c9953956b --- /dev/null +++ b/test/merge/dylib.wasm.toMerge diff --git a/test/merge/fusing.wast b/test/merge/fusing.wast new file mode 100644 index 000000000..588647e35 --- /dev/null +++ b/test/merge/fusing.wast @@ -0,0 +1,18 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (export "foo" (func $foo-func)) + (import "env" "bar" (func $bar-func)) + (global $a-global i32 (i32.const 0)) + (export "aglobal" (global $a-global)) + (import "env" "bglobal" (global $b-global f64)) + (func $foo-func + (drop (i32.const 1337)) + (call_import $bar-func) + (drop (get_global $a-global)) + (drop (get_global $b-global)) + ) +) + diff --git a/test/merge/fusing.wast.combined b/test/merge/fusing.wast.combined new file mode 100644 index 000000000..2a7adf6e2 --- /dev/null +++ b/test/merge/fusing.wast.combined @@ -0,0 +1,44 @@ +(module + (type $FUNCSIG$v (func)) + (type $FUNCSIG$v$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (global $a-global i32 (i32.const 0)) + (global $b-global f64 (f64.const 2.14281428)) + + (data (get_global $memoryBase) "") + (export "foo" (func $foo-func)) + (export "aglobal" (global $a-global)) + (export "bar" (func $bar-func)) + (export "bglobal" (global $b-global)) + (func $foo-func (type $FUNCSIG$v) + (drop + (i32.const 1337) + ) + (call $bar-func) + (drop + (get_global $a-global) + ) + (drop + (get_global $b-global) + ) + ) + (func $b (type $FUNCSIG$v$0) + (call $foo-func) + ) + (func $bar-func (type $FUNCSIG$v$0) + (drop + (f64.const 3.14159) + ) + (drop + (get_global $a-global) + ) + (drop + (get_global $b-global) + ) + ) +) diff --git a/test/merge/fusing.wast.combined.finalized b/test/merge/fusing.wast.combined.finalized new file mode 100644 index 000000000..7896e448d --- /dev/null +++ b/test/merge/fusing.wast.combined.finalized @@ -0,0 +1,44 @@ +(module + (type $FUNCSIG$v (func)) + (type $FUNCSIG$v$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 8 anyfunc)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (global $a-global i32 (i32.const 0)) + (global $b-global f64 (f64.const 2.14281428)) + + (data (i32.const 1024) "") + (export "foo" (func $foo-func)) + (export "aglobal" (global $a-global)) + (export "bar" (func $bar-func)) + (export "bglobal" (global $b-global)) + (func $foo-func (type $FUNCSIG$v) + (drop + (i32.const 1337) + ) + (call $bar-func) + (drop + (get_global $a-global) + ) + (drop + (get_global $b-global) + ) + ) + (func $b (type $FUNCSIG$v$0) + (call $foo-func) + ) + (func $bar-func (type $FUNCSIG$v$0) + (drop + (f64.const 3.14159) + ) + (drop + (get_global $a-global) + ) + (drop + (get_global $b-global) + ) + ) +) diff --git a/test/merge/fusing.wast.combined.finalized.opt b/test/merge/fusing.wast.combined.finalized.opt new file mode 100644 index 000000000..202c566e1 --- /dev/null +++ b/test/merge/fusing.wast.combined.finalized.opt @@ -0,0 +1,32 @@ +(module + (type $FUNCSIG$v (func)) + (type $FUNCSIG$v$0 (func)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 8 anyfunc)) + (global $a-global i32 (i32.const 0)) + (global $b-global f64 (f64.const 2.14281428)) + + (export "foo" (func $foo-func)) + (export "aglobal" (global $a-global)) + (export "bar" (func $bar-func)) + (export "bglobal" (global $b-global)) + (func $foo-func (type $FUNCSIG$v) + (nop) + (call $bar-func) + (drop + (get_global $a-global) + ) + (drop + (get_global $b-global) + ) + ) + (func $bar-func (type $FUNCSIG$v$0) + (nop) + (drop + (get_global $a-global) + ) + (drop + (get_global $b-global) + ) + ) +) diff --git a/test/merge/fusing.wast.combined.finalized.opt.stdout b/test/merge/fusing.wast.combined.finalized.opt.stdout new file mode 100644 index 000000000..80b514d22 --- /dev/null +++ b/test/merge/fusing.wast.combined.finalized.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 3 diff --git a/test/merge/fusing.wast.combined.finalized.stdout b/test/merge/fusing.wast.combined.finalized.stdout new file mode 100644 index 000000000..80b514d22 --- /dev/null +++ b/test/merge/fusing.wast.combined.finalized.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 3 diff --git a/test/merge/fusing.wast.combined.opt b/test/merge/fusing.wast.combined.opt new file mode 100644 index 000000000..1a09fb784 --- /dev/null +++ b/test/merge/fusing.wast.combined.opt @@ -0,0 +1,35 @@ +(module + (type $FUNCSIG$v (func)) + (type $FUNCSIG$v$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (global $a-global i32 (i32.const 0)) + (global $b-global f64 (f64.const 2.14281428)) + + (data (get_global $memoryBase) "") + (export "foo" (func $foo-func)) + (export "aglobal" (global $a-global)) + (export "bar" (func $bar-func)) + (export "bglobal" (global $b-global)) + (func $foo-func (type $FUNCSIG$v) + (nop) + (call $bar-func) + (drop + (get_global $a-global) + ) + (drop + (get_global $b-global) + ) + ) + (func $bar-func (type $FUNCSIG$v$0) + (nop) + (drop + (get_global $a-global) + ) + (drop + (get_global $b-global) + ) + ) +) diff --git a/test/merge/fusing.wast.combined.opt.stdout b/test/merge/fusing.wast.combined.opt.stdout new file mode 100644 index 000000000..80b514d22 --- /dev/null +++ b/test/merge/fusing.wast.combined.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 3 diff --git a/test/merge/fusing.wast.combined.stdout b/test/merge/fusing.wast.combined.stdout new file mode 100644 index 000000000..80b514d22 --- /dev/null +++ b/test/merge/fusing.wast.combined.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 3 diff --git a/test/merge/fusing.wast.toMerge b/test/merge/fusing.wast.toMerge new file mode 100644 index 000000000..4abd0a5e1 --- /dev/null +++ b/test/merge/fusing.wast.toMerge @@ -0,0 +1,20 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "foo" (func $b-foo)) + (export "bar" (func $bar-func)) + (global $b-global f64 (f64.const 2.14281428)) + (export "bglobal" (global $b-global)) + (import "env" "aglobal" (global $a-global i32)) + (func $b + (call $b-foo) + ) + (func $bar-func + (drop (f64.const 3.14159)) + (drop (get_global $a-global)) + (drop (get_global $b-global)) + ) +) + diff --git a/test/merge/global-init.wast b/test/merge/global-init.wast new file mode 100644 index 000000000..ddf1a868f --- /dev/null +++ b/test/merge/global-init.wast @@ -0,0 +1,10 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "globally" (global $i-collide i32)) + (global $a i32 (get_global $i-collide)) + (global $g-collide i32 (get_global $i-collide)) +) + diff --git a/test/merge/global-init.wast.combined b/test/merge/global-init.wast.combined new file mode 100644 index 000000000..95b339968 --- /dev/null +++ b/test/merge/global-init.wast.combined @@ -0,0 +1,16 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "globally" (global $i-collide i32)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (import "env" "globally" (global $i-collide$0 f64)) + (global $a i32 (get_global $i-collide)) + (global $g-collide i32 (get_global $i-collide)) + (global $b f64 (get_global $i-collide$0)) + (global $g-collide$0 f64 (get_global $i-collide$0)) + + (data (get_global $memoryBase) "") +) diff --git a/test/merge/global-init.wast.combined.finalized b/test/merge/global-init.wast.combined.finalized new file mode 100644 index 000000000..40a5066fa --- /dev/null +++ b/test/merge/global-init.wast.combined.finalized @@ -0,0 +1,16 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 8 anyfunc)) + (import "env" "globally" (global $i-collide i32)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (import "env" "globally" (global $i-collide$0 f64)) + (global $a i32 (get_global $i-collide)) + (global $g-collide i32 (get_global $i-collide)) + (global $b f64 (get_global $i-collide$0)) + (global $g-collide$0 f64 (get_global $i-collide$0)) + + (data (i32.const 1024) "") +) diff --git a/test/merge/global-init.wast.combined.finalized.opt b/test/merge/global-init.wast.combined.finalized.opt new file mode 100644 index 000000000..02a0900f5 --- /dev/null +++ b/test/merge/global-init.wast.combined.finalized.opt @@ -0,0 +1,5 @@ +(module + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 8 anyfunc)) + +) diff --git a/test/merge/global-init.wast.combined.finalized.opt.stdout b/test/merge/global-init.wast.combined.finalized.opt.stdout new file mode 100644 index 000000000..361590ef0 --- /dev/null +++ b/test/merge/global-init.wast.combined.finalized.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 0 diff --git a/test/merge/global-init.wast.combined.finalized.stdout b/test/merge/global-init.wast.combined.finalized.stdout new file mode 100644 index 000000000..361590ef0 --- /dev/null +++ b/test/merge/global-init.wast.combined.finalized.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 0 diff --git a/test/merge/global-init.wast.combined.opt b/test/merge/global-init.wast.combined.opt new file mode 100644 index 000000000..44c047693 --- /dev/null +++ b/test/merge/global-init.wast.combined.opt @@ -0,0 +1,8 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + + (data (get_global $memoryBase) "") +) diff --git a/test/merge/global-init.wast.combined.opt.stdout b/test/merge/global-init.wast.combined.opt.stdout new file mode 100644 index 000000000..361590ef0 --- /dev/null +++ b/test/merge/global-init.wast.combined.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 0 diff --git a/test/merge/global-init.wast.combined.stdout b/test/merge/global-init.wast.combined.stdout new file mode 100644 index 000000000..361590ef0 --- /dev/null +++ b/test/merge/global-init.wast.combined.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 0 diff --git a/test/merge/global-init.wast.toMerge b/test/merge/global-init.wast.toMerge new file mode 100644 index 000000000..6f5d5e6dd --- /dev/null +++ b/test/merge/global-init.wast.toMerge @@ -0,0 +1,10 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "globally" (global $i-collide f64)) + (global $b f64 (get_global $i-collide)) + (global $g-collide f64 (get_global $i-collide)) +) + diff --git a/test/merge/main-lacks-segments.wast b/test/merge/main-lacks-segments.wast new file mode 100644 index 000000000..c18db2470 --- /dev/null +++ b/test/merge/main-lacks-segments.wast @@ -0,0 +1,7 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) +) + diff --git a/test/merge/main-lacks-segments.wast.combined b/test/merge/main-lacks-segments.wast.combined new file mode 100644 index 000000000..33eb89435 --- /dev/null +++ b/test/merge/main-lacks-segments.wast.combined @@ -0,0 +1,25 @@ +(module + (type $0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 2 anyfunc)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (elem (get_global $tableBase) $foo $foo) + (data (get_global $memoryBase) "hello, this is some data!\00\00\00\00\00\00\00") + (func $foo (type $0) + (drop + (i32.add + (get_global $tableBase$0) + (i32.const 0) + ) + ) + (drop + (i32.add + (get_global $memoryBase$0) + (i32.const 0) + ) + ) + ) +) diff --git a/test/merge/main-lacks-segments.wast.combined.finalized b/test/merge/main-lacks-segments.wast.combined.finalized new file mode 100644 index 000000000..923ffd34d --- /dev/null +++ b/test/merge/main-lacks-segments.wast.combined.finalized @@ -0,0 +1,25 @@ +(module + (type $0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 10 anyfunc)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (elem (i32.const 8) $foo $foo) + (data (i32.const 1024) "hello, this is some data!\00\00\00\00\00\00\00") + (func $foo (type $0) + (drop + (i32.add + (i32.const 8) + (i32.const 0) + ) + ) + (drop + (i32.add + (i32.const 1024) + (i32.const 0) + ) + ) + ) +) diff --git a/test/merge/main-lacks-segments.wast.combined.finalized.opt b/test/merge/main-lacks-segments.wast.combined.finalized.opt new file mode 100644 index 000000000..0aeb4c62d --- /dev/null +++ b/test/merge/main-lacks-segments.wast.combined.finalized.opt @@ -0,0 +1,10 @@ +(module + (type $0 (func)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 10 anyfunc)) + (elem (i32.const 8) $foo $foo) + (data (i32.const 1024) "hello, this is some data!") + (func $foo (type $0) + (nop) + ) +) diff --git a/test/merge/main-lacks-segments.wast.combined.finalized.opt.stdout b/test/merge/main-lacks-segments.wast.combined.finalized.opt.stdout new file mode 100644 index 000000000..5e72852f9 --- /dev/null +++ b/test/merge/main-lacks-segments.wast.combined.finalized.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 32 +merged total table size: 2 +merged functions: 1 diff --git a/test/merge/main-lacks-segments.wast.combined.finalized.stdout b/test/merge/main-lacks-segments.wast.combined.finalized.stdout new file mode 100644 index 000000000..5e72852f9 --- /dev/null +++ b/test/merge/main-lacks-segments.wast.combined.finalized.stdout @@ -0,0 +1,3 @@ +merged total memory size: 32 +merged total table size: 2 +merged functions: 1 diff --git a/test/merge/main-lacks-segments.wast.combined.opt b/test/merge/main-lacks-segments.wast.combined.opt new file mode 100644 index 000000000..4ea294a8e --- /dev/null +++ b/test/merge/main-lacks-segments.wast.combined.opt @@ -0,0 +1,19 @@ +(module + (type $0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 2 anyfunc)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (elem (get_global $tableBase) $foo $foo) + (data (get_global $memoryBase) "hello, this is some data!") + (func $foo (type $0) + (drop + (get_global $tableBase$0) + ) + (drop + (get_global $memoryBase$0) + ) + ) +) diff --git a/test/merge/main-lacks-segments.wast.combined.opt.stdout b/test/merge/main-lacks-segments.wast.combined.opt.stdout new file mode 100644 index 000000000..5e72852f9 --- /dev/null +++ b/test/merge/main-lacks-segments.wast.combined.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 32 +merged total table size: 2 +merged functions: 1 diff --git a/test/merge/main-lacks-segments.wast.combined.stdout b/test/merge/main-lacks-segments.wast.combined.stdout new file mode 100644 index 000000000..5e72852f9 --- /dev/null +++ b/test/merge/main-lacks-segments.wast.combined.stdout @@ -0,0 +1,3 @@ +merged total memory size: 32 +merged total table size: 2 +merged functions: 1 diff --git a/test/merge/main-lacks-segments.wast.toMerge b/test/merge/main-lacks-segments.wast.toMerge new file mode 100644 index 000000000..63c2c3a3a --- /dev/null +++ b/test/merge/main-lacks-segments.wast.toMerge @@ -0,0 +1,13 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (elem (get_global $tableBase) $foo) + (data (get_global $memoryBase) "hello, this is some data!") + (func $foo + (drop (get_global $tableBase)) + (drop (get_global $memoryBase)) + ) +) + diff --git a/test/merge/post-instantiate-a.wast b/test/merge/post-instantiate-a.wast new file mode 100644 index 000000000..5099df574 --- /dev/null +++ b/test/merge/post-instantiate-a.wast @@ -0,0 +1,9 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (export "__post_instantiate" (func $0)) + (func $0 + (drop (i32.const 1000)) + ) +) + diff --git a/test/merge/post-instantiate-a.wast.combined b/test/merge/post-instantiate-a.wast.combined new file mode 100644 index 000000000..725e1df28 --- /dev/null +++ b/test/merge/post-instantiate-a.wast.combined @@ -0,0 +1,19 @@ +(module + (type $0 (func)) + (type $0$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (memory $0 0) + (data (get_global $memoryBase) "") + (export "__post_instantiate" (func $0)) + (func $0 (type $0) + (drop + (i32.const 1000) + ) + ) + (func $0$0 (type $0$0) + (nop) + ) +) diff --git a/test/merge/post-instantiate-a.wast.combined.finalized b/test/merge/post-instantiate-a.wast.combined.finalized new file mode 100644 index 000000000..e50f84e79 --- /dev/null +++ b/test/merge/post-instantiate-a.wast.combined.finalized @@ -0,0 +1,19 @@ +(module + (type $0 (func)) + (type $0$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (memory $0 1) + (data (i32.const 1024) "") + (export "__post_instantiate" (func $0)) + (func $0 (type $0) + (drop + (i32.const 1000) + ) + ) + (func $0$0 (type $0$0) + (nop) + ) +) diff --git a/test/merge/post-instantiate-a.wast.combined.finalized.opt b/test/merge/post-instantiate-a.wast.combined.finalized.opt new file mode 100644 index 000000000..2fc7dbdb3 --- /dev/null +++ b/test/merge/post-instantiate-a.wast.combined.finalized.opt @@ -0,0 +1,10 @@ +(module + (type $0 (func)) + (type $0$0 (func)) + (memory $0 1) + (data (i32.const 1024) "") + (export "__post_instantiate" (func $0)) + (func $0 (type $0) + (nop) + ) +) diff --git a/test/merge/post-instantiate-a.wast.combined.finalized.opt.stdout b/test/merge/post-instantiate-a.wast.combined.finalized.opt.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/post-instantiate-a.wast.combined.finalized.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/post-instantiate-a.wast.combined.finalized.stdout b/test/merge/post-instantiate-a.wast.combined.finalized.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/post-instantiate-a.wast.combined.finalized.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/post-instantiate-a.wast.combined.opt b/test/merge/post-instantiate-a.wast.combined.opt new file mode 100644 index 000000000..8f190f187 --- /dev/null +++ b/test/merge/post-instantiate-a.wast.combined.opt @@ -0,0 +1,12 @@ +(module + (type $0 (func)) + (type $0$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (memory $0 0) + (data (get_global $memoryBase) "") + (export "__post_instantiate" (func $0)) + (func $0 (type $0) + (nop) + ) +) diff --git a/test/merge/post-instantiate-a.wast.combined.opt.stdout b/test/merge/post-instantiate-a.wast.combined.opt.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/post-instantiate-a.wast.combined.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/post-instantiate-a.wast.combined.stdout b/test/merge/post-instantiate-a.wast.combined.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/post-instantiate-a.wast.combined.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/post-instantiate-a.wast.toMerge b/test/merge/post-instantiate-a.wast.toMerge new file mode 100644 index 000000000..3b62ceb9e --- /dev/null +++ b/test/merge/post-instantiate-a.wast.toMerge @@ -0,0 +1,6 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (func $0) +) + diff --git a/test/merge/post-instantiate-b.wast b/test/merge/post-instantiate-b.wast new file mode 100644 index 000000000..3b62ceb9e --- /dev/null +++ b/test/merge/post-instantiate-b.wast @@ -0,0 +1,6 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (func $0) +) + diff --git a/test/merge/post-instantiate-b.wast.combined b/test/merge/post-instantiate-b.wast.combined new file mode 100644 index 000000000..df4bfe76d --- /dev/null +++ b/test/merge/post-instantiate-b.wast.combined @@ -0,0 +1,19 @@ +(module + (type $0 (func)) + (type $0$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (memory $0 0) + (data (get_global $memoryBase) "") + (export "__post_instantiate" (func $0$0)) + (func $0 (type $0) + (nop) + ) + (func $0$0 (type $0$0) + (drop + (i32.const 2000) + ) + ) +) diff --git a/test/merge/post-instantiate-b.wast.combined.finalized b/test/merge/post-instantiate-b.wast.combined.finalized new file mode 100644 index 000000000..a6f2d309b --- /dev/null +++ b/test/merge/post-instantiate-b.wast.combined.finalized @@ -0,0 +1,19 @@ +(module + (type $0 (func)) + (type $0$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (memory $0 1) + (data (i32.const 1024) "") + (export "__post_instantiate" (func $0$0)) + (func $0 (type $0) + (nop) + ) + (func $0$0 (type $0$0) + (drop + (i32.const 2000) + ) + ) +) diff --git a/test/merge/post-instantiate-b.wast.combined.finalized.opt b/test/merge/post-instantiate-b.wast.combined.finalized.opt new file mode 100644 index 000000000..f335f08d9 --- /dev/null +++ b/test/merge/post-instantiate-b.wast.combined.finalized.opt @@ -0,0 +1,10 @@ +(module + (type $0 (func)) + (type $0$0 (func)) + (memory $0 1) + (data (i32.const 1024) "") + (export "__post_instantiate" (func $0$0)) + (func $0$0 (type $0$0) + (nop) + ) +) diff --git a/test/merge/post-instantiate-b.wast.combined.finalized.opt.stdout b/test/merge/post-instantiate-b.wast.combined.finalized.opt.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/post-instantiate-b.wast.combined.finalized.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/post-instantiate-b.wast.combined.finalized.stdout b/test/merge/post-instantiate-b.wast.combined.finalized.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/post-instantiate-b.wast.combined.finalized.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/post-instantiate-b.wast.combined.opt b/test/merge/post-instantiate-b.wast.combined.opt new file mode 100644 index 000000000..1a85ff79d --- /dev/null +++ b/test/merge/post-instantiate-b.wast.combined.opt @@ -0,0 +1,12 @@ +(module + (type $0 (func)) + (type $0$0 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (memory $0 0) + (data (get_global $memoryBase) "") + (export "__post_instantiate" (func $0$0)) + (func $0$0 (type $0$0) + (nop) + ) +) diff --git a/test/merge/post-instantiate-b.wast.combined.opt.stdout b/test/merge/post-instantiate-b.wast.combined.opt.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/post-instantiate-b.wast.combined.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/post-instantiate-b.wast.combined.stdout b/test/merge/post-instantiate-b.wast.combined.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/post-instantiate-b.wast.combined.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/post-instantiate-b.wast.toMerge b/test/merge/post-instantiate-b.wast.toMerge new file mode 100644 index 000000000..0b3678389 --- /dev/null +++ b/test/merge/post-instantiate-b.wast.toMerge @@ -0,0 +1,9 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (export "__post_instantiate" (func $0)) + (func $0 + (drop (i32.const 2000)) + ) +) + diff --git a/test/merge/printf.wast b/test/merge/printf.wast new file mode 100644 index 000000000..c984602bf --- /dev/null +++ b/test/merge/printf.wast @@ -0,0 +1,13 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "globally" (global $i-collide i32)) + (import "env" "foobar" (func $import$8 (param i32 i32) (result i32))) + (export "_printf" (func $625)) + (func $625 (param $var$0 i32) (param $var$1 i32) (result i32) + (i32.const 102030) + ) +) + diff --git a/test/merge/printf.wast.combined b/test/merge/printf.wast.combined new file mode 100644 index 000000000..f8dcc3d0c --- /dev/null +++ b/test/merge/printf.wast.combined @@ -0,0 +1,28 @@ +(module + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$iii$0 (func (param i32 i32) (result i32))) + (type $1 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "globally" (global $i-collide i32)) + (import "env" "foobar" (func $import$8 (param i32 i32) (result i32))) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (import "env" "globally" (global $i-collide$0 f64)) + + (data (get_global $memoryBase) "") + (export "_printf" (func $625)) + (func $625 (type $FUNCSIG$iii) (param $var$0 i32) (param $var$1 i32) (result i32) + (i32.const 102030) + ) + (func $b (type $1) + (drop + (call $625 + (i32.const 11) + (i32.const 22) + ) + ) + ) +) diff --git a/test/merge/printf.wast.combined.finalized b/test/merge/printf.wast.combined.finalized new file mode 100644 index 000000000..c72f0d28f --- /dev/null +++ b/test/merge/printf.wast.combined.finalized @@ -0,0 +1,28 @@ +(module + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$iii$0 (func (param i32 i32) (result i32))) + (type $1 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 8 anyfunc)) + (import "env" "globally" (global $i-collide i32)) + (import "env" "foobar" (func $import$8 (param i32 i32) (result i32))) + (import "env" "memoryBase" (global $memoryBase$0 i32)) + (import "env" "tableBase" (global $tableBase$0 i32)) + (import "env" "globally" (global $i-collide$0 f64)) + + (data (i32.const 1024) "") + (export "_printf" (func $625)) + (func $625 (type $FUNCSIG$iii) (param $var$0 i32) (param $var$1 i32) (result i32) + (i32.const 102030) + ) + (func $b (type $1) + (drop + (call $625 + (i32.const 11) + (i32.const 22) + ) + ) + ) +) diff --git a/test/merge/printf.wast.combined.finalized.opt b/test/merge/printf.wast.combined.finalized.opt new file mode 100644 index 000000000..92e17f720 --- /dev/null +++ b/test/merge/printf.wast.combined.finalized.opt @@ -0,0 +1,12 @@ +(module + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$iii$0 (func (param i32 i32) (result i32))) + (type $1 (func)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 8 anyfunc)) + + (export "_printf" (func $625)) + (func $625 (type $FUNCSIG$iii) (param $var$0 i32) (param $var$1 i32) (result i32) + (i32.const 102030) + ) +) diff --git a/test/merge/printf.wast.combined.finalized.opt.stdout b/test/merge/printf.wast.combined.finalized.opt.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/printf.wast.combined.finalized.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/printf.wast.combined.finalized.stdout b/test/merge/printf.wast.combined.finalized.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/printf.wast.combined.finalized.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/printf.wast.combined.opt b/test/merge/printf.wast.combined.opt new file mode 100644 index 000000000..e01710fd1 --- /dev/null +++ b/test/merge/printf.wast.combined.opt @@ -0,0 +1,15 @@ +(module + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$iii$0 (func (param i32 i32) (result i32))) + (type $1 (func)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + + (data (get_global $memoryBase) "") + (export "_printf" (func $625)) + (func $625 (type $FUNCSIG$iii) (param $var$0 i32) (param $var$1 i32) (result i32) + (i32.const 102030) + ) +) diff --git a/test/merge/printf.wast.combined.opt.stdout b/test/merge/printf.wast.combined.opt.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/printf.wast.combined.opt.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/printf.wast.combined.stdout b/test/merge/printf.wast.combined.stdout new file mode 100644 index 000000000..3816869a7 --- /dev/null +++ b/test/merge/printf.wast.combined.stdout @@ -0,0 +1,3 @@ +merged total memory size: 0 +merged total table size: 0 +merged functions: 2 diff --git a/test/merge/printf.wast.toMerge b/test/merge/printf.wast.toMerge new file mode 100644 index 000000000..d394abe34 --- /dev/null +++ b/test/merge/printf.wast.toMerge @@ -0,0 +1,14 @@ +(module + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (import "env" "memory" (memory $0 256)) + (import "env" "table" (table 0 anyfunc)) + (import "env" "globally" (global $i-collide f64)) + (import "env" "_printf" (func $import$8 (param i32 i32) (result i32))) + (func $b + (drop + (call $import$8 (i32.const 11) (i32.const 22)) + ) + ) +) + |