diff --git a/src/asm2wasm.h b/src/asm2wasm.h index c0f13ff8f3c..123741645d1 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -660,11 +660,11 @@ void Asm2WasmBuilder::processAsm(Ref ast) { // TODO: when not using aliasing function pointers, we could merge them by noticing that // index 0 in each table is the null func, and each other index should only have one // non-null func. However, that breaks down when function pointer casts are emulated. - functionTableStarts[name] = wasm.table.names.size(); // this table starts here + functionTableStarts[name] = wasm.getDefaultTable()->values.size(); // this table starts here Ref contents = value[1]; for (unsigned k = 0; k < contents->size(); k++) { IString curr = contents[k][1]->getIString(); - wasm.table.names.push_back(curr); + wasm.getDefaultTable()->values.push_back(curr); } } else { abort_on("invalid var element", pair); @@ -1404,6 +1404,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { } // function pointers auto ret = allocator.alloc(); + ret->table = wasm.getDefaultTable()->name; Ref target = ast[1]; assert(target[0] == SUB && target[1][0] == NAME && target[2][0] == BINARY && target[2][1] == AND && target[2][3][0] == NUM); // FUNCTION_TABLE[(expr) & mask] ret->target = process(target[2]); // TODO: as an optimization, we could look through the mask diff --git a/src/ast_utils.h b/src/ast_utils.h index 3e45d0e3395..a57e07e8e49 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -267,7 +267,7 @@ struct ExpressionManipulator { return ret; } Expression* visitCallIndirect(CallIndirect *curr) { - auto* ret = builder.makeCallIndirect(curr->fullType, curr->target, {}, curr->type); + auto* ret = builder.makeCallIndirect(curr->table, curr->fullType, curr->target, {}, curr->type); for (Index i = 0; i < curr->operands.size(); i++) { ret->operands.push_back(copy(curr->operands[i])); } @@ -467,6 +467,7 @@ struct ExpressionAnalyzer { break; } case Expression::Id::CallIndirectId: { + CHECK(CallIndirect, table); PUSH(CallIndirect, target); CHECK(CallIndirect, fullType); CHECK(CallIndirect, operands.size()); @@ -678,6 +679,7 @@ struct ExpressionAnalyzer { break; } case Expression::Id::CallIndirectId: { + HASH_NAME(CallIndirect, table); PUSH(CallIndirect, target); HASH_NAME(CallIndirect, fullType); HASH(CallIndirect, operands.size()); diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index b7fc4347a2c..8a1b35d3f26 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -586,7 +586,7 @@ BinaryenExpressionRef BinaryenSelect(BinaryenModuleRef module, BinaryenExpressio } BinaryenExpressionRef BinaryenReturn(BinaryenModuleRef module, BinaryenExpressionRef value) { auto* ret = Builder(*((Module*)module)).makeReturn((Expression*)value); - + if (tracing) { auto id = noteExpression(ret); std::cout << " expressions[" << id << "] = BinaryenReturn(the_module, expressions[" << expressions[value] << "]);\n"; @@ -730,7 +730,7 @@ void BinaryenSetFunctionTable(BinaryenModuleRef module, BinaryenFunctionRef* fun auto* wasm = (Module*)module; for (BinaryenIndex i = 0; i < numFuncs; i++) { - wasm->table.names.push_back(((Function*)funcs[i])->name); + wasm->getDefaultTable()->values.push_back(((Function*)funcs[i])->name); } } diff --git a/src/js/wasm.js-post.js b/src/js/wasm.js-post.js index ae42ef17596..10eb69739c3 100644 --- a/src/js/wasm.js-post.js +++ b/src/js/wasm.js-post.js @@ -301,8 +301,6 @@ function integrateWasmJS(Module) { for (var i = 0; i < methods.length; i++) { var curr = methods[i]; - Module['printErr']('trying binaryen method: ' + curr); - if (curr === 'native-wasm') { if (exports = doNativeWasm(global, env, providedBuffer)) break; } else if (curr === 'asmjs') { @@ -316,8 +314,6 @@ function integrateWasmJS(Module) { if (!exports) throw 'no binaryen method succeeded'; - Module['printErr']('binaryen method succeeded.'); - return exports; }; diff --git a/src/passes/DuplicateFunctionElimination.cpp b/src/passes/DuplicateFunctionElimination.cpp index 961d26ba5a3..af5b133cffb 100644 --- a/src/passes/DuplicateFunctionElimination.cpp +++ b/src/passes/DuplicateFunctionElimination.cpp @@ -123,10 +123,12 @@ struct DuplicateFunctionElimination : public Pass { replacerRunner.add(&replacements); replacerRunner.run(); // replace in table - for (auto& name : module->table.names) { - auto iter = replacements.find(name); - if (iter != replacements.end()) { - name = iter->second; + for (auto& curr : module->tables) { + for (auto& name : curr->values) { + auto iter = replacements.find(name); + if (iter != replacements.end()) { + name = iter->second; + } } } // replace in start diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 47e503fa4c4..ccf1b49950d 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -227,7 +227,9 @@ struct PrintSExpression : public Visitor { printCallBody(curr); } void visitCallIndirect(CallIndirect *curr) { - printOpening(o, "call_indirect ") << curr->fullType; + printOpening(o, "call_indirect "); + printName(curr->table); + o << ' ' << curr->fullType; incIndent(); printFullLine(curr->target); for (auto operand : curr->operands) { @@ -575,8 +577,12 @@ struct PrintSExpression : public Visitor { decIndent(); } void visitTable(Table *curr) { - printOpening(o, "table"); - for (auto name : curr->names) { + printOpening(o, "table "); + printName(curr->name) << ' '; + if (curr->isDefault) + o << "default" << ' '; + visitFunctionType(curr->elementType, true); + for (auto name : curr->values) { o << ' '; printName(name); } @@ -647,9 +653,9 @@ struct PrintSExpression : public Visitor { visitGlobal(child.get()); o << maybeNewLine; } - if (curr->table.names.size() > 0) { + for (auto& child : curr->tables) { doIndent(o, indent); - visitTable(&curr->table); + visitTable(child.get()); o << maybeNewLine; } for (auto& child : curr->functions) { diff --git a/src/passes/RemoveUnusedFunctions.cpp b/src/passes/RemoveUnusedFunctions.cpp index a2941aff662..e73b6f897d5 100644 --- a/src/passes/RemoveUnusedFunctions.cpp +++ b/src/passes/RemoveUnusedFunctions.cpp @@ -39,8 +39,10 @@ struct RemoveUnusedFunctions : public Pass { root.push_back(module->getFunction(curr->value)); } // For now, all functions that can be called indirectly are marked as roots. - for (auto& curr : module->table.names) { - root.push_back(module->getFunction(curr)); + for (auto& child : module->tables) { + for (auto& curr : child->values) { + root.push_back(module->getFunction(curr)); + } } // Compute function reachability starting from the root set. DirectCallGraphAnalyzer analyzer(module, root); diff --git a/src/passes/ReorderFunctions.cpp b/src/passes/ReorderFunctions.cpp index 38ef98afb7a..c4aeae9bd71 100644 --- a/src/passes/ReorderFunctions.cpp +++ b/src/passes/ReorderFunctions.cpp @@ -38,8 +38,10 @@ struct ReorderFunctions : public WalkerPassexports) { counts[curr->value]++; } - for (auto& curr : module->table.names) { - counts[curr]++; + for (auto& child : module->tables) { + for (auto& curr : child->values) { + counts[curr]++; + } } std::sort(module->functions.begin(), module->functions.end(), [this]( const std::unique_ptr& a, diff --git a/src/s2wasm.h b/src/s2wasm.h index b17ed070217..beee6f28c13 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -318,6 +318,11 @@ class S2WasmBuilder { return cashew::IString(str.c_str(), false); } + uint32_t getTable() { + if (!match(".")) return 0; + return getInt(); + } + std::vector getQuoted() { assert(*s == '"'); s++; @@ -863,6 +868,7 @@ class S2WasmBuilder { auto makeCall = [&](WasmType type) { if (match("_indirect")) { // indirect call + uint32_t table = getTable(); Name assign = getAssign(); int num = getNumInputs(); auto inputs = getInputs(num); @@ -871,7 +877,7 @@ class S2WasmBuilder { std::vector operands(++input, inputs.end()); auto* funcType = ensureFunctionType(getSig(type, operands), wasm); assert(type == funcType->result); - auto* indirect = builder.makeCallIndirect(funcType, target, std::move(operands)); + auto* indirect = builder.makeCallIndirect(linkerObj->getIndirectTable(table, funcType)->name, funcType, target, std::move(operands)); setOutput(indirect, assign); } else { // non-indirect call diff --git a/src/wasm-binary.h b/src/wasm-binary.h index aad142d4459..0c660d162aa 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -480,7 +480,7 @@ class WasmBinaryWriter : public Visitor { writeSignatures(); writeImports(); writeFunctionSignatures(); - writeFunctionTable(); + writeFunctionTables(); writeMemory(); writeGlobals(); writeExports(); @@ -556,7 +556,7 @@ class WasmBinaryWriter : public Visitor { finishSection(start); } - int32_t getFunctionTypeIndex(Name type) { + Index getFunctionTypeIndex(Name type) { // TODO: optimize for (size_t i = 0; i < wasm->functionTypes.size(); i++) { if (wasm->functionTypes[i]->name == type) return i; @@ -564,6 +564,14 @@ class WasmBinaryWriter : public Visitor { abort(); } + Index getFunctionTableIndex(Name type) { + // TODO: optimize + for (size_t i = 0; i < wasm->tables.size(); i++) { + if (wasm->tables[i]->name == type) return i; + } + abort(); + } + void writeImports() { if (wasm->imports.size() == 0) return; if (debug) std::cerr << "== writeImports" << std::endl; @@ -685,7 +693,7 @@ class WasmBinaryWriter : public Visitor { void writeExports() { if (wasm->exports.size() == 0) return; - if (debug) std::cerr << "== writeexports" << std::endl; + if (debug) std::cerr << "== writeExports" << std::endl; auto start = startSection(BinaryConsts::Section::ExportTable); o << U32LEB(wasm->exports.size()); for (auto& curr : wasm->exports) { @@ -724,8 +732,8 @@ class WasmBinaryWriter : public Visitor { assert(mappedImports.count(name)); return mappedImports[name]; } - - std::map mappedFunctions; // name of the Function => index + + std::map mappedFunctions; // name of the Function => entry index uint32_t getFunctionIndex(Name name) { if (!mappedFunctions.size()) { // Create name => index mapping. @@ -738,13 +746,21 @@ class WasmBinaryWriter : public Visitor { return mappedFunctions[name]; } - void writeFunctionTable() { - if (wasm->table.names.size() == 0) return; - if (debug) std::cerr << "== writeFunctionTable" << std::endl; + void writeFunctionTables() { + if (wasm->tables.size() == 0) return; + if (debug) std::cerr << "== writeFunctionTables" << std::endl; auto start = startSection(BinaryConsts::Section::FunctionTable); - o << U32LEB(wasm->table.names.size()); - for (auto name : wasm->table.names) { - o << U32LEB(getFunctionIndex(name)); + o << U32LEB(wasm->tables.size()); + for (auto& curr : wasm->tables) { + if (debug) std::cerr << "write one" << std::endl; + o << int8_t(curr->isDefault); + o << U32LEB(getFunctionTypeIndex(curr->elementType->name)); + assert(curr->initial == curr->values.size() && curr->initial == curr->max); + o << U32LEB(curr->initial); + o << U32LEB(curr->max); + for (auto name : curr->values) { + o << U32LEB(getFunctionIndex(name)); + } } finishSection(start); } @@ -924,7 +940,7 @@ class WasmBinaryWriter : public Visitor { for (auto* operand : curr->operands) { recurse(operand); } - o << int8_t(BinaryConsts::CallIndirect) << U32LEB(curr->operands.size()) << U32LEB(getFunctionTypeIndex(curr->fullType)); + o << int8_t(BinaryConsts::CallIndirect) << U32LEB(curr->operands.size()) << U32LEB(getFunctionTypeIndex(curr->fullType)) << U32LEB(getFunctionTableIndex(curr->table)); } void visitGetLocal(GetLocal *curr) { if (debug) std::cerr << "zz node: GetLocal " << (o.size() + 1) << std::endl; @@ -1256,7 +1272,7 @@ class WasmBinaryBuilder { else if (match(BinaryConsts::Section::ExportTable)) readExports(); else if (match(BinaryConsts::Section::Globals)) readGlobals(); else if (match(BinaryConsts::Section::DataSegments)) readDataSegments(); - else if (match(BinaryConsts::Section::FunctionTable)) readFunctionTable(); + else if (match(BinaryConsts::Section::FunctionTable)) readFunctionTables(); else if (match(BinaryConsts::Section::Names)) readNames(); else { std::cerr << "unfamiliar section: "; @@ -1452,6 +1468,11 @@ class WasmBinaryBuilder { assert(numResults == 1); curr->result = getWasmType(); } + // TODO: Handle "anyfunc" properly. This sets the name to "anyfunc" if + // it does not already exist, and matches the expected type signature. + if (!wasm.checkFunctionType(FunctionType::kAnyFunc) && FunctionType::isAnyFuncType(curr)) { + curr->name = FunctionType::kAnyFunc; + } wasm.addFunctionType(curr); } } @@ -1466,7 +1487,7 @@ class WasmBinaryBuilder { curr->name = Name(std::string("import$") + std::to_string(i)); auto index = getU32LEB(); assert(index < wasm.functionTypes.size()); - curr->type = wasm.getFunctionType(index); + curr->type = wasm.functionTypes[index].get(); assert(curr->type->name.is()); curr->module = getInlineString(); curr->base = getInlineString(); @@ -1638,9 +1659,12 @@ class WasmBinaryBuilder { } } - for (size_t index : functionTable) { - assert(index < wasm.functions.size()); - wasm.table.names.push_back(wasm.functions[index]->name); + for (auto& pair : functionTable) { + assert(pair.first < wasm.tables.size()); + assert(pair.second < wasm.functions.size()); + assert(wasm.tables[pair.first]->values.size() <= wasm.tables[pair.first]->max); + assert(wasm.tables[pair.first]->elementType->name == FunctionType::kAnyFunc || wasm.tables[pair.first]->elementType == wasm.getFunctionType(wasm.functions[pair.second]->type)); + wasm.tables[pair.first]->values.push_back(wasm.functions[pair.second]->name); } } @@ -1660,14 +1684,28 @@ class WasmBinaryBuilder { } } - std::vector functionTable; + std::vector> functionTable; - void readFunctionTable() { - if (debug) std::cerr << "== readFunctionTable" << std::endl; - auto num = getU32LEB(); - for (size_t i = 0; i < num; i++) { + void readFunctionTables() { + if (debug) std::cerr << "== readFunctionTables" << std::endl; + size_t numTables = getU32LEB(); + for (size_t i = 0; i < numTables; i++) { + if (debug) std::cerr << "read one" << std::endl; + auto curr = new Table; + auto flag = getInt8(); + assert((!i && flag) || (i && !flag)); + curr->isDefault = flag; auto index = getU32LEB(); - functionTable.push_back(index); + assert(index < functionTypes.size()); + curr->elementType = wasm.getFunctionType(index); + curr->initial = getU32LEB(); + curr->max = getU32LEB(); + assert(curr->initial == curr->max); + for (size_t j = 0; j < curr->initial; j++) { + auto index = getU32LEB(); + functionTable.push_back(std::make_pair<>(i, index)); + } + wasm.addTable(curr); } } @@ -1887,6 +1925,7 @@ class WasmBinaryBuilder { curr->fullType = fullType->name; auto num = fullType->params.size(); assert(num == arity); + curr->table = wasm.getTable(getU32LEB())->name; curr->operands.resize(num); for (size_t i = 0; i < num; i++) { curr->operands[num - i - 1] = popExpression(); diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 22e1f9a007f..fa6c9c58b50 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -115,16 +115,18 @@ class Builder { call->operands.set(args); return call; } - CallIndirect* makeCallIndirect(FunctionType* type, Expression* target, const std::vector& args) { + CallIndirect* makeCallIndirect(Name table, FunctionType* type, Expression* target, const std::vector& args) { auto* call = allocator.alloc(); + call->table = table; call->fullType = type->name; call->type = type->result; call->target = target; call->operands.set(args); return call; } - CallIndirect* makeCallIndirect(Name fullType, Expression* target, const std::vector& args, WasmType type) { + CallIndirect* makeCallIndirect(Name table, Name fullType, Expression* target, const std::vector& args, WasmType type) { auto* call = allocator.alloc(); + call->table = table; call->fullType = fullType; call->type = type; call->target = target; diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index adaee0b6fca..bfe02d8647c 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -666,11 +666,12 @@ class ModuleInstance { LiteralList arguments; Flow flow = generateArguments(curr->operands, arguments); if (flow.breaking()) return flow; + Table *table = instance.wasm.getTable(curr->table); + if (table->elementType->name != FunctionType::kAnyFunc && table->elementType->name != curr->fullType) trap("callIndirect: bad type"); size_t index = target.value.geti32(); - if (index >= instance.wasm.table.names.size()) trap("callIndirect: overflow"); - Name name = instance.wasm.table.names[index]; + if (index >= table->values.size()) trap("callIndirect: overflow"); + Name name = table->values[index]; Function *func = instance.wasm.getFunction(name); - if (func->type.is() && func->type != curr->fullType) trap("callIndirect: bad type"); if (func->params.size() != arguments.size()) trap("callIndirect: bad # of arguments"); for (size_t i = 0; i < func->params.size(); i++) { if (func->params[i] != arguments[i].type) { diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp index 45615fd59c1..cb36f5b261e 100644 --- a/src/wasm-linker.cpp +++ b/src/wasm-linker.cpp @@ -112,27 +112,30 @@ void Linker::layout() { for (Name name : out.globls) exportFunction(name, false); for (Name name : out.initializerFunctions) exportFunction(name, true); - // Pad the indirect function table with a dummy function - makeDummyFunction(); - // Pre-assign the function indexes - for (auto& pair : out.indirectIndexes) { - if (functionIndexes.count(pair.first) != 0 || - functionNames.count(pair.second) != 0) { - Fatal() << "Function " << pair.first << " already has an index " << - functionIndexes[pair.first] << " while setting index " << pair.second; - } - if (debug) { - std::cerr << "pre-assigned function index: " << pair.first << ": " - << pair.second << '\n'; + for (auto &pair : out.indirectIndexes) { + Index tableIndex = pair.first; + for (auto &funcName : pair.second) { + Function *func = out.wasm.getFunction(funcName); + FunctionType *funcType = ensureFunctionType(getSig(func), &out.wasm); + func->type = funcType->name; + Table *table = out.getIndirectTable(tableIndex, funcType); + if (table->values.empty()) { + Name dummy = makeDummyFunction(table); + functionIndexes[dummy] = std::make_pair(tableIndex, table->values.size()); + table->values.push_back(dummy); + } + if (functionIndexes.count(funcName) != 0) { + Fatal() << "Function " << funcName << " already has an index " << + functionIndexes[funcName].first << " while setting index " << pair.first; + } + if (debug) { + std::cerr << "pre-assigned function index: " << funcName << ": " + << pair.first << '\n'; + } + functionIndexes[funcName] = std::make_pair(tableIndex, table->values.size()); + table->values.push_back(funcName); } - functionIndexes[pair.first] = pair.second; - functionNames[pair.second] = pair.first; - } - - // Emit the pre-assigned function names in sorted order - for (const auto& P : functionNames) { - out.wasm.table.names.push_back(P.second); } for (auto& relocation : out.relocations) { @@ -170,6 +173,7 @@ void Linker::layout() { } } } + if (!!startFunction) { if (out.symbolInfo.implementedFunctions.count(startFunction) == 0) { Fatal() << "Unknown start function: `" << startFunction << "`\n"; @@ -205,10 +209,34 @@ void Linker::layout() { } } - // ensure an explicit function type for indirect call targets - for (auto& name : out.wasm.table.names) { - auto* func = out.wasm.getFunction(name); - func->type = ensureFunctionType(getSig(func), &out.wasm)->name; + // Create the default table if necessary + if (!out.tables.count(Table::kDefault)) { + bool create = out.tables.size(); + // Check if there are address-taken functions or non-default tables + for (auto& relocation : out.relocations) { + if (create || relocation->kind == LinkerObject::Relocation::kFunction) { + create = true; + break; + } + } + + if (create) { + Index tableIndex = Table::kDefault; + Table *table = out.getIndirectTable(tableIndex, NULL); + if (table->values.empty()) { + Name dummy = makeDummyFunction(table); + functionIndexes[dummy] = std::make_pair(tableIndex, table->values.size()); + table->values.push_back(dummy); + } + } + } + + // Create the actual tables in the underlying module. This is delayed because + // table references may be out of order, and the underlying object is a vector. + Index counter = 0; + for (auto& pair : out.tables) { + if (pair.first != counter++) Fatal() << "Tables are nonconsecutive!" << '\n'; + out.wasm.addTable(pair.second); } } @@ -371,14 +399,25 @@ void Linker::emscriptenGlue(std::ostream& o) { Index Linker::getFunctionIndex(Name name) { if (!functionIndexes.count(name)) { - functionIndexes[name] = out.wasm.table.names.size(); - out.wasm.table.names.push_back(name); + Function *func = out.wasm.getFunction(name); + FunctionType *funcType = ensureFunctionType(getSig(func), &out.wasm); + func->type = funcType->name; + Index tableIndex = Table::kDefault; + Table *table = out.getIndirectTable(tableIndex, funcType); + if (table->values.empty()) { + Name dummy = makeDummyFunction(table); + functionIndexes[dummy] = std::make_pair(tableIndex, table->values.size()); + table->values.push_back(dummy); + } + functionIndexes[name] = std::make_pair(tableIndex, table->values.size()); + table->values.push_back(name); if (debug) { std::cerr << "function index: " << name << ": " - << functionIndexes[name] << '\n'; + << functionIndexes[name].first << " " + << functionIndexes[name].second << '\n'; } } - return functionIndexes[name]; + return functionIndexes[name].second; } bool hasI64ResultOrParam(FunctionType* ft) { @@ -389,48 +428,50 @@ bool hasI64ResultOrParam(FunctionType* ft) { return false; } -void Linker::makeDummyFunction() { - assert(out.wasm.table.names.empty()); - bool create = false; - // Check if there are address-taken functions - for (auto& relocation : out.relocations) { - if (relocation->kind == LinkerObject::Relocation::kFunction) { - create = true; - break; +Name Linker::makeDummyFunction(Table *table) { + assert(table->values.empty()); + Name functionName = std::string(dummyFunction) + std::string(table->name.c_str()); + if (!out.wasm.checkFunction(functionName)) { + wasm::Builder wasmBuilder(out.wasm); + Expression *unreachable = wasmBuilder.makeUnreachable(); + Function *dummy = wasmBuilder.makeFunction(functionName, {}, table->elementType->result, {}, unreachable); + if (FunctionType::isAnyFuncType(table->elementType)) { + std::string sig = getSig(dummy); + dummy->type = ensureFunctionType(sig, &out.wasm)->name; + } else { + dummy->type = table->elementType->name; } + out.wasm.addFunction(dummy); } - if (!create) return; - wasm::Builder wasmBuilder(out.wasm); - Expression *unreachable = wasmBuilder.makeUnreachable(); - Function *dummy = wasmBuilder.makeFunction(Name(dummyFunction), {}, WasmType::none, {}, unreachable); - out.wasm.addFunction(dummy); - getFunctionIndex(dummy->name); + return functionName; } void Linker::makeDynCallThunks() { std::unordered_set sigs; wasm::Builder wasmBuilder(out.wasm); - for (const auto& indirectFunc : out.wasm.table.names) { - // Skip generating thunks for the dummy function - if (indirectFunc == dummyFunction) continue; - std::string sig(getSig(out.wasm.getFunction(indirectFunc))); - auto* funcType = ensureFunctionType(sig, &out.wasm); - if (hasI64ResultOrParam(funcType)) continue; // Can't export i64s on the web. - if (!sigs.insert(sig).second) continue; // Sig is already in the set - std::vector params; - params.emplace_back("fptr", i32); // function pointer param - int p = 0; - for (const auto& ty : funcType->params) params.emplace_back(std::to_string(p++), ty); - Function* f = wasmBuilder.makeFunction(std::string("dynCall_") + sig, std::move(params), funcType->result, {}); - Expression* fptr = wasmBuilder.makeGetLocal(0, i32); - std::vector args; - for (unsigned i = 0; i < funcType->params.size(); ++i) { - args.push_back(wasmBuilder.makeGetLocal(i + 1, funcType->params[i])); + for (const auto& table : out.wasm.tables) { + for (const auto& indirectFunc : table->values) { + // Skip generating thunks for the dummy function + if (!strncmp(indirectFunc.c_str(), dummyFunction, std::min(strlen(indirectFunc.c_str()), strlen(dummyFunction)))) continue; + std::string sig(getSig(out.wasm.getFunction(indirectFunc))); + auto* funcType = ensureFunctionType(sig, &out.wasm); + if (hasI64ResultOrParam(funcType)) continue; // Can't export i64s on the web. + if (!sigs.insert(sig).second) continue; // Sig is already in the set + std::vector params; + params.emplace_back("fptr", i32); // function pointer param + int p = 0; + for (const auto& ty : funcType->params) params.emplace_back(std::to_string(p++), ty); + Function* f = wasmBuilder.makeFunction(std::string("dynCall_") + sig, std::move(params), funcType->result, {}); + Expression* fptr = wasmBuilder.makeGetLocal(0, i32); + std::vector args; + for (unsigned i = 0; i < funcType->params.size(); ++i) { + args.push_back(wasmBuilder.makeGetLocal(i + 1, funcType->params[i])); + } + Expression* call = wasmBuilder.makeCallIndirect(table->name, funcType, fptr, args); + f->body = call; + out.wasm.addFunction(f); + exportFunction(f->name, true); } - Expression* call = wasmBuilder.makeCallIndirect(funcType, fptr, args); - f->body = call; - out.wasm.addFunction(f); - exportFunction(f->name, true); } } diff --git a/src/wasm-linker.h b/src/wasm-linker.h index 3f1e8c7aca6..5b99d3e0fb8 100644 --- a/src/wasm-linker.h +++ b/src/wasm-linker.h @@ -111,6 +111,29 @@ class LinkerObject { return nullptr; } + // Create a table locally, because insertion into the underlying wasm vector + // needs to be delayed until all tables have been encountered. + Table *getIndirectTable(Index index, FunctionType* type) { + Table *table; + if (tables.count(index)) { + return tables[index]; + } + + // Otherwise, proceed and create the requested table. + if (index != Table::kDefault) { + table = new Table(); + table->name = Name::fromInt(index); + table->isDefault = false; + table->elementType = type; + } else { + table = Table::createDefaultTable(); + table->elementType = wasm.getAnyFuncType(); + } + tables[index] = table; + + return table; + } + // Add an initializer segment for the named static variable. void addSegment(Name name, const char* data, Address size) { segments[name] = wasm.memory.segments.size(); @@ -142,8 +165,10 @@ class LinkerObject { } void addIndirectIndex(Name name, Address index) { - assert(!indirectIndexes.count(name)); - indirectIndexes[name] = index; + if (!indirectIndexes.count(index)) { + indirectIndexes[index] = std::vector(); + } + indirectIndexes[index].push_back(name); } bool isEmpty() { @@ -177,9 +202,10 @@ class LinkerObject { std::unordered_map externTypesMap; std::map segments; // name => segment index (in wasm module) + std::map tables; // index => table index (in wasm module) // preassigned indexes for functions called indirectly - std::map indirectIndexes; + std::map> indirectIndexes; std::vector initializerFunctions; @@ -253,7 +279,7 @@ class Linker { bool linkArchive(Archive& archive); // Name of the dummy function to prevent erroneous nullptr comparisons. - static constexpr const char* dummyFunction = "__wasm_nullptr"; + static constexpr const char* dummyFunction = "__wasm_nullptr_"; private: // Allocate a static variable and return its address in linear memory @@ -286,9 +312,9 @@ class Linker { // a given function. Index getFunctionIndex(Name name); - // Adds a dummy function in the indirect table at slot 0 to prevent NULL + // Adds a dummy function in the given indirect table to prevent NULL // pointer miscomparisons. - void makeDummyFunction(); + Name makeDummyFunction(Table *table); // Create thunks for use with emscripten Runtime.dynCall. Creates one for each // signature in the indirect function table. @@ -328,8 +354,7 @@ class Linker { std::unordered_map staticAddresses; // name => address std::unordered_map segmentsByAddress; // address => segment index - std::unordered_map functionIndexes; - std::map functionNames; + std::unordered_map> functionIndexes; // name => table, entry indexes }; diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 750d485fbe1..8f4357103b8 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -265,11 +265,13 @@ class SExpressionWasmBuilder { int functionCounter; int importCounter; int globalCounter; + int tableCounter; std::map functionTypes; // we need to know function return types before we parse their contents + std::map functionFullTypes; // we need to know function full types before we parse their contents for tables public: // Assumes control of and modifies the input. - SExpressionWasmBuilder(Module& wasm, Element& module) : wasm(wasm), allocator(wasm.allocator), importCounter(0), globalCounter(0) { + SExpressionWasmBuilder(Module& wasm, Element& module) : wasm(wasm), allocator(wasm.allocator), importCounter(0), globalCounter(0), tableCounter(0) { assert(module[0]->str() == MODULE); if (module.size() > 1 && module[1]->isStr()) { // these s-expressions contain a binary module, actually @@ -324,6 +326,7 @@ class SExpressionWasmBuilder { Name typeName = curr[1]->str(); if (!wasm.checkFunctionType(typeName)) throw ParseException("unknown function"); type = wasm.getFunctionType(typeName); + functionFullTypes[name] = type; functionTypes[name] = type->result; } else if (id == PARAM && curr.size() > 1) { Index j = 1; @@ -354,6 +357,7 @@ class SExpressionWasmBuilder { if (need) { wasm.addFunctionType(functionType.release()); } + functionFullTypes[name] = functionType.get(); } } @@ -1186,13 +1190,16 @@ class SExpressionWasmBuilder { Expression* makeCallIndirect(Element& s) { auto ret = allocator.alloc(); - IString type = s[1]->str(); + size_t i = 1; + ret->table = wasm.getDefaultTable()->name; + if (wasm.checkTable(s[i]->str())) ret->table = wasm.getTable(s[i++]->str())->name; + IString type = s[i++]->str(); auto* fullType = wasm.checkFunctionType(type); if (!fullType) throw ParseException("invalid call_indirect type", s.line, s.col); ret->fullType = fullType->name; ret->type = fullType->result; - ret->target = parseExpression(s[2]); - parseCallOperands(s, 3, ret); + ret->target = parseExpression(s[i++]); + parseCallOperands(s, i++, ret); return ret; } @@ -1402,9 +1409,42 @@ class SExpressionWasmBuilder { } void parseTable(Element& s) { - for (size_t i = 1; i < s.size(); i++) { - wasm.table.names.push_back(getFunctionName(*s[i])); + std::unique_ptr tab = make_unique
(); + size_t i = 1; + if (s.size() > i && s[i]->isStr()) { + tab->name = s[i++]->str(); + } else { + tab->name = Name::fromInt(tableCounter); + } + tab->isDefault = !tableCounter; + if (s.size() > i && s[i]->isStr() && s[i]->str() == "default") { + tab->isDefault = true; + i++; + } + if (tableCounter && tab->isDefault) throw ParseException("only the first table can be default"); + tableCounter++; + if (s.size() > i && s[i]->isList()) { + Element& params = *s[i++]; + IString id = params[0]->str(); + if (id == TYPE) { + IString name = params[1]->str(); + if (!wasm.checkFunctionType(name)) throw ParseException("bad function type for table"); + tab->elementType = wasm.getFunctionType(name); + } else { + throw ParseException("bad table element"); + } + } else { + tab->elementType = wasm.getAnyFuncType(); + } + while (i < s.size()) { + Name func = getFunctionName(*s[i++]); + if (!functionFullTypes.count(func)) throw ParseException("unknown function"); + if (tab->elementType->name != FunctionType::kAnyFunc && tab->elementType != functionFullTypes[func]) throw ParseException("bad element type for table"); + tab->values.push_back(func); } + tab->initial = tab->values.size(); + tab->max = tab->values.size(); + wasm.addTable(tab.release()); } void parseType(Element& s) { @@ -1420,12 +1460,13 @@ class SExpressionWasmBuilder { Element& curr = *func[i]; if (curr[0]->str() == PARAM) { for (size_t j = 1; j < curr.size(); j++) { - type->params.push_back(stringToWasmType(curr[j]->str())); + type->params.push_back(stringToWasmType(curr[j]->str(), type->name == FunctionType::kAnyFunc)); } } else if (curr[0]->str() == RESULT) { type->result = stringToWasmType(curr[1]->str()); } } + if (type->name == FunctionType::kAnyFunc && !FunctionType::isAnyFuncType(type.get())) throw ParseException("reserved type keyword"); wasm.addFunctionType(type.release()); } }; diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index b50ca0fb292..cddb5be899c 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -205,7 +205,9 @@ struct Walker : public VisitorType { for (auto& curr : module->functions) { self->walkFunction(curr.get()); } - self->visitTable(&module->table); + for (auto &curr : module->tables) { + self->visitTable(curr.get()); + } self->visitMemory(&module->memory); } diff --git a/src/wasm.h b/src/wasm.h index 38a030e1a26..8897830cd02 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1065,6 +1065,8 @@ class FunctionType { FunctionType() : result(none) {} + static constexpr const char* kAnyFunc = "anyfunc"; + bool structuralComparison(FunctionType& b) { if (result != b.result) return false; if (params.size() != b.params.size()) return false; @@ -1081,12 +1083,24 @@ class FunctionType { bool operator!=(FunctionType& b) { return !(*this == b); } + + static FunctionType* createAnyFuncType() { + FunctionType *anyFunc = new FunctionType; + anyFunc->name = FunctionType::kAnyFunc; + anyFunc->params.push_back(none); + return anyFunc; + } + + static bool isAnyFuncType(FunctionType *curr) { + return curr->params.size() == 1 && curr->params[0] == none && curr->result == none; + } }; class CallIndirect : public SpecificExpression { public: CallIndirect(MixedArena& allocator) : operands(allocator) {} + Name table; ExpressionList operands; Name fullType; Expression *target; @@ -1432,7 +1446,20 @@ class Export { class Table { public: - std::vector names; + Name name; + bool isDefault; + FunctionType* elementType; + Address initial, max; + std::vector values; + + enum { kDefault = 0 }; + + static Table* createDefaultTable() { + Table *table = new Table(); + table->isDefault = true; + table->name = Name::fromInt(kDefault); + return table; + } }; class Memory { @@ -1475,8 +1502,8 @@ class Module { std::vector> exports; std::vector> functions; std::vector> globals; + std::vector> tables; - Table table; Memory memory; Name start; @@ -1489,6 +1516,7 @@ class Module { std::map exportsMap; std::map functionsMap; std::map globalsMap; + std::map tablesMap; public: Module() {}; @@ -1498,24 +1526,28 @@ class Module { Export* getExport(Index i) { assert(i < exports.size()); return exports[i].get(); } Function* getFunction(Index i) { assert(i < functions.size()); return functions[i].get(); } Global* getGlobal(Index i) { assert(i < globals.size()); return globals[i].get(); } + Table* getTable(Index i) { assert(i < tables.size()); return tables[i].get(); } FunctionType* getFunctionType(Name name) { assert(functionTypesMap.count(name)); return functionTypesMap[name]; } Import* getImport(Name name) { assert(importsMap.count(name)); return importsMap[name]; } Export* getExport(Name name) { assert(exportsMap.count(name)); return exportsMap[name]; } Function* getFunction(Name name) { assert(functionsMap.count(name)); return functionsMap[name]; } Global* getGlobal(Name name) { assert(globalsMap.count(name)); return globalsMap[name]; } + Table* getTable(Name name) { assert(tablesMap.count(name)); return tablesMap[name]; } FunctionType* checkFunctionType(Name name) { if (!functionTypesMap.count(name)) return nullptr; return functionTypesMap[name]; } Import* checkImport(Name name) { if (!importsMap.count(name)) return nullptr; return importsMap[name]; } Export* checkExport(Name name) { if (!exportsMap.count(name)) return nullptr; return exportsMap[name]; } Function* checkFunction(Name name) { if (!functionsMap.count(name)) return nullptr; return functionsMap[name]; } Global* checkGlobal(Name name) { if (!globalsMap.count(name)) return nullptr; return globalsMap[name]; } + Table* checkTable(Name name) { if (!tablesMap.count(name)) return nullptr; return tablesMap[name]; } FunctionType* checkFunctionType(Index i) { if (i >= functionTypes.size()) return nullptr; return functionTypes[i].get(); } Import* checkImport(Index i) { if (i >= imports.size()) return nullptr; return imports[i].get(); } Export* checkExport(Index i) { if (i >= exports.size()) return nullptr; return exports[i].get(); } Function* checkFunction(Index i) { if (i >= functions.size()) return nullptr; return functions[i].get(); } Global* checkGlobal(Index i) { if (i >= globals.size()) return nullptr; return globals[i].get(); } + Table* checkTable(Index i) { if (i >= tables.size()) return nullptr; return tables[i].get(); } void addFunctionType(FunctionType* curr) { Name numericName = Name::fromInt(functionTypes.size()); // TODO: remove all these, assert on names already existing, do numeric stuff in wasm-s-parser etc. @@ -1562,11 +1594,36 @@ class Module { globalsMap[curr->name] = curr; globalsMap[numericName] = curr; } - + void addTable(Table *curr) { + Name numericName = Name::fromInt(tables.size()); + if (curr->name.isNull()) { + curr->name = numericName; + } + tables.push_back(std::unique_ptr
(curr)); + tablesMap[curr->name] = curr; + tablesMap[numericName] = curr; + } void addStart(const Name &s) { start = s; } + FunctionType* getAnyFuncType() { + FunctionType *anyFunc = checkFunctionType(FunctionType::kAnyFunc); + if (anyFunc) return anyFunc; + anyFunc = FunctionType::createAnyFuncType(); + addFunctionType(anyFunc); + return anyFunc; + } + + Table* getDefaultTable() { + Table *def = checkTable(Name::fromInt(Table::kDefault)); + if (def) return def; + def = Table::createDefaultTable(); + def->elementType = getAnyFuncType(); + addTable(def); + return def; + } + void removeImport(Name name) { for (size_t i = 0; i < imports.size(); i++) { if (imports[i]->name == name) { diff --git a/test/dot_s/alias.wast b/test/dot_s/alias.wast index 5744f8e8ade..90ad6a159ee 100644 --- a/test/dot_s/alias.wast +++ b/test/dot_s/alias.wast @@ -4,10 +4,11 @@ ) (export "memory" memory) (type $FUNCSIG$v (func)) + (type $anyfunc (func (param none))) (export "__exit" $__exit) (export "__needs_exit" $__needs_exit) (export "dynCall_v" $dynCall_v) - (table $__wasm_nullptr $__exit) + (table $0 default (type $anyfunc (func (param none))) $__wasm_nullptr_0 $__exit) (func $__exit (type $FUNCSIG$v) (return (i32.add @@ -26,11 +27,11 @@ (i32.const 1) ) ) - (func $__wasm_nullptr (type $FUNCSIG$v) + (func $__wasm_nullptr_0 (type $FUNCSIG$v) (unreachable) ) (func $dynCall_v (param $fptr i32) - (call_indirect $FUNCSIG$v + (call_indirect $0 $FUNCSIG$v (get_local $fptr) ) ) diff --git a/test/dot_s/basics.wast b/test/dot_s/basics.wast index b93bcd5cc2f..c6d4313c504 100644 --- a/test/dot_s/basics.wast +++ b/test/dot_s/basics.wast @@ -6,12 +6,13 @@ ) (export "memory" memory) (type $FUNCSIG$vi (func (param i32))) - (type $FUNCSIG$v (func)) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $anyfunc (func (param none))) + (type $FUNCSIG$v (func)) (import $puts "env" "puts" (param i32)) (export "main" $main) (export "dynCall_iii" $dynCall_iii) - (table $__wasm_nullptr $main) + (table $0 default (type $anyfunc (func (param none))) $__wasm_nullptr_0 $main) (func $main (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) (call_import $puts (i32.const 16) @@ -91,11 +92,11 @@ ) (get_local $0) ) - (func $__wasm_nullptr (type $FUNCSIG$v) + (func $__wasm_nullptr_0 (type $FUNCSIG$v) (unreachable) ) (func $dynCall_iii (param $fptr i32) (param $0 i32) (param $1 i32) (result i32) - (call_indirect $FUNCSIG$iii + (call_indirect $0 $FUNCSIG$iii (get_local $fptr) (get_local $0) (get_local $1) diff --git a/test/dot_s/bcp-1.wast b/test/dot_s/bcp-1.wast index fcbe3b81e3c..4bdad3f7ef5 100644 --- a/test/dot_s/bcp-1.wast +++ b/test/dot_s/bcp-1.wast @@ -10,6 +10,7 @@ ) (export "memory" memory) (type $FUNCSIG$i (func (result i32))) + (type $anyfunc (func (param none))) (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$v (func)) (type $FUNCSIG$vi (func (param i32))) @@ -35,7 +36,7 @@ (export "main" $main) (export "dynCall_i" $dynCall_i) (export "dynCall_ii" $dynCall_ii) - (table $__wasm_nullptr $bad0 $bad1 $bad5 $bad7 $bad8 $bad10 $bad2 $bad3 $bad6 $bad4 $bad9 $good0 $good1 $good2 $opt0 $opt1 $opt2) + (table $0 default (type $anyfunc (func (param none))) $__wasm_nullptr_0 $bad0 $bad1 $bad5 $bad7 $bad8 $bad10 $bad2 $bad3 $bad6 $bad4 $bad9 $good0 $good1 $good2 $opt0 $opt1 $opt2) (func $bad0 (type $FUNCSIG$i) (result i32) (return (i32.const 0) @@ -130,42 +131,42 @@ ) (block $label$0 (br_if $label$0 - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=16 (get_local $0) ) ) ) (br_if $label$0 - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=20 (get_local $0) ) ) ) (br_if $label$0 - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=24 (get_local $0) ) ) ) (br_if $label$0 - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=28 (get_local $0) ) ) ) (br_if $label$0 - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=32 (get_local $0) ) ) ) (br_if $label$0 - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=36 (get_local $0) ) @@ -181,13 +182,13 @@ ) (block $label$1 (br_if $label$1 - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (get_local $1) (get_local $2) ) ) (br_if $label$1 - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.load offset=44 (get_local $0) ) @@ -195,7 +196,7 @@ ) ) (br_if $label$1 - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.load offset=48 (get_local $0) ) @@ -212,13 +213,13 @@ ) (block $label$2 (br_if $label$2 - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (get_local $1) (get_local $2) ) ) (br_if $label$2 - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.load offset=56 (get_local $0) ) @@ -228,7 +229,7 @@ (block $label$3 (br_if $label$3 (i32.eq - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=60 (get_local $0) ) @@ -238,7 +239,7 @@ ) (br_if $label$3 (i32.eq - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=64 (get_local $0) ) @@ -248,7 +249,7 @@ ) (br_if $label$3 (i32.eq - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=68 (get_local $0) ) @@ -259,7 +260,7 @@ (block $label$4 (br_if $label$4 (i32.eq - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=72 (get_local $0) ) @@ -269,7 +270,7 @@ ) (br_if $label$4 (i32.eq - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=76 (get_local $0) ) @@ -279,7 +280,7 @@ ) (br_if $label$4 (i32.eq - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (i32.load offset=80 (get_local $0) ) @@ -307,16 +308,16 @@ (call_import $abort) (unreachable) ) - (func $__wasm_nullptr (type $FUNCSIG$v) + (func $__wasm_nullptr_0 (type $FUNCSIG$v) (unreachable) ) (func $dynCall_i (param $fptr i32) (result i32) - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (get_local $fptr) ) ) (func $dynCall_ii (param $fptr i32) (param $0 i32) (result i32) - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (get_local $fptr) (get_local $0) ) diff --git a/test/dot_s/dyncall.wast b/test/dot_s/dyncall.wast index e284c838de3..8872ca82a40 100644 --- a/test/dot_s/dyncall.wast +++ b/test/dot_s/dyncall.wast @@ -1,8 +1,9 @@ (module (memory 1) (export "memory" memory) - (type $FUNCSIG$v (func)) (type $FUNCSIG$i (func (result i32))) + (type $anyfunc (func (param none))) + (type $FUNCSIG$v (func)) (type $FUNCSIG$if (func (param f32) (result i32))) (type $FUNCSIG$vd (func (param f64))) (type $FUNCSIG$ffjjdi (func (param f32 i64 i64 f64 i32) (result f32))) @@ -15,7 +16,7 @@ (export "dynCall_i" $dynCall_i) (export "dynCall_if" $dynCall_if) (export "dynCall_vd" $dynCall_vd) - (table $__wasm_nullptr $i $i_f $vd $ffjjdi $vd2) + (table $0 default (type $anyfunc (func (param none))) $__wasm_nullptr_0 $i $i_f $vd $ffjjdi $vd2) (func $i (type $FUNCSIG$i) (result i32) (i32.const 0) ) @@ -37,22 +38,22 @@ (i32.const 5) (i32.const 0) ) - (func $__wasm_nullptr (type $FUNCSIG$v) + (func $__wasm_nullptr_0 (type $FUNCSIG$v) (unreachable) ) (func $dynCall_i (param $fptr i32) (result i32) - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (get_local $fptr) ) ) (func $dynCall_if (param $fptr i32) (param $0 f32) (result i32) - (call_indirect $FUNCSIG$if + (call_indirect $0 $FUNCSIG$if (get_local $fptr) (get_local $0) ) ) (func $dynCall_vd (param $fptr i32) (param $0 f64) - (call_indirect $FUNCSIG$vd + (call_indirect $0 $FUNCSIG$vd (get_local $fptr) (get_local $0) ) diff --git a/test/dot_s/indidx.s b/test/dot_s/indidx.s index 68d8f5b774f..29b9ab223f7 100644 --- a/test/dot_s/indidx.s +++ b/test/dot_s/indidx.s @@ -2,7 +2,7 @@ .file "cfi-wasm.bs.bc" .type a,@function a: # @a - .indidx 4 + .indidx 1 .result i32 # BB#0: # %entry i32.const $push0=, 0 @@ -13,7 +13,7 @@ a: # @a .type b,@function b: # @b - .indidx 2 + .indidx 1 .result i32 # BB#0: # %entry i32.const $push0=, 1 @@ -35,7 +35,7 @@ c: # @c .type d,@function d: # @d - .indidx 3 + .indidx 1 .result i32 # BB#0: # %entry i32.const $push0=, 3 @@ -64,7 +64,7 @@ main: # @main i32.ge_u $push6=, $pop8, $pop5 br_if 0, $pop6 # 0: down to label0 # BB#1: # %cont - i32.call_indirect $push7=, $2 + i32.call_indirect.1 $push7=, $2 return $pop7 .LBB4_2: # %trap end_block # label0: diff --git a/test/dot_s/indidx.wast b/test/dot_s/indidx.wast index 2a5224d00d0..bd7206324de 100644 --- a/test/dot_s/indidx.wast +++ b/test/dot_s/indidx.wast @@ -1,14 +1,16 @@ (module (memory 1 - (segment 16 "\04\00\00\00\02\00\00\00\01\00\00\00\03\00\00\00") + (segment 16 "\01\00\00\00\02\00\00\00\03\00\00\00\04\00\00\00") ) (export "memory" memory) (type $FUNCSIG$i (func (result i32))) + (type $anyfunc (func (param none))) (type $FUNCSIG$v (func)) (import $getchar "env" "getchar" (result i32)) (export "main" $main) (export "dynCall_i" $dynCall_i) - (table $__wasm_nullptr $c $b $d $a) + (table $0 default (type $anyfunc (func (param none))) $__wasm_nullptr_0) + (table $1 (type $FUNCSIG$i (func (result i32))) $__wasm_nullptr_1 $a $b $c $d) (func $a (type $FUNCSIG$i) (result i32) (i32.const 0) ) @@ -41,7 +43,7 @@ ) ) (return - (call_indirect $FUNCSIG$i + (call_indirect $1 $FUNCSIG$i (get_local $2) ) ) @@ -49,11 +51,14 @@ (unreachable) (unreachable) ) - (func $__wasm_nullptr (type $FUNCSIG$v) + (func $__wasm_nullptr_1 (type $FUNCSIG$i) (result i32) + (unreachable) + ) + (func $__wasm_nullptr_0 (type $FUNCSIG$v) (unreachable) ) (func $dynCall_i (param $fptr i32) (result i32) - (call_indirect $FUNCSIG$i + (call_indirect $1 $FUNCSIG$i (get_local $fptr) ) ) diff --git a/test/dot_s/indirect-import.wast b/test/dot_s/indirect-import.wast index 22821a4e0c4..5aee0f377cb 100644 --- a/test/dot_s/indirect-import.wast +++ b/test/dot_s/indirect-import.wast @@ -6,6 +6,7 @@ (type $FUNCSIG$v (func)) (type $FUNCSIG$ijidf (func (param i64 i32 f64 f32) (result i32))) (type $FUNCSIG$vi (func (param i32))) + (type $anyfunc (func (param none))) (import $extern_ijidf "env" "extern_ijidf" (param i64 i32 f64 f32) (result i32)) (import $extern_v "env" "extern_v") (import $extern_vj "env" "extern_vj" (param i64)) @@ -17,7 +18,7 @@ (export "dynCall_fd" $dynCall_fd) (export "dynCall_v" $dynCall_v) (export "dynCall_vi" $dynCall_vi) - (table $__wasm_nullptr $__importThunk_extern_fd $__importThunk_extern_vj $__importThunk_extern_v $__importThunk_extern_ijidf $__importThunk_extern_struct $__importThunk_extern_sret) + (table $0 default (type $anyfunc (func (param none))) $__wasm_nullptr_0 $__importThunk_extern_fd $__importThunk_extern_vj $__importThunk_extern_v $__importThunk_extern_ijidf $__importThunk_extern_struct $__importThunk_extern_sret) (func $bar (result i32) (local $0 i32) (local $1 i32) @@ -82,14 +83,14 @@ (func $baz (result i32) (i32.const 3) ) - (func $__wasm_nullptr (type $FUNCSIG$v) - (unreachable) - ) (func $__importThunk_extern_fd (type $FUNCSIG$fd) (param $0 f64) (result f32) (call_import $extern_fd (get_local $0) ) ) + (func $__wasm_nullptr_0 (type $FUNCSIG$v) + (unreachable) + ) (func $__importThunk_extern_vj (type $FUNCSIG$vj) (param $0 i64) (call_import $extern_vj (get_local $0) @@ -117,18 +118,18 @@ ) ) (func $dynCall_fd (param $fptr i32) (param $0 f64) (result f32) - (call_indirect $FUNCSIG$fd + (call_indirect $0 $FUNCSIG$fd (get_local $fptr) (get_local $0) ) ) (func $dynCall_v (param $fptr i32) - (call_indirect $FUNCSIG$v + (call_indirect $0 $FUNCSIG$v (get_local $fptr) ) ) (func $dynCall_vi (param $fptr i32) (param $0 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (get_local $fptr) (get_local $0) ) diff --git a/test/emcc_O2_hello_world.fromasm b/test/emcc_O2_hello_world.fromasm index 8289055612a..9523da805d2 100644 --- a/test/emcc_O2_hello_world.fromasm +++ b/test/emcc_O2_hello_world.fromasm @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) @@ -42,7 +43,7 @@ (export "dynCall_ii" $dynCall_ii) (export "dynCall_iiii" $dynCall_iiii) (export "dynCall_vi" $dynCall_vi) - (table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) + (table $0 default (type $anyfunc (func (param none))) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) (func $_malloc (param $0 i32) (result i32) (local $1 i32) (local $2 i32) @@ -8255,7 +8256,7 @@ ) (block (set_local $4 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8332,7 +8333,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8827,7 +8828,7 @@ (set_local $4 (if (i32.eq - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8886,7 +8887,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8934,7 +8935,7 @@ ) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=40 @@ -9809,7 +9810,7 @@ ) ) (func $dynCall_iiii (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $0) @@ -9896,7 +9897,7 @@ ) ) (func $dynCall_ii (param $0 i32) (param $1 i32) (result i32) - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $0) @@ -9930,7 +9931,7 @@ ) ) (func $dynCall_vi (param $0 i32) (param $1 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $0) diff --git a/test/emcc_O2_hello_world.fromasm.imprecise b/test/emcc_O2_hello_world.fromasm.imprecise index ede6c05d4a0..1224568e0b8 100644 --- a/test/emcc_O2_hello_world.fromasm.imprecise +++ b/test/emcc_O2_hello_world.fromasm.imprecise @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) @@ -41,7 +42,7 @@ (export "dynCall_ii" $dynCall_ii) (export "dynCall_iiii" $dynCall_iiii) (export "dynCall_vi" $dynCall_vi) - (table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) + (table $0 default (type $anyfunc (func (param none))) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) (func $_malloc (param $0 i32) (result i32) (local $1 i32) (local $2 i32) @@ -8254,7 +8255,7 @@ ) (block (set_local $4 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8331,7 +8332,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8826,7 +8827,7 @@ (set_local $4 (if (i32.eq - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8885,7 +8886,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8933,7 +8934,7 @@ ) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=40 @@ -9808,7 +9809,7 @@ ) ) (func $dynCall_iiii (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $0) @@ -9895,7 +9896,7 @@ ) ) (func $dynCall_ii (param $0 i32) (param $1 i32) (result i32) - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $0) @@ -9929,7 +9930,7 @@ ) ) (func $dynCall_vi (param $0 i32) (param $1 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $0) diff --git a/test/emcc_O2_hello_world.fromasm.imprecise.no-opts b/test/emcc_O2_hello_world.fromasm.imprecise.no-opts index d34022a9e39..19897ef8fda 100644 --- a/test/emcc_O2_hello_world.fromasm.imprecise.no-opts +++ b/test/emcc_O2_hello_world.fromasm.imprecise.no-opts @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) @@ -41,7 +42,7 @@ (export "dynCall_ii" $dynCall_ii) (export "dynCall_iiii" $dynCall_iiii) (export "dynCall_vi" $dynCall_vi) - (table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) + (table $0 default (type $anyfunc (func (param none))) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) (func $_malloc (param $i1 i32) (result i32) (local $i2 i32) (local $i3 i32) @@ -9722,7 +9723,7 @@ ) (block (set_local $i8 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -9809,7 +9810,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10427,7 +10428,7 @@ ) (if (i32.eq - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10497,7 +10498,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10554,7 +10555,7 @@ (get_local $i6) (get_local $i8) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -11672,7 +11673,7 @@ ) (func $dynCall_iiii (param $i1 i32) (param $i2 i32) (param $i3 i32) (param $i4 i32) (result i32) (return - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $i1) @@ -11778,7 +11779,7 @@ ) (func $dynCall_ii (param $i1 i32) (param $i2 i32) (result i32) (return - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $i1) @@ -11817,7 +11818,7 @@ ) ) (func $dynCall_vi (param $i1 i32) (param $i2 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $i1) diff --git a/test/emcc_O2_hello_world.fromasm.no-opts b/test/emcc_O2_hello_world.fromasm.no-opts index f850b8306c7..4cc6dc7fadf 100644 --- a/test/emcc_O2_hello_world.fromasm.no-opts +++ b/test/emcc_O2_hello_world.fromasm.no-opts @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) @@ -42,7 +43,7 @@ (export "dynCall_ii" $dynCall_ii) (export "dynCall_iiii" $dynCall_iiii) (export "dynCall_vi" $dynCall_vi) - (table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) + (table $0 default (type $anyfunc (func (param none))) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $b1 $___stdio_write $b1 $b1 $b2 $b2 $b2 $b2 $_cleanup_418 $b2 $b2 $b2) (func $_malloc (param $i1 i32) (result i32) (local $i2 i32) (local $i3 i32) @@ -9723,7 +9724,7 @@ ) (block (set_local $i8 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -9810,7 +9811,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10428,7 +10429,7 @@ ) (if (i32.eq - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10498,7 +10499,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10555,7 +10556,7 @@ (get_local $i6) (get_local $i8) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -11673,7 +11674,7 @@ ) (func $dynCall_iiii (param $i1 i32) (param $i2 i32) (param $i3 i32) (param $i4 i32) (result i32) (return - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $i1) @@ -11779,7 +11780,7 @@ ) (func $dynCall_ii (param $i1 i32) (param $i2 i32) (result i32) (return - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $i1) @@ -11818,7 +11819,7 @@ ) ) (func $dynCall_vi (param $i1 i32) (param $i2 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $i1) diff --git a/test/emcc_hello_world.fromasm b/test/emcc_hello_world.fromasm index c99290ba837..7e0680c6d64 100644 --- a/test/emcc_hello_world.fromasm +++ b/test/emcc_hello_world.fromasm @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$id (func (param f64) (result i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) @@ -55,7 +56,7 @@ (export "dynCall_iiii" $dynCall_iiii) (export "dynCall_vi" $dynCall_vi) (export "___udivmoddi4" $___udivmoddi4) - (table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2) + (table $0 default (type $anyfunc (func (param none))) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2) (func $stackAlloc (param $0 i32) (result i32) (local $1 i32) (set_local $1 @@ -1653,7 +1654,7 @@ ) (get_local $1) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -1833,7 +1834,7 @@ (get_local $3) (block (set_local $4 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -1915,7 +1916,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -2783,7 +2784,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -2845,7 +2846,7 @@ ) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=40 @@ -19491,7 +19492,7 @@ ) ) (func $dynCall_ii (param $0 i32) (param $1 i32) (result i32) - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $0) @@ -19503,7 +19504,7 @@ ) ) (func $dynCall_iiii (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $0) @@ -19517,7 +19518,7 @@ ) ) (func $dynCall_vi (param $0 i32) (param $1 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $0) diff --git a/test/emcc_hello_world.fromasm.imprecise b/test/emcc_hello_world.fromasm.imprecise index ee84765a141..c6147c08a4f 100644 --- a/test/emcc_hello_world.fromasm.imprecise +++ b/test/emcc_hello_world.fromasm.imprecise @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) @@ -49,7 +50,7 @@ (export "dynCall_iiii" $dynCall_iiii) (export "dynCall_vi" $dynCall_vi) (export "___udivmoddi4" $___udivmoddi4) - (table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2) + (table $0 default (type $anyfunc (func (param none))) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2) (func $stackAlloc (param $0 i32) (result i32) (local $1 i32) (set_local $1 @@ -1647,7 +1648,7 @@ ) (get_local $1) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -1827,7 +1828,7 @@ (get_local $3) (block (set_local $4 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -1909,7 +1910,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -2777,7 +2778,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -2839,7 +2840,7 @@ ) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=40 @@ -19476,7 +19477,7 @@ ) ) (func $dynCall_ii (param $0 i32) (param $1 i32) (result i32) - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $0) @@ -19488,7 +19489,7 @@ ) ) (func $dynCall_iiii (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $0) @@ -19502,7 +19503,7 @@ ) ) (func $dynCall_vi (param $0 i32) (param $1 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $0) diff --git a/test/emcc_hello_world.fromasm.imprecise.no-opts b/test/emcc_hello_world.fromasm.imprecise.no-opts index 32761816931..937a5c763c9 100644 --- a/test/emcc_hello_world.fromasm.imprecise.no-opts +++ b/test/emcc_hello_world.fromasm.imprecise.no-opts @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) @@ -49,7 +50,7 @@ (export "dynCall_iiii" $dynCall_iiii) (export "dynCall_vi" $dynCall_vi) (export "___udivmoddi4" $___udivmoddi4) - (table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2) + (table $0 default (type $anyfunc (func (param none))) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2) (func $stackAlloc (param $size i32) (result i32) (local $ret i32) (set_local $ret @@ -2641,7 +2642,7 @@ (get_local $$write) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$5) @@ -2933,7 +2934,7 @@ ) ) (set_local $$call4 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$5) @@ -3062,7 +3063,7 @@ ) ) (set_local $$call16 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$8) @@ -4544,7 +4545,7 @@ (get_local $$write) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$2) @@ -4641,7 +4642,7 @@ (get_local $$sub$ptr$rhs$cast) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$6) @@ -32692,7 +32693,7 @@ ) (func $dynCall_ii (param $index i32) (param $a1 i32) (result i32) (return - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $index) @@ -32706,7 +32707,7 @@ ) (func $dynCall_iiii (param $index i32) (param $a1 i32) (param $a2 i32) (param $a3 i32) (result i32) (return - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $index) @@ -32721,7 +32722,7 @@ ) ) (func $dynCall_vi (param $index i32) (param $a1 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $index) diff --git a/test/emcc_hello_world.fromasm.no-opts b/test/emcc_hello_world.fromasm.no-opts index 41e3e9e26e2..f7da2a1e6de 100644 --- a/test/emcc_hello_world.fromasm.no-opts +++ b/test/emcc_hello_world.fromasm.no-opts @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$id (func (param f64) (result i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) @@ -55,7 +56,7 @@ (export "dynCall_iiii" $dynCall_iiii) (export "dynCall_vi" $dynCall_vi) (export "___udivmoddi4" $___udivmoddi4) - (table $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2) + (table $0 default (type $anyfunc (func (param none))) $b0 $___stdio_close $b1 $b1 $___stdout_write $___stdio_seek $___stdio_write $b1 $b1 $b1 $b2 $b2 $b2 $b2 $b2 $_cleanup $b2 $b2) (func $stackAlloc (param $size i32) (result i32) (local $ret i32) (set_local $ret @@ -2647,7 +2648,7 @@ (get_local $$write) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$5) @@ -2939,7 +2940,7 @@ ) ) (set_local $$call4 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$5) @@ -3068,7 +3069,7 @@ ) ) (set_local $$call16 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$8) @@ -4550,7 +4551,7 @@ (get_local $$write) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$2) @@ -4647,7 +4648,7 @@ (get_local $$sub$ptr$rhs$cast) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $$6) @@ -32698,7 +32699,7 @@ ) (func $dynCall_ii (param $index i32) (param $a1 i32) (result i32) (return - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $index) @@ -32712,7 +32713,7 @@ ) (func $dynCall_iiii (param $index i32) (param $a1 i32) (param $a2 i32) (param $a3 i32) (result i32) (return - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $index) @@ -32727,7 +32728,7 @@ ) ) (func $dynCall_vi (param $index i32) (param $a1 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $index) diff --git a/test/llvm_autogenerated/call.wast b/test/llvm_autogenerated/call.wast index 812667aec91..dd22242d565 100644 --- a/test/llvm_autogenerated/call.wast +++ b/test/llvm_autogenerated/call.wast @@ -4,6 +4,7 @@ ) (export "memory" memory) (type $FUNCSIG$v (func)) + (type $anyfunc (func (param none))) (type $FUNCSIG$i (func (result i32))) (type $FUNCSIG$d (func (result f64))) (type $FUNCSIG$f (func (result f32))) @@ -29,6 +30,7 @@ (export "tail_call_void_nullary" $tail_call_void_nullary) (export "fastcc_tail_call_void_nullary" $fastcc_tail_call_void_nullary) (export "coldcc_tail_call_void_nullary" $coldcc_tail_call_void_nullary) + (table $0 default (type $anyfunc (func (param none)))) (func $call_i32_nullary (result i32) (return (call_import $i32_nullary) @@ -69,14 +71,14 @@ ) ) (func $call_indirect_void (param $0 i32) - (call_indirect $FUNCSIG$v + (call_indirect $0 $FUNCSIG$v (get_local $0) ) (return) ) (func $call_indirect_i32 (param $0 i32) (result i32) (return - (call_indirect $FUNCSIG$i + (call_indirect $0 $FUNCSIG$i (get_local $0) ) ) diff --git a/test/memorygrowth.fromasm b/test/memorygrowth.fromasm index 5c005ba9993..2eed5247a90 100644 --- a/test/memorygrowth.fromasm +++ b/test/memorygrowth.fromasm @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) @@ -40,7 +41,7 @@ (export "dynCall_iiii" $lb) (export "dynCall_vi" $mb) (export "__growWasmMemory" $__growWasmMemory) - (table $nb $Oa $ob $Va $Ua $Ra $pb $Sa) + (table $0 default (type $anyfunc (func (param none))) $nb $Oa $ob $Va $Ua $Ra $pb $Sa) (func $eb (param $0 i32) (result i32) (local $1 i32) (local $2 i32) @@ -8338,7 +8339,7 @@ ) (block (set_local $4 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8415,7 +8416,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8905,7 +8906,7 @@ (set_local $4 (if (i32.eq - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8963,7 +8964,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -9022,7 +9023,7 @@ ) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=40 @@ -9904,7 +9905,7 @@ ) ) (func $lb (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $0) @@ -9986,7 +9987,7 @@ ) ) (func $kb (param $0 i32) (param $1 i32) (result i32) - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $0) @@ -10010,7 +10011,7 @@ ) ) (func $mb (param $0 i32) (param $1 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $0) diff --git a/test/memorygrowth.fromasm.imprecise b/test/memorygrowth.fromasm.imprecise index b70bc7c9e27..2187fb9b064 100644 --- a/test/memorygrowth.fromasm.imprecise +++ b/test/memorygrowth.fromasm.imprecise @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) @@ -39,7 +40,7 @@ (export "dynCall_iiii" $lb) (export "dynCall_vi" $mb) (export "__growWasmMemory" $__growWasmMemory) - (table $nb $Oa $ob $Va $Ua $Ra $pb $Sa) + (table $0 default (type $anyfunc (func (param none))) $nb $Oa $ob $Va $Ua $Ra $pb $Sa) (func $eb (param $0 i32) (result i32) (local $1 i32) (local $2 i32) @@ -8337,7 +8338,7 @@ ) (block (set_local $4 - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8414,7 +8415,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8904,7 +8905,7 @@ (set_local $4 (if (i32.eq - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -8962,7 +8963,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=36 @@ -9021,7 +9022,7 @@ ) ) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load offset=40 @@ -9903,7 +9904,7 @@ ) ) (func $lb (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $0) @@ -9985,7 +9986,7 @@ ) ) (func $kb (param $0 i32) (param $1 i32) (result i32) - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $0) @@ -10009,7 +10010,7 @@ ) ) (func $mb (param $0 i32) (param $1 i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $0) diff --git a/test/memorygrowth.fromasm.imprecise.no-opts b/test/memorygrowth.fromasm.imprecise.no-opts index dd03e651e9c..8014c2dd456 100644 --- a/test/memorygrowth.fromasm.imprecise.no-opts +++ b/test/memorygrowth.fromasm.imprecise.no-opts @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) (type $FUNCSIG$vi (func (param i32))) @@ -39,7 +40,7 @@ (export "dynCall_iiii" $lb) (export "dynCall_vi" $mb) (export "__growWasmMemory" $__growWasmMemory) - (table $nb $Oa $ob $Va $Ua $Ra $pb $Sa) + (table $0 default (type $anyfunc (func (param none))) $nb $Oa $ob $Va $Ua $Ra $pb $Sa) (func $eb (param $a i32) (result i32) (local $b i32) (local $c i32) @@ -9781,7 +9782,7 @@ ) (block (set_local $h - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -9868,7 +9869,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10487,7 +10488,7 @@ ) (if (i32.eq - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10556,7 +10557,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10624,7 +10625,7 @@ (get_local $f) (get_local $h) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -11764,7 +11765,7 @@ ) (func $lb (param $a i32) (param $b i32) (param $c i32) (param $d i32) (result i32) (return - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $a) @@ -11854,7 +11855,7 @@ ) (func $kb (param $a i32) (param $b i32) (result i32) (return - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $a) @@ -11883,7 +11884,7 @@ (return) ) (func $mb (param $a i32) (param $b i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $a) diff --git a/test/memorygrowth.fromasm.no-opts b/test/memorygrowth.fromasm.no-opts index 29aa4aa3099..0cc0a430689 100644 --- a/test/memorygrowth.fromasm.no-opts +++ b/test/memorygrowth.fromasm.no-opts @@ -1,6 +1,7 @@ (module (memory 256 256) (export "memory" memory) + (type $anyfunc (func (param none))) (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) (type $FUNCSIG$ii (func (param i32) (result i32))) @@ -40,7 +41,7 @@ (export "dynCall_iiii" $lb) (export "dynCall_vi" $mb) (export "__growWasmMemory" $__growWasmMemory) - (table $nb $Oa $ob $Va $Ua $Ra $pb $Sa) + (table $0 default (type $anyfunc (func (param none))) $nb $Oa $ob $Va $Ua $Ra $pb $Sa) (func $eb (param $a i32) (result i32) (local $b i32) (local $c i32) @@ -9782,7 +9783,7 @@ ) (block (set_local $h - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -9869,7 +9870,7 @@ ) (if (i32.lt_u - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10488,7 +10489,7 @@ ) (if (i32.eq - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10557,7 +10558,7 @@ ) ) (block - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -10625,7 +10626,7 @@ (get_local $f) (get_local $h) ) - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (i32.load @@ -11765,7 +11766,7 @@ ) (func $lb (param $a i32) (param $b i32) (param $c i32) (param $d i32) (result i32) (return - (call_indirect $FUNCSIG$iiii + (call_indirect $0 $FUNCSIG$iiii (i32.add (i32.and (get_local $a) @@ -11855,7 +11856,7 @@ ) (func $kb (param $a i32) (param $b i32) (result i32) (return - (call_indirect $FUNCSIG$ii + (call_indirect $0 $FUNCSIG$ii (i32.add (i32.and (get_local $a) @@ -11884,7 +11885,7 @@ (return) ) (func $mb (param $a i32) (param $b i32) - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (get_local $a) diff --git a/test/passes/coalesce-locals-learning.txt b/test/passes/coalesce-locals-learning.txt index 44ad12f5394..412cde19498 100644 --- a/test/passes/coalesce-locals-learning.txt +++ b/test/passes/coalesce-locals-learning.txt @@ -5,7 +5,9 @@ (type $2 (func)) (type $3 (func (param i32 f32))) (type $4 (func (param i32))) + (type $anyfunc (func (param none))) (import $_emscripten_autodebug_i32 "env" "_emscripten_autodebug_i32" (param i32 i32) (result i32)) + (table $0 default (type $anyfunc (func (param none)))) (func $nothing-to-do (type $2) (local $0 i32) (nop) diff --git a/test/passes/coalesce-locals.txt b/test/passes/coalesce-locals.txt index c24cf34e9cf..f9530d0710d 100644 --- a/test/passes/coalesce-locals.txt +++ b/test/passes/coalesce-locals.txt @@ -5,7 +5,9 @@ (type $2 (func)) (type $3 (func (param i32 f32))) (type $4 (func (param i32))) + (type $anyfunc (func (param none))) (import $_emscripten_autodebug_i32 "env" "_emscripten_autodebug_i32" (param i32 i32) (result i32)) + (table $0 default (type $anyfunc (func (param none)))) (func $nothing-to-do (type $2) (local $0 i32) (nop) diff --git a/test/passes/dce.txt b/test/passes/dce.txt index 692a5005e85..ca29e425808 100644 --- a/test/passes/dce.txt +++ b/test/passes/dce.txt @@ -2,7 +2,8 @@ (memory 10) (type $ii (func (param i32 i32))) (type $1 (func)) - (table $call-me) + (type $anyfunc (func (param none))) + (table $0 default (type $anyfunc (func (param none))) $call-me) (func $call-me (type $ii) (param $0 i32) (param $1 i32) (nop) ) diff --git a/test/passes/dce.wast b/test/passes/dce.wast index dcec20cc1fe..50fbeb6c91e 100644 --- a/test/passes/dce.wast +++ b/test/passes/dce.wast @@ -1,7 +1,7 @@ (module (memory 10) (type $ii (func (param i32) (param i32))) - (table $call-me) + (table $0 $call-me) (func $call-me (param i32) (param i32) ) (func $code-to-kill diff --git a/test/passes/duplicate-function-elimination.txt b/test/passes/duplicate-function-elimination.txt index 3671ce24b44..a8d3fa911b6 100644 --- a/test/passes/duplicate-function-elimination.txt +++ b/test/passes/duplicate-function-elimination.txt @@ -36,9 +36,10 @@ (memory 0) (start $keep2) (type $0 (func)) + (type $anyfunc (func (param none))) (export "keep2" $keep2) (export "other" $keep2) - (table $keep2 $keep2 $caller) + (table $0 default (type $anyfunc (func (param none))) $keep2 $keep2 $caller) (func $keep2 (type $0) (nop) ) @@ -363,9 +364,10 @@ (module (memory 0) (type $T (func)) - (table $erase $erase) + (type $anyfunc (func (param none))) + (table $0 default (type $anyfunc (func (param none))) $erase $erase) (func $erase (type $T) - (call_indirect $T + (call_indirect $0 $T (i32.const 0) ) ) @@ -373,14 +375,15 @@ (module (memory 0) (type $T (func)) - (table $keep2 $other) + (type $anyfunc (func (param none))) + (table $0 default (type $anyfunc (func (param none))) $keep2 $other) (func $keep2 (type $T) - (call_indirect $T + (call_indirect $0 $T (i32.const 0) ) ) (func $other (type $T) - (call_indirect $T + (call_indirect $0 $T (i32.const 1) ) ) @@ -389,14 +392,15 @@ (memory 0) (type $T (func)) (type $S (func)) - (table $keep2 $other) + (type $anyfunc (func (param none))) + (table $0 default (type $anyfunc (func (param none))) $keep2 $other) (func $keep2 (type $T) - (call_indirect $T + (call_indirect $0 $T (i32.const 0) ) ) (func $other (type $T) - (call_indirect $S + (call_indirect $0 $S (i32.const 0) ) ) diff --git a/test/passes/duplicate-function-elimination.wast b/test/passes/duplicate-function-elimination.wast index 8d1a85cd58d..45a8edd17ce 100644 --- a/test/passes/duplicate-function-elimination.wast +++ b/test/passes/duplicate-function-elimination.wast @@ -34,7 +34,7 @@ (export "keep2" $keep2) (export "other" $other) (start $other) - (table $keep2 $other $caller) + (table $0 $keep2 $other $caller) (func $keep2 (nop) ) @@ -315,7 +315,7 @@ ) (module (type T (func)) - (table $erase $other) + (table $0 $erase $other) (func $erase (call_indirect $T (i32.const 0)) ) @@ -325,7 +325,7 @@ ) (module (type T (func)) - (table $keep2 $other) + (table $0 $keep2 $other) (func $keep2 (call_indirect $T (i32.const 0)) ) @@ -336,7 +336,7 @@ (module (type T (func)) (type S (func)) - (table $keep2 $other) + (table $0 $keep2 $other) (func $keep2 (call_indirect $T (i32.const 0)) ) diff --git a/test/passes/remove-unused-functions.txt b/test/passes/remove-unused-functions.txt index b6f7cf3e1ce..10bde36fae2 100644 --- a/test/passes/remove-unused-functions.txt +++ b/test/passes/remove-unused-functions.txt @@ -2,8 +2,9 @@ (memory 0) (start $start) (type $0 (func)) + (type $anyfunc (func (param none))) (export "exported" $exported) - (table $called_indirect) + (table $0 default (type $anyfunc (func (param none))) $called_indirect) (func $start (type $0) (call $called0) ) diff --git a/test/passes/remove-unused-functions.wast b/test/passes/remove-unused-functions.wast index 4c89804bf59..29c95f27883 100644 --- a/test/passes/remove-unused-functions.wast +++ b/test/passes/remove-unused-functions.wast @@ -1,7 +1,7 @@ (module (start $start) (export "exported" $exported) - (table $called_indirect) + (table $0 $called_indirect) (func $start (call $called0) ) diff --git a/test/passes/remove-unused-names_merge-blocks.txt b/test/passes/remove-unused-names_merge-blocks.txt index fe5bd5cf8ed..6cacf62be9d 100644 --- a/test/passes/remove-unused-names_merge-blocks.txt +++ b/test/passes/remove-unused-names_merge-blocks.txt @@ -4,7 +4,8 @@ (type $ii (func (param i32 i32))) (type $iii (func (param i32 i32 i32))) (type $3 (func)) - (table $call-i) + (type $anyfunc (func (param none))) + (table $0 default (type $anyfunc (func (param none))) $call-i) (func $call-i (type $i) (param $0 i32) (nop) ) @@ -405,12 +406,12 @@ (i32.const 10) (i32.const 30) (i32.const 50) - (call_indirect $ii + (call_indirect $0 $ii (i32.const 20) (i32.const 40) (i32.const 60) ) - (call_indirect $ii + (call_indirect $0 $ii (unreachable) (block (i32.const 30) diff --git a/test/passes/remove-unused-names_merge-blocks.wast b/test/passes/remove-unused-names_merge-blocks.wast index 85bb11da62d..99932673265 100644 --- a/test/passes/remove-unused-names_merge-blocks.wast +++ b/test/passes/remove-unused-names_merge-blocks.wast @@ -3,7 +3,7 @@ (type $i (func (param i32))) (type $ii (func (param i32) (param i32))) (type $iii (func (param i32) (param i32) (param i32))) - (table $call-i) + (table $0 $call-i) (func $call-i (param i32) ) (func $call-ii (param i32) (param i32) diff --git a/test/unit.fromasm b/test/unit.fromasm index f939782e73f..b383ac0095b 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -4,6 +4,7 @@ (type $FUNCSIG$id (func (param f64) (result i32))) (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $anyfunc (func (param none))) (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$vd (func (param f64))) @@ -15,7 +16,7 @@ (import $i32u-div "asm2wasm" "i32u-div" (param i32 i32) (result i32)) (export "big_negative" $big_negative) (export "pick" $big_negative) - (table $big_negative $big_negative $big_negative $big_negative $big_negative $big_negative $importedDoubles $big_negative $big_negative $cneg) + (table $0 default (type $anyfunc (func (param none))) $big_negative $big_negative $big_negative $big_negative $big_negative $big_negative $importedDoubles $big_negative $big_negative $cneg) (func $big_negative (nop) ) @@ -221,7 +222,7 @@ ) (func $neg (local $0 f32) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.const 1) (i32.const 8) @@ -232,7 +233,7 @@ ) ) (func $cneg (param $0 f32) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.const 1) (i32.const 8) @@ -270,7 +271,7 @@ (get_local $0) ) (func $cneg_nosemicolon - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.const 1) (i32.const 8) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index f80f4ce6c74..dbc5d6943fb 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -2,6 +2,7 @@ (memory 256 256) (export "memory" memory) (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) + (type $anyfunc (func (param none))) (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$vd (func (param f64))) @@ -11,7 +12,7 @@ (import $f64-rem "asm2wasm" "f64-rem" (param f64 f64) (result f64)) (export "big_negative" $big_negative) (export "pick" $big_negative) - (table $big_negative $big_negative $big_negative $big_negative $big_negative $big_negative $importedDoubles $big_negative $big_negative $cneg) + (table $0 default (type $anyfunc (func (param none))) $big_negative $big_negative $big_negative $big_negative $big_negative $big_negative $importedDoubles $big_negative $big_negative $cneg) (func $big_negative (nop) ) @@ -205,7 +206,7 @@ ) (func $neg (local $0 f32) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.const 1) (i32.const 8) @@ -216,7 +217,7 @@ ) ) (func $cneg (param $0 f32) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.const 1) (i32.const 8) @@ -254,7 +255,7 @@ (get_local $0) ) (func $cneg_nosemicolon - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.const 1) (i32.const 8) diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index 4fa627938f1..227bdb5f33b 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -2,6 +2,7 @@ (memory 256 256) (export "memory" memory) (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) + (type $anyfunc (func (param none))) (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$vd (func (param f64))) @@ -11,7 +12,7 @@ (import $f64-rem "asm2wasm" "f64-rem" (param f64 f64) (result f64)) (export "big_negative" $big_negative) (export "pick" $exportMe) - (table $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + (table $0 default (type $anyfunc (func (param none))) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) (func $big_negative (local $temp f64) (set_local $temp @@ -394,7 +395,7 @@ (get_local $x) ) ) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.and (i32.const 1) @@ -406,7 +407,7 @@ ) ) (func $cneg (param $x f32) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.and (i32.const 1) @@ -456,7 +457,7 @@ ) ) (func $cneg_nosemicolon - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (i32.const 1) diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index c10bd3dff25..8e92645fd87 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -4,6 +4,7 @@ (type $FUNCSIG$id (func (param f64) (result i32))) (type $FUNCSIG$ddd (func (param f64 f64) (result f64))) (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $anyfunc (func (param none))) (type $FUNCSIG$vf (func (param f32))) (type $FUNCSIG$vi (func (param i32))) (type $FUNCSIG$vd (func (param f64))) @@ -15,7 +16,7 @@ (import $i32u-div "asm2wasm" "i32u-div" (param i32 i32) (result i32)) (export "big_negative" $big_negative) (export "pick" $exportMe) - (table $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + (table $0 default (type $anyfunc (func (param none))) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) (func $big_negative (local $temp f64) (set_local $temp @@ -400,7 +401,7 @@ (get_local $x) ) ) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.and (i32.const 1) @@ -412,7 +413,7 @@ ) ) (func $cneg (param $x f32) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.and (i32.const 1) @@ -462,7 +463,7 @@ ) ) (func $cneg_nosemicolon - (call_indirect $FUNCSIG$vi + (call_indirect $0 $FUNCSIG$vi (i32.add (i32.and (i32.const 1) diff --git a/test/unit.wast b/test/unit.wast index 301ba719c46..d5b12634f7a 100644 --- a/test/unit.wast +++ b/test/unit.wast @@ -10,11 +10,12 @@ (type $5 (func (result i32))) (type $6 (func (param i32) (result i32))) (type $7 (func (param f64) (result f64))) + (type $anyfunc (func (param none))) (import $_emscripten_asm_const_vi "env" "_emscripten_asm_const_vi") (import $f64-to-int "asm2wasm" "f64-to-int" (param f64) (result i32)) (import $f64-rem "asm2wasm" "f64-rem" (param f64 f64) (result f64)) (export "big_negative" $big_negative) - (table $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + (table $0 default (type $anyfunc (func (param none))) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) (func $big_negative (type $FUNCSIG$v) (local $temp f64) (block $block0 @@ -359,7 +360,7 @@ (get_local $x) ) ) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.and (i32.const 1) @@ -372,7 +373,7 @@ ) ) (func $cneg (type $FUNCSIG$vf) (param $x f32) - (call_indirect $FUNCSIG$vf + (call_indirect $0 $FUNCSIG$vf (i32.add (i32.and (i32.const 1) diff --git a/test/unit.wast.fromBinary b/test/unit.wast.fromBinary index c9ba4528b31..46a33f998d2 100644 --- a/test/unit.wast.fromBinary +++ b/test/unit.wast.fromBinary @@ -10,11 +10,12 @@ (type $5 (func (result i32))) (type $6 (func (param i32) (result i32))) (type $7 (func (param f64) (result f64))) + (type $anyfunc (func (param none))) (import $import$0 "env" "_emscripten_asm_const_vi") (import $import$1 "asm2wasm" "f64-to-int" (param f64) (result i32)) (import $import$2 "asm2wasm" "f64-rem" (param f64 f64) (result f64)) (export "big_negative" $big_negative) - (table $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) + (table $0 default (type $anyfunc (func (param none))) $z $big_negative $z $z $w $w $importedDoubles $w $z $cneg) (func $big_negative (type $1) (local $var$0 f64) (block $label$0 @@ -367,7 +368,7 @@ (get_local $var$0) ) ) - (call_indirect $0 + (call_indirect $0 $0 (i32.add (i32.and (i32.const 1) @@ -380,7 +381,7 @@ ) ) (func $cneg (type $0) (param $var$0 f32) - (call_indirect $0 + (call_indirect $0 $0 (i32.add (i32.and (i32.const 1)