bool ModuleGenerator::finishFuncExports() { // ModuleGenerator::exportedFuncs_ is an unordered HashSet. The // FuncExportVector stored in Metadata needs to be stored sorted by // function index to allow O(log(n)) lookup at runtime. Uint32Vector funcIndices; if (!funcIndices.reserve(exportedFuncs_.count())) return false; for (Uint32Set::Range r = exportedFuncs_.all(); !r.empty(); r.popFront()) funcIndices.infallibleAppend(r.front()); std::sort(funcIndices.begin(), funcIndices.end()); MOZ_ASSERT(metadata_->funcExports.empty()); if (!metadata_->funcExports.reserve(exportedFuncs_.count())) return false; for (uint32_t funcIndex : funcIndices) { Sig sig; if (!sig.clone(funcSig(funcIndex))) return false; metadata_->funcExports.infallibleEmplaceBack(Move(sig), funcIndex, funcIndexToCodeRange_[funcIndex]); } return true; }
bool ModuleGenerator::finishFuncExports() { // In addition to all the functions that were explicitly exported, any // element of an exported table is also exported. for (ElemSegment& elems : elemSegments_) { if (shared_->tables[elems.tableIndex].external) { for (uint32_t funcIndex : elems.elemFuncIndices) { if (!exportedFuncs_.put(funcIndex)) return false; } } } // ModuleGenerator::exportedFuncs_ is an unordered HashSet. The // FuncExportVector stored in Metadata needs to be stored sorted by // function index to allow O(log(n)) lookup at runtime. Uint32Vector sorted; if (!sorted.reserve(exportedFuncs_.count())) return false; for (Uint32Set::Range r = exportedFuncs_.all(); !r.empty(); r.popFront()) sorted.infallibleAppend(r.front()); std::sort(sorted.begin(), sorted.end()); MOZ_ASSERT(metadata_->funcExports.empty()); if (!metadata_->funcExports.reserve(sorted.length())) return false; for (uint32_t funcIndex : sorted) { Sig sig; if (!sig.clone(funcSig(funcIndex))) return false; uint32_t codeRangeIndex = funcToCodeRange_[funcIndex]; metadata_->funcExports.infallibleEmplaceBack(Move(sig), funcIndex, codeRangeIndex); } return true; }