| 447 | } |
| 448 | |
| 449 | Error CodeHolder::newNamedLabelId(uint32_t& idOut, const char* name, size_t nameLength, uint32_t type, uint32_t parentId) noexcept { |
| 450 | idOut = 0; |
| 451 | uint32_t hVal = CodeHolder_hashNameAndFixLen(name, nameLength); |
| 452 | |
| 453 | if (ASMJIT_UNLIKELY(nameLength == 0)) |
| 454 | return DebugUtils::errored(kErrorInvalidLabelName); |
| 455 | |
| 456 | if (ASMJIT_UNLIKELY(nameLength > Globals::kMaxLabelLength)) |
| 457 | return DebugUtils::errored(kErrorLabelNameTooLong); |
| 458 | |
| 459 | switch (type) { |
| 460 | case Label::kTypeLocal: |
| 461 | if (ASMJIT_UNLIKELY(Operand::unpackId(parentId) >= _labels.getLength())) |
| 462 | return DebugUtils::errored(kErrorInvalidParentLabel); |
| 463 | |
| 464 | hVal ^= parentId; |
| 465 | break; |
| 466 | |
| 467 | case Label::kTypeGlobal: |
| 468 | if (ASMJIT_UNLIKELY(parentId != 0)) |
| 469 | return DebugUtils::errored(kErrorNonLocalLabelCantHaveParent); |
| 470 | |
| 471 | break; |
| 472 | |
| 473 | default: |
| 474 | return DebugUtils::errored(kErrorInvalidArgument); |
| 475 | } |
| 476 | |
| 477 | // Don't allow to insert duplicates. Local labels allow duplicates that have |
| 478 | // different id, this is already accomplished by having a different hashes |
| 479 | // between the same label names having different parent labels. |
| 480 | LabelEntry* le = _namedLabels.get(LabelByName(name, nameLength, hVal)); |
| 481 | if (ASMJIT_UNLIKELY(le)) |
| 482 | return DebugUtils::errored(kErrorLabelAlreadyDefined); |
| 483 | |
| 484 | Error err = kErrorOk; |
| 485 | size_t index = _labels.getLength(); |
| 486 | |
| 487 | if (ASMJIT_UNLIKELY(index >= Operand::kPackedIdCount)) |
| 488 | return DebugUtils::errored(kErrorLabelIndexOverflow); |
| 489 | |
| 490 | ASMJIT_PROPAGATE(_labels.willGrow(&_baseHeap)); |
| 491 | le = _baseHeap.allocZeroedT<LabelEntry>(); |
| 492 | |
| 493 | if (ASMJIT_UNLIKELY(!le)) |
| 494 | return DebugUtils::errored(kErrorNoHeapMemory); |
| 495 | |
| 496 | uint32_t id = Operand::packId(static_cast<uint32_t>(index)); |
| 497 | le->_hVal = hVal; |
| 498 | le->_setId(id); |
| 499 | le->_type = static_cast<uint8_t>(type); |
| 500 | le->_parentId = 0; |
| 501 | le->_sectionId = SectionEntry::kInvalidId; |
| 502 | le->_offset = 0; |
| 503 | |
| 504 | if (le->_name.mustEmbed(nameLength)) { |
| 505 | le->_name.setEmbedded(name, nameLength); |
| 506 | } |
no test coverage detected