Parses the function table section and creates metadata for each function.
| 2018 | |
| 2019 | /// Parses the function table section and creates metadata for each function. |
| 2020 | static LogicalResult parseFunctionTableSection( |
| 2021 | ArrayRef<uint8_t> payload, std::vector<FunctionInfo> &functionInfoList, |
| 2022 | const EncodingReader &reader, LazyTypeTable &types, |
| 2023 | ArrayRef<ArrayRef<uint8_t>> constants, DenseElementsAttrCache &constCache, |
| 2024 | MLIRContext &context) { |
| 2025 | EncodingReader sectionReader(payload, context); |
| 2026 | sectionReader.inheritStringTableFrom(reader); |
| 2027 | uint64_t numFunctions; |
| 2028 | if (failed(sectionReader.readVarInt(numFunctions))) |
| 2029 | return failure(); |
| 2030 | if (numFunctions > payload.size()) |
| 2031 | return sectionReader.emitError() |
| 2032 | << "number of functions (" << numFunctions |
| 2033 | << ") exceeds payload size (" << payload.size() << ")"; |
| 2034 | // Read each function's metadata |
| 2035 | functionInfoList.reserve(numFunctions); |
| 2036 | for (uint64_t i = 0; i < numFunctions; ++i) { |
| 2037 | FunctionInfo funcInfo; |
| 2038 | // Read the name index as a varint. |
| 2039 | if (failed(sectionReader.readVarInt(funcInfo.nameIndex))) |
| 2040 | return failure(); |
| 2041 | // Read the signature index as a varint. |
| 2042 | if (failed(sectionReader.readVarInt(funcInfo.signatureIndex))) |
| 2043 | return failure(); |
| 2044 | // Read the entry flag byte. |
| 2045 | if (failed(sectionReader.readLE(funcInfo.entryFlag))) |
| 2046 | return failure(); |
| 2047 | // Read the function location index as a varint. |
| 2048 | if (failed(sectionReader.readVarInt(funcInfo.functionLocIndex))) |
| 2049 | return failure(); |
| 2050 | |
| 2051 | // Read optimization hints if the flag is set for EntryOp. |
| 2052 | bool isEntry = |
| 2053 | (funcInfo.entryFlag & |
| 2054 | static_cast<uint8_t>(Bytecode::FunctionFlags::KindKernel)) != 0; |
| 2055 | bool hasOptHints = |
| 2056 | (funcInfo.entryFlag & |
| 2057 | static_cast<uint8_t>(Bytecode::FunctionFlags::HasOptimizationHints)) != |
| 2058 | 0; |
| 2059 | if (isEntry && hasOptHints) { |
| 2060 | if (failed(InstructionParser::parseSelfContainedOpAttribute( |
| 2061 | sectionReader, context, types, constants, constCache, |
| 2062 | funcInfo.optimizationHints))) |
| 2063 | return failure(); |
| 2064 | } |
| 2065 | |
| 2066 | // Read the length of the function as a varint. |
| 2067 | if (failed(sectionReader.readVarInt(funcInfo.lengthOfFunction))) |
| 2068 | return failure(); |
| 2069 | |
| 2070 | // Validate function length. |
| 2071 | if (funcInfo.lengthOfFunction > std::numeric_limits<size_t>::max()) |
| 2072 | return sectionReader.emitError() |
| 2073 | << "function body length " << funcInfo.lengthOfFunction |
| 2074 | << " exceeds maximum addressable size (" |
| 2075 | << std::numeric_limits<size_t>::max() << " bytes)"; |
| 2076 | |
| 2077 | // Check that we have enough remaining bytes. |
no test coverage detected