| 295 | } |
| 296 | |
| 297 | spv_result_t LookupExtInst(spv_ext_inst_type_t type, const char* name, |
| 298 | const ExtInstDesc** desc) { |
| 299 | auto ir = ExtInstNameRangeForKind(type); |
| 300 | if (ir.empty()) { |
| 301 | return SPV_ERROR_INVALID_LOOKUP; |
| 302 | } |
| 303 | |
| 304 | auto span = ir.apply(kExtInstNames.data()); |
| 305 | |
| 306 | // The comparison function knows to use 'name' string to compare against |
| 307 | // when the value is kSentinel. |
| 308 | const auto kSentinel = uint32_t(-1); |
| 309 | const NameIndex needle{{}, kSentinel}; |
| 310 | auto less = [&](const NameIndex& lhs, const NameIndex& rhs) { |
| 311 | const char* lhs_chars = lhs.index == kSentinel ? name : getChars(lhs.name); |
| 312 | const char* rhs_chars = rhs.index == kSentinel ? name : getChars(rhs.name); |
| 313 | return std::strcmp(lhs_chars, rhs_chars) < 0; |
| 314 | }; |
| 315 | |
| 316 | auto where = std::lower_bound(span.begin(), span.end(), needle, less); |
| 317 | if (where != span.end() && std::strcmp(getChars(where->name), name) == 0) { |
| 318 | *desc = &kExtInstByValue[where->index]; |
| 319 | return SPV_SUCCESS; |
| 320 | } |
| 321 | return SPV_ERROR_INVALID_LOOKUP; |
| 322 | } |
| 323 | |
| 324 | // Finds the extended instruction description by opcode value. |
| 325 | // On success, returns SPV_SUCCESS and updates *desc. |