| 698 | } |
| 699 | |
| 700 | Error CodeHolder::new_named_label_id(Out<uint32_t> label_id_out, const char* name, size_t name_size, LabelType type, uint32_t parent_id) noexcept { |
| 701 | uint32_t label_id = _label_entries._size; |
| 702 | uint32_t hash_code = CodeHolder_hash_name_and_get_size(name, name_size); |
| 703 | |
| 704 | label_id_out = Globals::kInvalidId; |
| 705 | ASMJIT_PROPAGATE(_label_entries.reserve_additional(_arena)); |
| 706 | |
| 707 | if (name_size == 0) { |
| 708 | if (type != LabelType::kAnonymous) { |
| 709 | return make_error(Error::kInvalidLabelName); |
| 710 | } |
| 711 | |
| 712 | label_id_out = label_id; |
| 713 | _label_entries.append_unchecked(LabelEntry{const_cast<LabelEntry::ExtraData*>(&CodeHolder_shared_label_extra_data), uint64_t(0)}); |
| 714 | return Error::kOk; |
| 715 | } |
| 716 | |
| 717 | if (ASMJIT_UNLIKELY(name_size > Globals::kMaxLabelNameSize)) { |
| 718 | return make_error(Error::kLabelNameTooLong); |
| 719 | } |
| 720 | |
| 721 | size_t extra_data_size = sizeof(LabelEntry::ExtraData) + name_size + 1u; |
| 722 | |
| 723 | switch (type) { |
| 724 | case LabelType::kAnonymous: { |
| 725 | // Anonymous labels cannot have a parent (or more specifically, parent is useless here). |
| 726 | if (ASMJIT_UNLIKELY(parent_id != Globals::kInvalidId)) { |
| 727 | return make_error(Error::kInvalidParentLabel); |
| 728 | } |
| 729 | |
| 730 | LabelEntry::ExtraData* extra_data = _arena.alloc_oneshot<LabelEntry::ExtraData>(Arena::aligned_size(extra_data_size)); |
| 731 | if (ASMJIT_UNLIKELY(!extra_data)) { |
| 732 | return make_error(Error::kOutOfMemory); |
| 733 | } |
| 734 | |
| 735 | char* name_ptr = reinterpret_cast<char*>(extra_data) + sizeof(LabelEntry::ExtraData); |
| 736 | extra_data->_section_id = Globals::kInvalidId; |
| 737 | extra_data->_internal_label_type = type; |
| 738 | extra_data->_internal_label_flags = LabelFlags::kHasOwnExtraData | LabelFlags::kHasName; |
| 739 | extra_data->_internal_uint16_data = 0; |
| 740 | extra_data->_parent_id = Globals::kInvalidId; |
| 741 | extra_data->_name_size = uint32_t(name_size); |
| 742 | memcpy(name_ptr, name, name_size); |
| 743 | name_ptr[name_size] = '\0'; |
| 744 | |
| 745 | label_id_out = label_id; |
| 746 | _label_entries.append_unchecked(LabelEntry{extra_data, uint64_t(0)}); |
| 747 | return Error::kOk; |
| 748 | } |
| 749 | |
| 750 | case LabelType::kLocal: { |
| 751 | if (ASMJIT_UNLIKELY(parent_id >= _label_entries.size())) { |
| 752 | return make_error(Error::kInvalidParentLabel); |
| 753 | } |
| 754 | |
| 755 | hash_code ^= parent_id; |
| 756 | break; |
| 757 | } |
no test coverage detected