1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci#include <cstdint> 17b1994897Sopenharmony_ci 18b1994897Sopenharmony_ci#include "libpandafile/bytecode_instruction-inl.h" 19b1994897Sopenharmony_ci#include "libpandafile/line_number_program.h" 20b1994897Sopenharmony_ci#include "libpandafile/literal_data_accessor-inl.h" 21b1994897Sopenharmony_ci#include "libpandafile/class_data_accessor-inl.h" 22b1994897Sopenharmony_ci#include "libpandafile/proto_data_accessor-inl.h" 23b1994897Sopenharmony_ci#include "libpandafile/code_data_accessor-inl.h" 24b1994897Sopenharmony_ci#include "libpandafile/debug_data_accessor-inl.h" 25b1994897Sopenharmony_ci#include "libpandafile/field_data_accessor-inl.h" 26b1994897Sopenharmony_ci#include "libpandafile/method_data_accessor-inl.h" 27b1994897Sopenharmony_ci 28b1994897Sopenharmony_ci#include "file.h" 29b1994897Sopenharmony_ci 30b1994897Sopenharmony_ci#include "libpandabase/utils/utf.h" 31b1994897Sopenharmony_ci 32b1994897Sopenharmony_ci#include "libpandafile/file_reader.h" 33b1994897Sopenharmony_ci 34b1994897Sopenharmony_cinamespace panda::panda_file { 35b1994897Sopenharmony_ci 36b1994897Sopenharmony_cibool FileReader::ReadContainer() 37b1994897Sopenharmony_ci{ 38b1994897Sopenharmony_ci if (!ReadClasses()) { 39b1994897Sopenharmony_ci return false; 40b1994897Sopenharmony_ci } 41b1994897Sopenharmony_ci if (!ReadLiteralArrayItems()) { 42b1994897Sopenharmony_ci return false; 43b1994897Sopenharmony_ci } 44b1994897Sopenharmony_ci if (!ReadIndexHeaders()) { 45b1994897Sopenharmony_ci return false; 46b1994897Sopenharmony_ci } 47b1994897Sopenharmony_ci 48b1994897Sopenharmony_ci ComputeLayoutAndUpdateIndices(); 49b1994897Sopenharmony_ci 50b1994897Sopenharmony_ci return true; 51b1994897Sopenharmony_ci} 52b1994897Sopenharmony_ci 53b1994897Sopenharmony_ci/* static */ 54b1994897Sopenharmony_cibool FileReader::CreateLiteralArrayItem(const LiteralDataAccessor::LiteralValue &lit_value, const LiteralTag &tag, 55b1994897Sopenharmony_ci File::EntityId array_id) 56b1994897Sopenharmony_ci{ 57b1994897Sopenharmony_ci auto it = items_done_.find(array_id); 58b1994897Sopenharmony_ci if (it != items_done_.end()) { 59b1994897Sopenharmony_ci return true; 60b1994897Sopenharmony_ci } 61b1994897Sopenharmony_ci 62b1994897Sopenharmony_ci LiteralArrayItem *item = container_.GetOrCreateLiteralArrayItem(std::to_string(array_id.GetOffset())); 63b1994897Sopenharmony_ci items_done_.insert({array_id, static_cast<BaseItem *>(item)}); 64b1994897Sopenharmony_ci 65b1994897Sopenharmony_ci File::EntityId id(std::get<uint32_t>(lit_value)); 66b1994897Sopenharmony_ci auto sp = file_->GetSpanFromId(id); 67b1994897Sopenharmony_ci 68b1994897Sopenharmony_ci std::vector<panda_file::LiteralItem> literal_array; 69b1994897Sopenharmony_ci literal_array.emplace_back(static_cast<uint8_t>(tag)); 70b1994897Sopenharmony_ci switch (tag) { 71b1994897Sopenharmony_ci case panda_file::LiteralTag::BOOL: { 72b1994897Sopenharmony_ci auto v = helpers::Read<sizeof(bool)>(&sp); 73b1994897Sopenharmony_ci literal_array.emplace_back(static_cast<uint8_t>(v)); 74b1994897Sopenharmony_ci break; 75b1994897Sopenharmony_ci } 76b1994897Sopenharmony_ci case panda_file::LiteralTag::TAGVALUE: 77b1994897Sopenharmony_ci case panda_file::LiteralTag::ACCESSOR: 78b1994897Sopenharmony_ci case panda_file::LiteralTag::NULLVALUE: { 79b1994897Sopenharmony_ci auto v = helpers::Read<sizeof(uint8_t)>(&sp); 80b1994897Sopenharmony_ci literal_array.emplace_back(v); 81b1994897Sopenharmony_ci break; 82b1994897Sopenharmony_ci } 83b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_U1: 84b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_I8: 85b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_U8: { 86b1994897Sopenharmony_ci auto len = helpers::Read<sizeof(uint32_t)>(&sp); 87b1994897Sopenharmony_ci literal_array.emplace_back(len); 88b1994897Sopenharmony_ci for (size_t i = 0; i < len; i++) { 89b1994897Sopenharmony_ci auto v = helpers::Read<sizeof(uint8_t)>(&sp); 90b1994897Sopenharmony_ci literal_array.emplace_back(v); 91b1994897Sopenharmony_ci } 92b1994897Sopenharmony_ci break; 93b1994897Sopenharmony_ci } 94b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_I16: 95b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_U16: { 96b1994897Sopenharmony_ci auto len = helpers::Read<sizeof(uint32_t)>(&sp); 97b1994897Sopenharmony_ci literal_array.emplace_back(len); 98b1994897Sopenharmony_ci for (size_t i = 0; i < len; i++) { 99b1994897Sopenharmony_ci auto v = helpers::Read<sizeof(uint16_t)>(&sp); 100b1994897Sopenharmony_ci literal_array.emplace_back(v); 101b1994897Sopenharmony_ci } 102b1994897Sopenharmony_ci break; 103b1994897Sopenharmony_ci } 104b1994897Sopenharmony_ci case panda_file::LiteralTag::INTEGER: { 105b1994897Sopenharmony_ci auto v = helpers::Read<sizeof(uint32_t)>(&sp); 106b1994897Sopenharmony_ci literal_array.emplace_back(v); 107b1994897Sopenharmony_ci break; 108b1994897Sopenharmony_ci } 109b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_I32: 110b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_U32: 111b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_F32: { 112b1994897Sopenharmony_ci auto len = helpers::Read<sizeof(uint32_t)>(&sp); 113b1994897Sopenharmony_ci literal_array.emplace_back(len); 114b1994897Sopenharmony_ci for (size_t i = 0; i < len; i++) { 115b1994897Sopenharmony_ci auto v = helpers::Read<sizeof(uint32_t)>(&sp); 116b1994897Sopenharmony_ci literal_array.emplace_back(v); 117b1994897Sopenharmony_ci } 118b1994897Sopenharmony_ci break; 119b1994897Sopenharmony_ci } 120b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_I64: 121b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_U64: 122b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_F64: { 123b1994897Sopenharmony_ci auto len = helpers::Read<sizeof(uint32_t)>(&sp); 124b1994897Sopenharmony_ci literal_array.emplace_back(len); 125b1994897Sopenharmony_ci for (size_t i = 0; i < len; i++) { 126b1994897Sopenharmony_ci auto v = helpers::Read<sizeof(uint64_t)>(&sp); 127b1994897Sopenharmony_ci literal_array.emplace_back(v); 128b1994897Sopenharmony_ci } 129b1994897Sopenharmony_ci break; 130b1994897Sopenharmony_ci } 131b1994897Sopenharmony_ci case panda_file::LiteralTag::FLOAT: { 132b1994897Sopenharmony_ci auto v = helpers::Read<sizeof(uint32_t)>(&sp); 133b1994897Sopenharmony_ci literal_array.emplace_back(v); 134b1994897Sopenharmony_ci break; 135b1994897Sopenharmony_ci } 136b1994897Sopenharmony_ci case panda_file::LiteralTag::DOUBLE: { 137b1994897Sopenharmony_ci auto v = panda_file::helpers::Read<sizeof(uint64_t)>(&sp); 138b1994897Sopenharmony_ci literal_array.emplace_back(v); 139b1994897Sopenharmony_ci break; 140b1994897Sopenharmony_ci } 141b1994897Sopenharmony_ci case panda_file::LiteralTag::STRING: { 142b1994897Sopenharmony_ci File::EntityId str_id(helpers::Read<sizeof(uint32_t)>(&sp)); 143b1994897Sopenharmony_ci auto data = file_->GetStringData(str_id); 144b1994897Sopenharmony_ci std::string item_str(utf::Mutf8AsCString(data.data)); 145b1994897Sopenharmony_ci auto *string_item = container_.GetOrCreateStringItem(item_str); 146b1994897Sopenharmony_ci literal_array.emplace_back(string_item); 147b1994897Sopenharmony_ci break; 148b1994897Sopenharmony_ci } 149b1994897Sopenharmony_ci case panda_file::LiteralTag::ARRAY_STRING: { 150b1994897Sopenharmony_ci auto len = helpers::Read<sizeof(uint32_t)>(&sp); 151b1994897Sopenharmony_ci literal_array.emplace_back(len); 152b1994897Sopenharmony_ci for (size_t i = 0; i < len; i++) { 153b1994897Sopenharmony_ci File::EntityId str_id(helpers::Read<sizeof(uint32_t)>(&sp)); 154b1994897Sopenharmony_ci auto data = file_->GetStringData(str_id); 155b1994897Sopenharmony_ci std::string item_str(utf::Mutf8AsCString(data.data)); 156b1994897Sopenharmony_ci auto *string_item = container_.GetOrCreateStringItem(item_str); 157b1994897Sopenharmony_ci literal_array.emplace_back(string_item); 158b1994897Sopenharmony_ci } 159b1994897Sopenharmony_ci break; 160b1994897Sopenharmony_ci } 161b1994897Sopenharmony_ci case panda_file::LiteralTag::METHOD: 162b1994897Sopenharmony_ci case panda_file::LiteralTag::GETTER: 163b1994897Sopenharmony_ci case panda_file::LiteralTag::SETTER: 164b1994897Sopenharmony_ci case panda_file::LiteralTag::GENERATORMETHOD: 165b1994897Sopenharmony_ci case panda_file::LiteralTag::ASYNCGENERATORMETHOD: { 166b1994897Sopenharmony_ci File::EntityId method_id(helpers::Read<sizeof(uint32_t)>(&sp)); 167b1994897Sopenharmony_ci MethodDataAccessor method_acc(*file_, method_id); 168b1994897Sopenharmony_ci File::EntityId class_id(method_acc.GetClassId()); 169b1994897Sopenharmony_ci auto *class_item = CreateClassItem(class_id); 170b1994897Sopenharmony_ci literal_array.emplace_back(CreateMethodItem(class_item, method_id)); 171b1994897Sopenharmony_ci break; 172b1994897Sopenharmony_ci } 173b1994897Sopenharmony_ci default: 174b1994897Sopenharmony_ci UNREACHABLE(); 175b1994897Sopenharmony_ci } 176b1994897Sopenharmony_ci 177b1994897Sopenharmony_ci item->AddItems(literal_array); 178b1994897Sopenharmony_ci 179b1994897Sopenharmony_ci return true; 180b1994897Sopenharmony_ci} 181b1994897Sopenharmony_ci 182b1994897Sopenharmony_ci// NOLINTNEXTLINE(readability-function-size) 183b1994897Sopenharmony_ciAnnotationItem *FileReader::CreateAnnotationItem(File::EntityId ann_id) 184b1994897Sopenharmony_ci{ 185b1994897Sopenharmony_ci auto it = items_done_.find(ann_id); 186b1994897Sopenharmony_ci if (it != items_done_.end()) { 187b1994897Sopenharmony_ci return static_cast<AnnotationItem *>(it->second); 188b1994897Sopenharmony_ci } 189b1994897Sopenharmony_ci 190b1994897Sopenharmony_ci AnnotationDataAccessor ann_acc(*file_, ann_id); 191b1994897Sopenharmony_ci File::EntityId ann_class_id {ann_acc.GetClassId()}; 192b1994897Sopenharmony_ci AnnotationItem *ann_item = nullptr; 193b1994897Sopenharmony_ci 194b1994897Sopenharmony_ci if (!file_->IsExternal(ann_class_id)) { 195b1994897Sopenharmony_ci auto *ann_class_item = CreateClassItem(ann_class_id); 196b1994897Sopenharmony_ci ann_item = container_.CreateItem<AnnotationItem>(ann_class_item, std::vector<AnnotationItem::Elem>(), 197b1994897Sopenharmony_ci std::vector<AnnotationItem::Tag>()); 198b1994897Sopenharmony_ci } else { 199b1994897Sopenharmony_ci auto *ann_class_item = CreateForeignClassItem(ann_class_id); 200b1994897Sopenharmony_ci ann_item = container_.CreateItem<AnnotationItem>(ann_class_item, std::vector<AnnotationItem::Elem>(), 201b1994897Sopenharmony_ci std::vector<AnnotationItem::Tag>()); 202b1994897Sopenharmony_ci } 203b1994897Sopenharmony_ci 204b1994897Sopenharmony_ci ASSERT(ann_item != nullptr); 205b1994897Sopenharmony_ci 206b1994897Sopenharmony_ci items_done_.insert({ann_id, static_cast<BaseItem *>(ann_item)}); 207b1994897Sopenharmony_ci 208b1994897Sopenharmony_ci std::vector<AnnotationItem::Elem> item_elements; 209b1994897Sopenharmony_ci std::vector<AnnotationItem::Tag> tag_elements; 210b1994897Sopenharmony_ci 211b1994897Sopenharmony_ci for (size_t i = 0; i < ann_acc.GetCount(); i++) { 212b1994897Sopenharmony_ci AnnotationDataAccessor::Tag ann_tag = ann_acc.GetTag(i); 213b1994897Sopenharmony_ci AnnotationDataAccessor::Elem ann_elem = ann_acc.GetElement(i); 214b1994897Sopenharmony_ci ValueItem *elem_value_item = nullptr; 215b1994897Sopenharmony_ci switch (ann_tag.GetItem()) { 216b1994897Sopenharmony_ci case '1': 217b1994897Sopenharmony_ci case '2': 218b1994897Sopenharmony_ci case '3': { 219b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 220b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIntegerValueItem(scalar.Get<uint8_t>()); 221b1994897Sopenharmony_ci break; 222b1994897Sopenharmony_ci } 223b1994897Sopenharmony_ci case '4': 224b1994897Sopenharmony_ci case '5': { 225b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 226b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIntegerValueItem(scalar.Get<uint16_t>()); 227b1994897Sopenharmony_ci break; 228b1994897Sopenharmony_ci } 229b1994897Sopenharmony_ci case '6': 230b1994897Sopenharmony_ci case '7': { 231b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 232b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIntegerValueItem(scalar.Get<uint32_t>()); 233b1994897Sopenharmony_ci break; 234b1994897Sopenharmony_ci } 235b1994897Sopenharmony_ci case '8': 236b1994897Sopenharmony_ci case '9': { 237b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 238b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateLongValueItem(scalar.Get<uint64_t>()); 239b1994897Sopenharmony_ci break; 240b1994897Sopenharmony_ci } 241b1994897Sopenharmony_ci case 'A': { 242b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 243b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateFloatValueItem(scalar.Get<float>()); 244b1994897Sopenharmony_ci break; 245b1994897Sopenharmony_ci } 246b1994897Sopenharmony_ci case 'B': { 247b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 248b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateDoubleValueItem(scalar.Get<double>()); 249b1994897Sopenharmony_ci break; 250b1994897Sopenharmony_ci } 251b1994897Sopenharmony_ci case 'C': { 252b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 253b1994897Sopenharmony_ci const File::EntityId str_id(scalar.Get<uint32_t>()); 254b1994897Sopenharmony_ci auto data = file_->GetStringData(str_id); 255b1994897Sopenharmony_ci std::string item_str(utf::Mutf8AsCString(data.data)); 256b1994897Sopenharmony_ci auto *str_item = container_.GetOrCreateStringItem(item_str); 257b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIdValueItem(str_item); 258b1994897Sopenharmony_ci break; 259b1994897Sopenharmony_ci } 260b1994897Sopenharmony_ci case 'D': { 261b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 262b1994897Sopenharmony_ci const File::EntityId class_id {scalar.Get<uint32_t>()}; 263b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIdValueItem(CreateGenericClassItem(class_id)); 264b1994897Sopenharmony_ci break; 265b1994897Sopenharmony_ci } 266b1994897Sopenharmony_ci case 'E': { 267b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 268b1994897Sopenharmony_ci const File::EntityId method_id {scalar.Get<uint32_t>()}; 269b1994897Sopenharmony_ci MethodDataAccessor method_acc(*file_, method_id); 270b1994897Sopenharmony_ci auto *cls_item = CreateGenericClassItem(method_acc.GetClassId()); 271b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIdValueItem(CreateGenericMethodItem(cls_item, method_id)); 272b1994897Sopenharmony_ci break; 273b1994897Sopenharmony_ci } 274b1994897Sopenharmony_ci case 'F': { 275b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 276b1994897Sopenharmony_ci const File::EntityId field_id {scalar.Get<uint32_t>()}; 277b1994897Sopenharmony_ci FieldDataAccessor field_acc(*file_, field_id); 278b1994897Sopenharmony_ci auto *cls_item = CreateGenericClassItem(field_acc.GetClassId()); 279b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIdValueItem(CreateGenericFieldItem(cls_item, field_id)); 280b1994897Sopenharmony_ci break; 281b1994897Sopenharmony_ci } 282b1994897Sopenharmony_ci case 'G': { 283b1994897Sopenharmony_ci auto scalar = ann_elem.GetScalarValue(); 284b1994897Sopenharmony_ci const File::EntityId ann_item_id {scalar.Get<uint32_t>()}; 285b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIdValueItem(CreateAnnotationItem(ann_item_id)); 286b1994897Sopenharmony_ci break; 287b1994897Sopenharmony_ci } 288b1994897Sopenharmony_ci case 'J': { 289b1994897Sopenharmony_ci LOG(FATAL, PANDAFILE) << "MethodHandle is not supported so far"; 290b1994897Sopenharmony_ci break; 291b1994897Sopenharmony_ci } 292b1994897Sopenharmony_ci case '*': { 293b1994897Sopenharmony_ci elem_value_item = container_.GetOrCreateIntegerValueItem(0); 294b1994897Sopenharmony_ci break; 295b1994897Sopenharmony_ci } 296b1994897Sopenharmony_ci case 'K': { 297b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 298b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 299b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 300b1994897Sopenharmony_ci ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint8_t>(j))); 301b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 302b1994897Sopenharmony_ci } 303b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 304b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U1), std::move(items))); 305b1994897Sopenharmony_ci break; 306b1994897Sopenharmony_ci } 307b1994897Sopenharmony_ci case 'L': { 308b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 309b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 310b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 311b1994897Sopenharmony_ci ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint8_t>(j))); 312b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 313b1994897Sopenharmony_ci } 314b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 315b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::I8), std::move(items))); 316b1994897Sopenharmony_ci break; 317b1994897Sopenharmony_ci } 318b1994897Sopenharmony_ci case 'M': { 319b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 320b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 321b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 322b1994897Sopenharmony_ci ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint8_t>(j))); 323b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 324b1994897Sopenharmony_ci } 325b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 326b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U8), std::move(items))); 327b1994897Sopenharmony_ci break; 328b1994897Sopenharmony_ci } 329b1994897Sopenharmony_ci case 'N': { 330b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 331b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 332b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 333b1994897Sopenharmony_ci ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint16_t>(j))); 334b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 335b1994897Sopenharmony_ci } 336b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 337b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::I16), std::move(items))); 338b1994897Sopenharmony_ci break; 339b1994897Sopenharmony_ci } 340b1994897Sopenharmony_ci case 'O': { 341b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 342b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 343b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 344b1994897Sopenharmony_ci ScalarValueItem scalar(static_cast<uint32_t>(array.Get<uint16_t>(j))); 345b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 346b1994897Sopenharmony_ci } 347b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 348b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U16), std::move(items))); 349b1994897Sopenharmony_ci break; 350b1994897Sopenharmony_ci } 351b1994897Sopenharmony_ci case 'P': { 352b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 353b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 354b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 355b1994897Sopenharmony_ci ScalarValueItem scalar(array.Get<uint32_t>(j)); 356b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 357b1994897Sopenharmony_ci } 358b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 359b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::I32), std::move(items))); 360b1994897Sopenharmony_ci break; 361b1994897Sopenharmony_ci } 362b1994897Sopenharmony_ci case 'Q': { 363b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 364b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 365b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 366b1994897Sopenharmony_ci ScalarValueItem scalar(array.Get<uint32_t>(j)); 367b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 368b1994897Sopenharmony_ci } 369b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 370b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U32), std::move(items))); 371b1994897Sopenharmony_ci break; 372b1994897Sopenharmony_ci } 373b1994897Sopenharmony_ci case 'R': { 374b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 375b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 376b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 377b1994897Sopenharmony_ci ScalarValueItem scalar(array.Get<uint64_t>(j)); 378b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 379b1994897Sopenharmony_ci } 380b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 381b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::I64), std::move(items))); 382b1994897Sopenharmony_ci break; 383b1994897Sopenharmony_ci } 384b1994897Sopenharmony_ci case 'S': { 385b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 386b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 387b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 388b1994897Sopenharmony_ci ScalarValueItem scalar(array.Get<uint64_t>(j)); 389b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 390b1994897Sopenharmony_ci } 391b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 392b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::U64), std::move(items))); 393b1994897Sopenharmony_ci break; 394b1994897Sopenharmony_ci } 395b1994897Sopenharmony_ci case 'T': { 396b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 397b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 398b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 399b1994897Sopenharmony_ci ScalarValueItem scalar(array.Get<float>(j)); 400b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 401b1994897Sopenharmony_ci } 402b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 403b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::F32), std::move(items))); 404b1994897Sopenharmony_ci break; 405b1994897Sopenharmony_ci } 406b1994897Sopenharmony_ci case 'U': { 407b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 408b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 409b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 410b1994897Sopenharmony_ci ScalarValueItem scalar(array.Get<double>(j)); 411b1994897Sopenharmony_ci items.emplace_back(std::move(scalar)); 412b1994897Sopenharmony_ci } 413b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 414b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::F64), std::move(items))); 415b1994897Sopenharmony_ci break; 416b1994897Sopenharmony_ci } 417b1994897Sopenharmony_ci case 'V': { 418b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 419b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 420b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 421b1994897Sopenharmony_ci const File::EntityId str_id(array.Get<uint32_t>(j)); 422b1994897Sopenharmony_ci auto data = file_->GetStringData(str_id); 423b1994897Sopenharmony_ci std::string item_str(utf::Mutf8AsCString(data.data)); 424b1994897Sopenharmony_ci items.emplace_back(ScalarValueItem(container_.GetOrCreateStringItem(item_str))); 425b1994897Sopenharmony_ci } 426b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 427b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items))); 428b1994897Sopenharmony_ci break; 429b1994897Sopenharmony_ci } 430b1994897Sopenharmony_ci case 'W': { 431b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 432b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 433b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 434b1994897Sopenharmony_ci const File::EntityId class_id {array.Get<uint32_t>(j)}; 435b1994897Sopenharmony_ci BaseClassItem *cls_item = nullptr; 436b1994897Sopenharmony_ci if (file_->IsExternal(class_id)) { 437b1994897Sopenharmony_ci cls_item = CreateForeignClassItem(class_id); 438b1994897Sopenharmony_ci } else { 439b1994897Sopenharmony_ci cls_item = CreateClassItem(class_id); 440b1994897Sopenharmony_ci } 441b1994897Sopenharmony_ci ASSERT(cls_item != nullptr); 442b1994897Sopenharmony_ci items.emplace_back(ScalarValueItem(cls_item)); 443b1994897Sopenharmony_ci } 444b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 445b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items))); 446b1994897Sopenharmony_ci break; 447b1994897Sopenharmony_ci } 448b1994897Sopenharmony_ci case 'X': { 449b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 450b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 451b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 452b1994897Sopenharmony_ci const File::EntityId method_id {array.Get<uint32_t>(j)}; 453b1994897Sopenharmony_ci MethodDataAccessor method_acc(*file_, method_id); 454b1994897Sopenharmony_ci auto *cls_item = CreateGenericClassItem(method_acc.GetClassId()); 455b1994897Sopenharmony_ci items.emplace_back(ScalarValueItem(CreateGenericMethodItem(cls_item, method_id))); 456b1994897Sopenharmony_ci } 457b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 458b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items))); 459b1994897Sopenharmony_ci break; 460b1994897Sopenharmony_ci } 461b1994897Sopenharmony_ci case 'Y': { 462b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 463b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 464b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 465b1994897Sopenharmony_ci const File::EntityId field_id {array.Get<uint32_t>(j)}; 466b1994897Sopenharmony_ci FieldDataAccessor field_acc(*file_, field_id); 467b1994897Sopenharmony_ci auto *cls_item = CreateGenericClassItem(field_acc.GetClassId()); 468b1994897Sopenharmony_ci items.emplace_back(ScalarValueItem(CreateGenericFieldItem(cls_item, field_id))); 469b1994897Sopenharmony_ci } 470b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 471b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items))); 472b1994897Sopenharmony_ci break; 473b1994897Sopenharmony_ci } 474b1994897Sopenharmony_ci case 'H': { 475b1994897Sopenharmony_ci // ARRAY can appear for empty arrays only 476b1994897Sopenharmony_ci ASSERT(ann_elem.GetArrayValue().GetCount() == 0); 477b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 478b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::VOID), std::vector<ScalarValueItem>())); 479b1994897Sopenharmony_ci break; 480b1994897Sopenharmony_ci } 481b1994897Sopenharmony_ci case 'Z': { 482b1994897Sopenharmony_ci auto array = ann_elem.GetArrayValue(); 483b1994897Sopenharmony_ci std::vector<ScalarValueItem> items; 484b1994897Sopenharmony_ci for (size_t j = 0; j < array.GetCount(); j++) { 485b1994897Sopenharmony_ci const File::EntityId ann_item_id {array.Get<uint32_t>(j)}; 486b1994897Sopenharmony_ci items.emplace_back(CreateAnnotationItem(ann_item_id)); 487b1994897Sopenharmony_ci } 488b1994897Sopenharmony_ci elem_value_item = static_cast<ValueItem *>( 489b1994897Sopenharmony_ci container_.CreateItem<ArrayValueItem>(Type(Type::TypeId::REFERENCE), std::move(items))); 490b1994897Sopenharmony_ci break; 491b1994897Sopenharmony_ci } 492b1994897Sopenharmony_ci case '@': { 493b1994897Sopenharmony_ci // TODO(nsizov): support it 494b1994897Sopenharmony_ci LOG(FATAL, PANDAFILE) << "MethodHandle is not supported so far"; 495b1994897Sopenharmony_ci break; 496b1994897Sopenharmony_ci } 497b1994897Sopenharmony_ci // array 498b1994897Sopenharmony_ci case 'I': 499b1994897Sopenharmony_ci // VOID(I) and ARRAY(H) value should not appear 500b1994897Sopenharmony_ci default: 501b1994897Sopenharmony_ci UNREACHABLE(); 502b1994897Sopenharmony_ci } 503b1994897Sopenharmony_ci 504b1994897Sopenharmony_ci ASSERT(elem_value_item != nullptr); 505b1994897Sopenharmony_ci 506b1994897Sopenharmony_ci tag_elements.emplace_back(AnnotationItem::Tag(static_cast<char>(ann_tag.GetItem()))); 507b1994897Sopenharmony_ci File::EntityId name_id(ann_elem.GetNameId()); 508b1994897Sopenharmony_ci std::string annot_name_str(utf::Mutf8AsCString(file_->GetStringData(name_id).data)); 509b1994897Sopenharmony_ci auto elem_name_item = container_.GetOrCreateStringItem(annot_name_str); 510b1994897Sopenharmony_ci item_elements.emplace_back(AnnotationItem::Elem(elem_name_item, elem_value_item)); 511b1994897Sopenharmony_ci } 512b1994897Sopenharmony_ci 513b1994897Sopenharmony_ci ann_item->SetElements(std::move(item_elements)); 514b1994897Sopenharmony_ci ann_item->SetTags(std::move(tag_elements)); 515b1994897Sopenharmony_ci 516b1994897Sopenharmony_ci return ann_item; 517b1994897Sopenharmony_ci} 518b1994897Sopenharmony_ci 519b1994897Sopenharmony_ciTypeItem *FileReader::CreateParamTypeItem(ProtoDataAccessor *proto_acc, size_t param_num, size_t reference_num) 520b1994897Sopenharmony_ci{ 521b1994897Sopenharmony_ci Type param_type = proto_acc->GetArgType(param_num); 522b1994897Sopenharmony_ci TypeItem *param_type_item = nullptr; 523b1994897Sopenharmony_ci if (param_type.IsPrimitive()) { 524b1994897Sopenharmony_ci param_type_item = container_.GetOrCreatePrimitiveTypeItem(param_type); 525b1994897Sopenharmony_ci } else { 526b1994897Sopenharmony_ci const File::EntityId type_cls_id = proto_acc->GetReferenceType(reference_num); 527b1994897Sopenharmony_ci if (file_->IsExternal(type_cls_id)) { 528b1994897Sopenharmony_ci param_type_item = CreateForeignClassItem(type_cls_id); 529b1994897Sopenharmony_ci } else { 530b1994897Sopenharmony_ci param_type_item = CreateClassItem(type_cls_id); 531b1994897Sopenharmony_ci } 532b1994897Sopenharmony_ci } 533b1994897Sopenharmony_ci 534b1994897Sopenharmony_ci ASSERT(param_type_item != nullptr); 535b1994897Sopenharmony_ci 536b1994897Sopenharmony_ci return param_type_item; 537b1994897Sopenharmony_ci} 538b1994897Sopenharmony_ci 539b1994897Sopenharmony_cistd::vector<MethodParamItem> FileReader::CreateMethodParamItems(ProtoDataAccessor *proto_acc, 540b1994897Sopenharmony_ci MethodDataAccessor *method_acc, size_t reference_num) 541b1994897Sopenharmony_ci{ 542b1994897Sopenharmony_ci std::vector<MethodParamItem> param_items; 543b1994897Sopenharmony_ci 544b1994897Sopenharmony_ci for (size_t i = 0; i < proto_acc->GetNumArgs(); i++) { 545b1994897Sopenharmony_ci TypeItem *param_type_item = CreateParamTypeItem(proto_acc, i, reference_num); 546b1994897Sopenharmony_ci if (param_type_item->GetType().IsReference()) { 547b1994897Sopenharmony_ci reference_num++; 548b1994897Sopenharmony_ci } 549b1994897Sopenharmony_ci param_items.emplace_back(MethodParamItem(param_type_item)); 550b1994897Sopenharmony_ci } 551b1994897Sopenharmony_ci 552b1994897Sopenharmony_ci auto param_ann_id = method_acc->GetParamAnnotationId(); 553b1994897Sopenharmony_ci if (param_ann_id) { 554b1994897Sopenharmony_ci ParamAnnotationsDataAccessor param_acc(*file_, param_ann_id.value()); 555b1994897Sopenharmony_ci for (size_t i = 0; i < proto_acc->GetNumArgs(); i++) { 556b1994897Sopenharmony_ci ParamAnnotationsDataAccessor::AnnotationArray ann_arr = param_acc.GetAnnotationArray(i); 557b1994897Sopenharmony_ci ann_arr.EnumerateAnnotations([&](File::EntityId ann_id) { 558b1994897Sopenharmony_ci auto ann_item = CreateAnnotationItem(ann_id); 559b1994897Sopenharmony_ci param_items[i].AddAnnotation(ann_item); 560b1994897Sopenharmony_ci }); 561b1994897Sopenharmony_ci } 562b1994897Sopenharmony_ci } 563b1994897Sopenharmony_ci 564b1994897Sopenharmony_ci auto runtime_param_ann_id = method_acc->GetRuntimeParamAnnotationId(); 565b1994897Sopenharmony_ci if (runtime_param_ann_id) { 566b1994897Sopenharmony_ci ParamAnnotationsDataAccessor param_acc(*file_, runtime_param_ann_id.value()); 567b1994897Sopenharmony_ci for (size_t i = 0; i < proto_acc->GetNumArgs(); i++) { 568b1994897Sopenharmony_ci ParamAnnotationsDataAccessor::AnnotationArray ann_arr = param_acc.GetAnnotationArray(i); 569b1994897Sopenharmony_ci ann_arr.EnumerateAnnotations([&](File::EntityId ann_id) { 570b1994897Sopenharmony_ci auto ann_item = CreateAnnotationItem(ann_id); 571b1994897Sopenharmony_ci param_items[i].AddRuntimeAnnotation(ann_item); 572b1994897Sopenharmony_ci }); 573b1994897Sopenharmony_ci } 574b1994897Sopenharmony_ci } 575b1994897Sopenharmony_ci 576b1994897Sopenharmony_ci return param_items; 577b1994897Sopenharmony_ci} 578b1994897Sopenharmony_ci 579b1994897Sopenharmony_ciDebugInfoItem *FileReader::CreateDebugInfoItem(File::EntityId debug_info_id) 580b1994897Sopenharmony_ci{ 581b1994897Sopenharmony_ci auto it = items_done_.find(debug_info_id); 582b1994897Sopenharmony_ci if (it != items_done_.end()) { 583b1994897Sopenharmony_ci return static_cast<DebugInfoItem *>(it->second); 584b1994897Sopenharmony_ci } 585b1994897Sopenharmony_ci 586b1994897Sopenharmony_ci auto *lnp_item = container_.CreateLineNumberProgramItem(); 587b1994897Sopenharmony_ci auto *debug_info_item = container_.CreateItem<DebugInfoItem>(lnp_item); 588b1994897Sopenharmony_ci items_done_.insert({debug_info_id, static_cast<BaseItem *>(debug_info_item)}); 589b1994897Sopenharmony_ci 590b1994897Sopenharmony_ci DebugInfoDataAccessor debug_acc(*file_, debug_info_id); 591b1994897Sopenharmony_ci 592b1994897Sopenharmony_ci debug_info_item->SetLineNumber(debug_acc.GetLineStart()); 593b1994897Sopenharmony_ci debug_acc.EnumerateParameters([&](File::EntityId param_id) { 594b1994897Sopenharmony_ci auto data = file_->GetStringData(param_id); 595b1994897Sopenharmony_ci std::string item_str(utf::Mutf8AsCString(data.data)); 596b1994897Sopenharmony_ci auto *string_item = container_.GetOrCreateStringItem(item_str); 597b1994897Sopenharmony_ci debug_info_item->AddParameter(string_item); 598b1994897Sopenharmony_ci }); 599b1994897Sopenharmony_ci 600b1994897Sopenharmony_ci return debug_info_item; 601b1994897Sopenharmony_ci} 602b1994897Sopenharmony_ci 603b1994897Sopenharmony_ciTypeItem *FileReader::GetReturnTypeItem(Type ret_type, size_t &reference_num) 604b1994897Sopenharmony_ci{ 605b1994897Sopenharmony_ci TypeItem *ret_type_item = nullptr; 606b1994897Sopenharmony_ci if (ret_type.IsPrimitive()) { 607b1994897Sopenharmony_ci ret_type_item = container_.GetOrCreatePrimitiveTypeItem(ret_type); 608b1994897Sopenharmony_ci } else { 609b1994897Sopenharmony_ci const File::EntityId type_cls_id = proto_acc.GetReferenceType(reference_num); 610b1994897Sopenharmony_ci if (file_->IsExternal(type_cls_id)) { 611b1994897Sopenharmony_ci ret_type_item = CreateForeignClassItem(type_cls_id); 612b1994897Sopenharmony_ci } else { 613b1994897Sopenharmony_ci ret_type_item = CreateClassItem(type_cls_id); 614b1994897Sopenharmony_ci } 615b1994897Sopenharmony_ci reference_num++; 616b1994897Sopenharmony_ci } 617b1994897Sopenharmony_ci return ret_type_item; 618b1994897Sopenharmony_ci} 619b1994897Sopenharmony_ci 620b1994897Sopenharmony_civoid FileReader::EnumerateBlocks(MethodDataAccessor method_acc, MethodItem *method_item) 621b1994897Sopenharmony_ci{ 622b1994897Sopenharmony_ci // quick check 623b1994897Sopenharmony_ci auto code_id = method_acc.GetCodeId(); 624b1994897Sopenharmony_ci if (code_id == std::nullopt) { 625b1994897Sopenharmony_ci return; 626b1994897Sopenharmony_ci } 627b1994897Sopenharmony_ci 628b1994897Sopenharmony_ci CodeDataAccessor code_acc(*file_, code_id.value()); 629b1994897Sopenharmony_ci std::vector<uint8_t> instructions(code_acc.GetCodeSize()); 630b1994897Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 631b1994897Sopenharmony_ci instructions.assign(code_acc.GetInstructions(), code_acc.GetInstructions() + code_acc.GetCodeSize()); 632b1994897Sopenharmony_ci auto *code_item = 633b1994897Sopenharmony_ci container_.CreateItem<CodeItem>(code_acc.GetNumVregs(), code_acc.GetNumArgs(), std::move(instructions)); 634b1994897Sopenharmony_ci 635b1994897Sopenharmony_ci code_acc.EnumerateTryBlocks([&](CodeDataAccessor::TryBlock &try_block) { 636b1994897Sopenharmony_ci std::vector<CodeItem::CatchBlock> catch_blocks; 637b1994897Sopenharmony_ci try_block.EnumerateCatchBlocks([&](CodeDataAccessor::CatchBlock &catch_block) { 638b1994897Sopenharmony_ci BaseClassItem *catch_type_item = nullptr; 639b1994897Sopenharmony_ci auto type_idx = catch_block.GetTypeIdx(); 640b1994897Sopenharmony_ci if (type_idx != panda_file::INVALID_INDEX) { 641b1994897Sopenharmony_ci File::EntityId catch_cls_id = file_->ResolveClassIndex(method_id, catch_block.GetTypeIdx()); 642b1994897Sopenharmony_ci catch_type_item = (file_->IsExternal(catch_cls_id)) ? CreateForeignClassItem(catch_cls_id) : 643b1994897Sopenharmony_ci CreateClassItem(catch_cls_id); 644b1994897Sopenharmony_ci method_item->AddIndexDependency(catch_type_item); 645b1994897Sopenharmony_ci } 646b1994897Sopenharmony_ci // Add new CatchBlock 647b1994897Sopenharmony_ci catch_blocks.emplace_back(CodeItem::CatchBlock(method_item, catch_type_item, catch_block.GetHandlerPc(), 648b1994897Sopenharmony_ci catch_block.GetCodeSize())); 649b1994897Sopenharmony_ci return true; 650b1994897Sopenharmony_ci }); 651b1994897Sopenharmony_ci code_item->AddTryBlock( 652b1994897Sopenharmony_ci CodeItem::TryBlock(try_block.GetStartPc(), try_block.GetLength(), std::move(catch_blocks))); 653b1994897Sopenharmony_ci return true; 654b1994897Sopenharmony_ci }); 655b1994897Sopenharmony_ci 656b1994897Sopenharmony_ci method_item->SetCode(code_item); 657b1994897Sopenharmony_ci} 658b1994897Sopenharmony_ci 659b1994897Sopenharmony_ciMethodItem *FileReader::CreateMethodItem(ClassItem *cls, File::EntityId method_id) 660b1994897Sopenharmony_ci{ 661b1994897Sopenharmony_ci // Check if we have done this method 662b1994897Sopenharmony_ci auto it = items_done_.find(method_id); 663b1994897Sopenharmony_ci if (it != items_done_.end()) { 664b1994897Sopenharmony_ci return static_cast<MethodItem *>(it->second); 665b1994897Sopenharmony_ci } 666b1994897Sopenharmony_ci 667b1994897Sopenharmony_ci MethodDataAccessor method_acc(*file_, method_id); 668b1994897Sopenharmony_ci auto data = file_->GetStringData(method_acc.GetNameId()); 669b1994897Sopenharmony_ci std::string method_name(utf::Mutf8AsCString(data.data)); 670b1994897Sopenharmony_ci auto method_str_item = container_.GetOrCreateStringItem(method_name); 671b1994897Sopenharmony_ci 672b1994897Sopenharmony_ci ProtoDataAccessor proto_acc(*file_, method_acc.GetProtoId()); 673b1994897Sopenharmony_ci Type ret_type = proto_acc.GetReturnType(); 674b1994897Sopenharmony_ci size_t reference_num = 0; 675b1994897Sopenharmony_ci TypeItem *ret_type_item = GetReturnTypeItem(ret_type, reference_num); 676b1994897Sopenharmony_ci ASSERT(ret_type_item != nullptr); 677b1994897Sopenharmony_ci auto param_items = CreateMethodParamItems(&proto_acc, &method_acc, reference_num); 678b1994897Sopenharmony_ci 679b1994897Sopenharmony_ci // Double check if we have done this method while computing params 680b1994897Sopenharmony_ci auto it_check = items_done_.find(method_id); 681b1994897Sopenharmony_ci if (it_check != items_done_.end()) { 682b1994897Sopenharmony_ci return static_cast<MethodItem *>(it_check->second); 683b1994897Sopenharmony_ci } 684b1994897Sopenharmony_ci 685b1994897Sopenharmony_ci auto proto_item = container_.GetOrCreateProtoItem(ret_type_item, param_items); 686b1994897Sopenharmony_ci auto method_item = 687b1994897Sopenharmony_ci cls->AddMethod(method_str_item, proto_item, method_acc.GetAccessFlags(), std::move(param_items)); 688b1994897Sopenharmony_ci if (method_item->HasRuntimeParamAnnotations()) { 689b1994897Sopenharmony_ci container_.CreateItem<ParamAnnotationsItem>(method_item, true); 690b1994897Sopenharmony_ci } 691b1994897Sopenharmony_ci 692b1994897Sopenharmony_ci if (method_item->HasParamAnnotations()) { 693b1994897Sopenharmony_ci container_.CreateItem<ParamAnnotationsItem>(method_item, false); 694b1994897Sopenharmony_ci } 695b1994897Sopenharmony_ci items_done_.insert({method_id, static_cast<BaseItem *>(method_item)}); 696b1994897Sopenharmony_ci 697b1994897Sopenharmony_ci method_acc.EnumerateAnnotations( 698b1994897Sopenharmony_ci [&](File::EntityId ann_id) { method_item->AddAnnotation(CreateAnnotationItem(ann_id)); }); 699b1994897Sopenharmony_ci 700b1994897Sopenharmony_ci method_acc.EnumerateRuntimeAnnotations( 701b1994897Sopenharmony_ci [&](File::EntityId ann_id) { method_item->AddRuntimeAnnotation(CreateAnnotationItem(ann_id)); }); 702b1994897Sopenharmony_ci 703b1994897Sopenharmony_ci method_acc.EnumerateTypeAnnotations( 704b1994897Sopenharmony_ci [&](File::EntityId ann_id) { method_item->AddTypeAnnotation(CreateAnnotationItem(ann_id)); }); 705b1994897Sopenharmony_ci 706b1994897Sopenharmony_ci method_acc.EnumerateRuntimeTypeAnnotations( 707b1994897Sopenharmony_ci [&](File::EntityId ann_id) { method_item->AddRuntimeTypeAnnotation(CreateAnnotationItem(ann_id)); }); 708b1994897Sopenharmony_ci 709b1994897Sopenharmony_ci EnumerateBlocks(method_acc, method_item); 710b1994897Sopenharmony_ci 711b1994897Sopenharmony_ci auto debug_info_id = method_acc.GetDebugInfoId(); 712b1994897Sopenharmony_ci if (debug_info_id) { 713b1994897Sopenharmony_ci method_item->SetDebugInfo(CreateDebugInfoItem(debug_info_id.value())); 714b1994897Sopenharmony_ci } 715b1994897Sopenharmony_ci 716b1994897Sopenharmony_ci auto source_lang = method_acc.GetSourceLang(); 717b1994897Sopenharmony_ci if (source_lang) { 718b1994897Sopenharmony_ci method_item->SetSourceLang(source_lang.value()); 719b1994897Sopenharmony_ci } 720b1994897Sopenharmony_ci 721b1994897Sopenharmony_ci return method_item; 722b1994897Sopenharmony_ci} 723b1994897Sopenharmony_ci 724b1994897Sopenharmony_ciMethodHandleItem *FileReader::CreateMethodHandleItem(File::EntityId mh_id) 725b1994897Sopenharmony_ci{ 726b1994897Sopenharmony_ci (void)mh_id; 727b1994897Sopenharmony_ci ASSERT(false); 728b1994897Sopenharmony_ci return nullptr; // STUB 729b1994897Sopenharmony_ci} 730b1994897Sopenharmony_ci 731b1994897Sopenharmony_ciFieldItem *FileReader::CreateFieldItem(ClassItem *cls, File::EntityId field_id) 732b1994897Sopenharmony_ci{ 733b1994897Sopenharmony_ci auto it = items_done_.find(field_id); 734b1994897Sopenharmony_ci if (it != items_done_.end()) { 735b1994897Sopenharmony_ci return static_cast<FieldItem *>(it->second); 736b1994897Sopenharmony_ci } 737b1994897Sopenharmony_ci 738b1994897Sopenharmony_ci FieldDataAccessor field_acc(*file_, field_id); 739b1994897Sopenharmony_ci 740b1994897Sopenharmony_ci auto data = file_->GetStringData(field_acc.GetNameId()); 741b1994897Sopenharmony_ci std::string string_name(utf::Mutf8AsCString(data.data)); 742b1994897Sopenharmony_ci auto *field_name = container_.GetOrCreateStringItem(string_name); 743b1994897Sopenharmony_ci Type field_type = Type::GetTypeFromFieldEncoding(field_acc.GetType()); 744b1994897Sopenharmony_ci 745b1994897Sopenharmony_ci TypeItem *field_type_item = nullptr; 746b1994897Sopenharmony_ci if (field_type.IsReference()) { 747b1994897Sopenharmony_ci File::EntityId type_id(field_acc.GetType()); 748b1994897Sopenharmony_ci if (file_->IsExternal(type_id)) { 749b1994897Sopenharmony_ci field_type_item = CreateForeignClassItem(type_id); 750b1994897Sopenharmony_ci } else { 751b1994897Sopenharmony_ci field_type_item = CreateClassItem(type_id); 752b1994897Sopenharmony_ci // Double check if we done this field while generated class item 753b1994897Sopenharmony_ci auto it_check = items_done_.find(field_id); 754b1994897Sopenharmony_ci if (it_check != items_done_.end()) { 755b1994897Sopenharmony_ci return static_cast<FieldItem *>(it_check->second); 756b1994897Sopenharmony_ci } 757b1994897Sopenharmony_ci } 758b1994897Sopenharmony_ci } else { 759b1994897Sopenharmony_ci field_type_item = container_.GetOrCreatePrimitiveTypeItem(field_type.GetId()); 760b1994897Sopenharmony_ci } 761b1994897Sopenharmony_ci 762b1994897Sopenharmony_ci ASSERT(field_type_item != nullptr); 763b1994897Sopenharmony_ci 764b1994897Sopenharmony_ci FieldItem *field_item = cls->AddField(field_name, field_type_item, field_acc.GetAccessFlags()); 765b1994897Sopenharmony_ci items_done_.insert({field_id, static_cast<BaseItem *>(field_item)}); 766b1994897Sopenharmony_ci 767b1994897Sopenharmony_ci switch (field_type.GetId()) { 768b1994897Sopenharmony_ci case Type::TypeId::U1: 769b1994897Sopenharmony_ci case Type::TypeId::I8: 770b1994897Sopenharmony_ci case Type::TypeId::U8: 771b1994897Sopenharmony_ci SetIntegerFieldValue<uint8_t>(&field_acc, field_item); 772b1994897Sopenharmony_ci break; 773b1994897Sopenharmony_ci case Type::TypeId::I16: 774b1994897Sopenharmony_ci case Type::TypeId::U16: 775b1994897Sopenharmony_ci SetIntegerFieldValue<uint16_t>(&field_acc, field_item); 776b1994897Sopenharmony_ci break; 777b1994897Sopenharmony_ci case Type::TypeId::I32: 778b1994897Sopenharmony_ci case Type::TypeId::U32: 779b1994897Sopenharmony_ci SetIntegerFieldValue<uint32_t>(&field_acc, field_item); 780b1994897Sopenharmony_ci break; 781b1994897Sopenharmony_ci case Type::TypeId::I64: 782b1994897Sopenharmony_ci case Type::TypeId::U64: 783b1994897Sopenharmony_ci SetIntegerFieldValue<uint64_t>(&field_acc, field_item); 784b1994897Sopenharmony_ci break; 785b1994897Sopenharmony_ci case Type::TypeId::F32: 786b1994897Sopenharmony_ci SetFloatFieldValue<float>(&field_acc, field_item); 787b1994897Sopenharmony_ci break; 788b1994897Sopenharmony_ci case Type::TypeId::F64: 789b1994897Sopenharmony_ci SetFloatFieldValue<double>(&field_acc, field_item); 790b1994897Sopenharmony_ci break; 791b1994897Sopenharmony_ci case Type::TypeId::REFERENCE: 792b1994897Sopenharmony_ci SetStringFieldValue(&field_acc, field_item); 793b1994897Sopenharmony_ci break; 794b1994897Sopenharmony_ci case Type::TypeId::TAGGED: 795b1994897Sopenharmony_ci default: 796b1994897Sopenharmony_ci UNREACHABLE(); 797b1994897Sopenharmony_ci break; 798b1994897Sopenharmony_ci } 799b1994897Sopenharmony_ci 800b1994897Sopenharmony_ci field_acc.EnumerateAnnotations( 801b1994897Sopenharmony_ci [&](File::EntityId ann_id) { field_item->AddAnnotation(CreateAnnotationItem(ann_id)); }); 802b1994897Sopenharmony_ci 803b1994897Sopenharmony_ci field_acc.EnumerateRuntimeAnnotations( 804b1994897Sopenharmony_ci [&](File::EntityId ann_id) { field_item->AddRuntimeAnnotation(CreateAnnotationItem(ann_id)); }); 805b1994897Sopenharmony_ci 806b1994897Sopenharmony_ci field_acc.EnumerateRuntimeTypeAnnotations( 807b1994897Sopenharmony_ci [&](File::EntityId ann_id) { field_item->AddRuntimeTypeAnnotation(CreateAnnotationItem(ann_id)); }); 808b1994897Sopenharmony_ci 809b1994897Sopenharmony_ci field_acc.EnumerateTypeAnnotations( 810b1994897Sopenharmony_ci [&](File::EntityId ann_id) { field_item->AddTypeAnnotation(CreateAnnotationItem(ann_id)); }); 811b1994897Sopenharmony_ci 812b1994897Sopenharmony_ci return field_item; 813b1994897Sopenharmony_ci} 814b1994897Sopenharmony_ci 815b1994897Sopenharmony_ciForeignMethodItem *FileReader::CreateForeignMethodItem(BaseClassItem *fcls, File::EntityId method_id) 816b1994897Sopenharmony_ci{ 817b1994897Sopenharmony_ci auto it = items_done_.find(method_id); 818b1994897Sopenharmony_ci if (it != items_done_.end()) { 819b1994897Sopenharmony_ci return static_cast<ForeignMethodItem *>(it->second); 820b1994897Sopenharmony_ci } 821b1994897Sopenharmony_ci 822b1994897Sopenharmony_ci MethodDataAccessor method_acc(*file_, method_id); 823b1994897Sopenharmony_ci auto data = file_->GetStringData(method_acc.GetNameId()); 824b1994897Sopenharmony_ci std::string method_name(utf::Mutf8AsCString(data.data)); 825b1994897Sopenharmony_ci auto *method_str_item = container_.GetOrCreateStringItem(method_name); 826b1994897Sopenharmony_ci 827b1994897Sopenharmony_ci ProtoDataAccessor proto_acc(*file_, method_acc.GetProtoId()); 828b1994897Sopenharmony_ci Type ret_type = proto_acc.GetReturnType(); 829b1994897Sopenharmony_ci size_t reference_num = 0; 830b1994897Sopenharmony_ci TypeItem *ret_type_item = nullptr; 831b1994897Sopenharmony_ci if (ret_type.IsPrimitive()) { 832b1994897Sopenharmony_ci ret_type_item = container_.GetOrCreatePrimitiveTypeItem(ret_type); 833b1994897Sopenharmony_ci } else { 834b1994897Sopenharmony_ci const File::EntityId type_cls_id = proto_acc.GetReferenceType(reference_num); 835b1994897Sopenharmony_ci if (file_->IsExternal(type_cls_id)) { 836b1994897Sopenharmony_ci ret_type_item = CreateForeignClassItem(type_cls_id); 837b1994897Sopenharmony_ci } else { 838b1994897Sopenharmony_ci ret_type_item = CreateClassItem(type_cls_id); 839b1994897Sopenharmony_ci } 840b1994897Sopenharmony_ci reference_num++; 841b1994897Sopenharmony_ci } 842b1994897Sopenharmony_ci ASSERT(ret_type_item != nullptr); 843b1994897Sopenharmony_ci auto param_items = CreateMethodParamItems(&proto_acc, &method_acc, reference_num); 844b1994897Sopenharmony_ci // Double check if we done this method while computing params 845b1994897Sopenharmony_ci auto it_check = items_done_.find(method_id); 846b1994897Sopenharmony_ci if (it_check != items_done_.end()) { 847b1994897Sopenharmony_ci return static_cast<ForeignMethodItem *>(it_check->second); 848b1994897Sopenharmony_ci } 849b1994897Sopenharmony_ci auto *proto_item = container_.GetOrCreateProtoItem(ret_type_item, param_items); 850b1994897Sopenharmony_ci 851b1994897Sopenharmony_ci auto *method_item = 852b1994897Sopenharmony_ci container_.CreateItem<ForeignMethodItem>(fcls, method_str_item, proto_item, method_acc.GetAccessFlags()); 853b1994897Sopenharmony_ci 854b1994897Sopenharmony_ci items_done_.insert({method_id, static_cast<BaseItem *>(method_item)}); 855b1994897Sopenharmony_ci 856b1994897Sopenharmony_ci return method_item; 857b1994897Sopenharmony_ci} 858b1994897Sopenharmony_ci 859b1994897Sopenharmony_ciForeignFieldItem *FileReader::CreateForeignFieldItem(BaseClassItem *fcls, File::EntityId field_id) 860b1994897Sopenharmony_ci{ 861b1994897Sopenharmony_ci auto it = items_done_.find(field_id); 862b1994897Sopenharmony_ci if (it != items_done_.end()) { 863b1994897Sopenharmony_ci return static_cast<ForeignFieldItem *>(it->second); 864b1994897Sopenharmony_ci } 865b1994897Sopenharmony_ci 866b1994897Sopenharmony_ci FieldDataAccessor field_acc(*file_, field_id); 867b1994897Sopenharmony_ci 868b1994897Sopenharmony_ci auto data = file_->GetStringData(field_acc.GetNameId()); 869b1994897Sopenharmony_ci std::string string_name(utf::Mutf8AsCString(data.data)); 870b1994897Sopenharmony_ci auto *field_name = container_.GetOrCreateStringItem(string_name); 871b1994897Sopenharmony_ci Type field_type = Type::GetTypeFromFieldEncoding(field_acc.GetType()); 872b1994897Sopenharmony_ci TypeItem *field_type_item = nullptr; 873b1994897Sopenharmony_ci if (field_type.IsReference()) { 874b1994897Sopenharmony_ci File::EntityId type_id(field_acc.GetType()); 875b1994897Sopenharmony_ci if (file_->IsExternal(type_id)) { 876b1994897Sopenharmony_ci field_type_item = CreateForeignClassItem(type_id); 877b1994897Sopenharmony_ci } else { 878b1994897Sopenharmony_ci field_type_item = CreateClassItem(type_id); 879b1994897Sopenharmony_ci // Double check if we done this field while generated class item 880b1994897Sopenharmony_ci auto it_check = items_done_.find(field_id); 881b1994897Sopenharmony_ci if (it_check != items_done_.end()) { 882b1994897Sopenharmony_ci return static_cast<ForeignFieldItem *>(it_check->second); 883b1994897Sopenharmony_ci } 884b1994897Sopenharmony_ci } 885b1994897Sopenharmony_ci } else { 886b1994897Sopenharmony_ci field_type_item = container_.GetOrCreatePrimitiveTypeItem(field_type.GetId()); 887b1994897Sopenharmony_ci } 888b1994897Sopenharmony_ci 889b1994897Sopenharmony_ci ASSERT(field_type_item != nullptr); 890b1994897Sopenharmony_ci 891b1994897Sopenharmony_ci auto *field_item = container_.CreateItem<ForeignFieldItem>(fcls, field_name, field_type_item); 892b1994897Sopenharmony_ci items_done_.insert({field_id, static_cast<BaseItem *>(field_item)}); 893b1994897Sopenharmony_ci 894b1994897Sopenharmony_ci return field_item; 895b1994897Sopenharmony_ci} 896b1994897Sopenharmony_ci 897b1994897Sopenharmony_ciForeignClassItem *FileReader::CreateForeignClassItem(File::EntityId class_id) 898b1994897Sopenharmony_ci{ 899b1994897Sopenharmony_ci auto it = items_done_.find(class_id); 900b1994897Sopenharmony_ci if (it != items_done_.end()) { 901b1994897Sopenharmony_ci return static_cast<ForeignClassItem *>(it->second); 902b1994897Sopenharmony_ci } 903b1994897Sopenharmony_ci 904b1994897Sopenharmony_ci std::string class_name(utf::Mutf8AsCString(file_->GetStringData(class_id).data)); 905b1994897Sopenharmony_ci auto *class_item = container_.GetOrCreateForeignClassItem(class_name); 906b1994897Sopenharmony_ci 907b1994897Sopenharmony_ci items_done_.insert({class_id, static_cast<BaseItem *>(class_item)}); 908b1994897Sopenharmony_ci 909b1994897Sopenharmony_ci return class_item; 910b1994897Sopenharmony_ci} 911b1994897Sopenharmony_ci 912b1994897Sopenharmony_civoid FileReader::CreateSuperClassItem(ClassDataAccessor& class_acc, 913b1994897Sopenharmony_ci ClassItem* class_item, 914b1994897Sopenharmony_ci const std::string& class_name) 915b1994897Sopenharmony_ci{ 916b1994897Sopenharmony_ci auto super_class_id = class_acc.GetSuperClassId(); 917b1994897Sopenharmony_ci if (super_class_id.GetOffset() != 0) { 918b1994897Sopenharmony_ci if (super_class_id.GetOffset() == class_id.GetOffset()) { 919b1994897Sopenharmony_ci LOG(FATAL, PANDAFILE) << "Class " << class_name << " has cyclic inheritance"; 920b1994897Sopenharmony_ci } 921b1994897Sopenharmony_ci 922b1994897Sopenharmony_ci if (file_->IsExternal(super_class_id)) { 923b1994897Sopenharmony_ci auto *super_class_item = CreateForeignClassItem(super_class_id); 924b1994897Sopenharmony_ci class_item->SetSuperClass(super_class_item); 925b1994897Sopenharmony_ci } else { 926b1994897Sopenharmony_ci auto *super_class_item = CreateClassItem(super_class_id); 927b1994897Sopenharmony_ci class_item->SetSuperClass(super_class_item); 928b1994897Sopenharmony_ci } 929b1994897Sopenharmony_ci } 930b1994897Sopenharmony_ci} 931b1994897Sopenharmony_ci 932b1994897Sopenharmony_ciClassItem *FileReader::CreateClassItem(File::EntityId class_id) 933b1994897Sopenharmony_ci{ 934b1994897Sopenharmony_ci auto it = items_done_.find(class_id); 935b1994897Sopenharmony_ci if (it != items_done_.end()) { 936b1994897Sopenharmony_ci return static_cast<ClassItem *>(it->second); 937b1994897Sopenharmony_ci } 938b1994897Sopenharmony_ci ClassDataAccessor class_acc(*file_, class_id); 939b1994897Sopenharmony_ci 940b1994897Sopenharmony_ci std::string class_name(utf::Mutf8AsCString(file_->GetStringData(class_id).data)); 941b1994897Sopenharmony_ci auto *class_item = container_.GetOrCreateClassItem(class_name); 942b1994897Sopenharmony_ci 943b1994897Sopenharmony_ci items_done_.insert({class_id, static_cast<BaseItem *>(class_item)}); 944b1994897Sopenharmony_ci 945b1994897Sopenharmony_ci class_item->SetAccessFlags(class_acc.GetAccessFlags()); 946b1994897Sopenharmony_ci 947b1994897Sopenharmony_ci auto source_lang_opt = class_acc.GetSourceLang(); 948b1994897Sopenharmony_ci if (source_lang_opt) { 949b1994897Sopenharmony_ci class_item->SetSourceLang(source_lang_opt.value()); 950b1994897Sopenharmony_ci } 951b1994897Sopenharmony_ci 952b1994897Sopenharmony_ci CreateSuperClassItem(class_acc, class_item, class_name); 953b1994897Sopenharmony_ci 954b1994897Sopenharmony_ci class_acc.EnumerateInterfaces([&](File::EntityId iface_id) { 955b1994897Sopenharmony_ci if (file_->IsExternal(iface_id)) { 956b1994897Sopenharmony_ci class_item->AddInterface(CreateForeignClassItem(iface_id)); 957b1994897Sopenharmony_ci } else { 958b1994897Sopenharmony_ci class_item->AddInterface(CreateClassItem(iface_id)); 959b1994897Sopenharmony_ci } 960b1994897Sopenharmony_ci }); 961b1994897Sopenharmony_ci 962b1994897Sopenharmony_ci class_acc.EnumerateAnnotations( 963b1994897Sopenharmony_ci [&](File::EntityId ann_id) { class_item->AddAnnotation(CreateAnnotationItem(ann_id)); }); 964b1994897Sopenharmony_ci 965b1994897Sopenharmony_ci class_acc.EnumerateRuntimeAnnotations( 966b1994897Sopenharmony_ci [&](File::EntityId ann_id) { class_item->AddRuntimeAnnotation(CreateAnnotationItem(ann_id)); }); 967b1994897Sopenharmony_ci 968b1994897Sopenharmony_ci class_acc.EnumerateTypeAnnotations( 969b1994897Sopenharmony_ci [&](File::EntityId ann_id) { class_item->AddTypeAnnotation(CreateAnnotationItem(ann_id)); }); 970b1994897Sopenharmony_ci 971b1994897Sopenharmony_ci class_acc.EnumerateFields( 972b1994897Sopenharmony_ci [&](FieldDataAccessor &field_acc) { CreateFieldItem(class_item, field_acc.GetFieldId()); }); 973b1994897Sopenharmony_ci 974b1994897Sopenharmony_ci class_acc.EnumerateMethods( 975b1994897Sopenharmony_ci [&](MethodDataAccessor &method_acc) { CreateMethodItem(class_item, method_acc.GetMethodId()); }); 976b1994897Sopenharmony_ci 977b1994897Sopenharmony_ci auto source_file_id = class_acc.GetSourceFileId(); 978b1994897Sopenharmony_ci if (source_file_id) { 979b1994897Sopenharmony_ci std::string source_file = utf::Mutf8AsCString(file_->GetStringData(source_file_id.value()).data); 980b1994897Sopenharmony_ci class_item->SetSourceFile(container_.GetOrCreateStringItem(source_file)); 981b1994897Sopenharmony_ci } 982b1994897Sopenharmony_ci 983b1994897Sopenharmony_ci ASSERT(class_item != nullptr); 984b1994897Sopenharmony_ci 985b1994897Sopenharmony_ci return class_item; 986b1994897Sopenharmony_ci} 987b1994897Sopenharmony_ci 988b1994897Sopenharmony_cibool FileReader::ReadLiteralArrayItems() 989b1994897Sopenharmony_ci{ 990b1994897Sopenharmony_ci const auto lit_arrays_id = file_->GetLiteralArraysId(); 991b1994897Sopenharmony_ci LiteralDataAccessor lit_array_accessor(*file_, lit_arrays_id); 992b1994897Sopenharmony_ci size_t num_litarrays = lit_array_accessor.GetLiteralNum(); 993b1994897Sopenharmony_ci 994b1994897Sopenharmony_ci for (size_t i = 0; i < num_litarrays; i++) { 995b1994897Sopenharmony_ci auto id = lit_array_accessor.GetLiteralArrayId(i); 996b1994897Sopenharmony_ci lit_array_accessor.EnumerateLiteralVals( 997b1994897Sopenharmony_ci id, [id, this](const panda_file::LiteralDataAccessor::LiteralValue &value, 998b1994897Sopenharmony_ci const panda_file::LiteralTag &tag) { CreateLiteralArrayItem(value, tag, id); }); 999b1994897Sopenharmony_ci } 1000b1994897Sopenharmony_ci 1001b1994897Sopenharmony_ci return true; 1002b1994897Sopenharmony_ci} 1003b1994897Sopenharmony_ci 1004b1994897Sopenharmony_cibool FileReader::ReadIndexHeaders() 1005b1994897Sopenharmony_ci{ 1006b1994897Sopenharmony_ci auto index_headers = file_->GetIndexHeaders(); 1007b1994897Sopenharmony_ci for (const auto &header : index_headers) { 1008b1994897Sopenharmony_ci auto method_index = file_->GetMethodIndex(&header); 1009b1994897Sopenharmony_ci for (auto method_id : method_index) { 1010b1994897Sopenharmony_ci MethodDataAccessor method_acc(*file_, method_id); 1011b1994897Sopenharmony_ci File::EntityId class_id(method_acc.GetClassId()); 1012b1994897Sopenharmony_ci if (file_->IsExternal(class_id)) { 1013b1994897Sopenharmony_ci auto *fclass_item = CreateForeignClassItem(class_id); 1014b1994897Sopenharmony_ci ASSERT(file_->IsExternal(method_id)); 1015b1994897Sopenharmony_ci if (CreateForeignMethodItem(fclass_item, method_id) == nullptr) { 1016b1994897Sopenharmony_ci return false; 1017b1994897Sopenharmony_ci } 1018b1994897Sopenharmony_ci } else { 1019b1994897Sopenharmony_ci auto *class_item = CreateClassItem(class_id); 1020b1994897Sopenharmony_ci if (file_->IsExternal(method_id)) { 1021b1994897Sopenharmony_ci if (CreateForeignMethodItem(class_item, method_id) == nullptr) { 1022b1994897Sopenharmony_ci return false; 1023b1994897Sopenharmony_ci } 1024b1994897Sopenharmony_ci } else if (CreateMethodItem(class_item, method_id) == nullptr) { 1025b1994897Sopenharmony_ci return false; 1026b1994897Sopenharmony_ci } 1027b1994897Sopenharmony_ci } 1028b1994897Sopenharmony_ci } 1029b1994897Sopenharmony_ci auto field_index = file_->GetFieldIndex(&header); 1030b1994897Sopenharmony_ci for (auto field_id : field_index) { 1031b1994897Sopenharmony_ci FieldDataAccessor field_acc(*file_, field_id); 1032b1994897Sopenharmony_ci File::EntityId class_id(field_acc.GetClassId()); 1033b1994897Sopenharmony_ci if (file_->IsExternal(class_id)) { 1034b1994897Sopenharmony_ci ASSERT(file_->IsExternal(field_id)); 1035b1994897Sopenharmony_ci auto *fclass_item = CreateForeignClassItem(field_acc.GetClassId()); 1036b1994897Sopenharmony_ci if (CreateForeignFieldItem(fclass_item, field_id) == nullptr) { 1037b1994897Sopenharmony_ci return false; 1038b1994897Sopenharmony_ci } 1039b1994897Sopenharmony_ci } else { 1040b1994897Sopenharmony_ci auto *class_item = CreateClassItem(field_acc.GetClassId()); 1041b1994897Sopenharmony_ci if (file_->IsExternal(field_id)) { 1042b1994897Sopenharmony_ci if (CreateForeignFieldItem(class_item, field_id) == nullptr) { 1043b1994897Sopenharmony_ci return false; 1044b1994897Sopenharmony_ci } 1045b1994897Sopenharmony_ci } else if (CreateFieldItem(class_item, field_id) == nullptr) { 1046b1994897Sopenharmony_ci return false; 1047b1994897Sopenharmony_ci } 1048b1994897Sopenharmony_ci } 1049b1994897Sopenharmony_ci } 1050b1994897Sopenharmony_ci } 1051b1994897Sopenharmony_ci return true; 1052b1994897Sopenharmony_ci} 1053b1994897Sopenharmony_ci 1054b1994897Sopenharmony_cibool FileReader::ReadClasses() 1055b1994897Sopenharmony_ci{ 1056b1994897Sopenharmony_ci const auto class_idx = file_->GetClasses(); 1057b1994897Sopenharmony_ci 1058b1994897Sopenharmony_ci for (unsigned int id : class_idx) { 1059b1994897Sopenharmony_ci File::EntityId eid(id); 1060b1994897Sopenharmony_ci if (file_->IsExternal(eid)) { 1061b1994897Sopenharmony_ci CreateForeignClassItem(eid); 1062b1994897Sopenharmony_ci } else { 1063b1994897Sopenharmony_ci CreateClassItem(eid); 1064b1994897Sopenharmony_ci } 1065b1994897Sopenharmony_ci } 1066b1994897Sopenharmony_ci 1067b1994897Sopenharmony_ci return true; 1068b1994897Sopenharmony_ci} 1069b1994897Sopenharmony_ci 1070b1994897Sopenharmony_civoid FileReader::UpdateDebugInfoDependecies(File::EntityId debug_info_id) 1071b1994897Sopenharmony_ci{ 1072b1994897Sopenharmony_ci DebugInfoDataAccessor debug_acc(*file_, debug_info_id); 1073b1994897Sopenharmony_ci const uint8_t *program = debug_acc.GetLineNumberProgram(); 1074b1994897Sopenharmony_ci auto size = file_->GetSpanFromId(file_->GetIdFromPointer(program)).size(); 1075b1994897Sopenharmony_ci auto opcode_sp = Span(program, size); 1076b1994897Sopenharmony_ci 1077b1994897Sopenharmony_ci size_t i = 0; 1078b1994897Sopenharmony_ci LineNumberProgramItem::Opcode opcode; 1079b1994897Sopenharmony_ci panda_file::LineProgramState state(*file_, File::EntityId(0), debug_acc.GetLineStart(), 1080b1994897Sopenharmony_ci debug_acc.GetConstantPool()); 1081b1994897Sopenharmony_ci while ((opcode = LineNumberProgramItem::Opcode(opcode_sp[i++])) != LineNumberProgramItem::Opcode::END_SEQUENCE) { 1082b1994897Sopenharmony_ci switch (opcode) { 1083b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::ADVANCE_PC: 1084b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::ADVANCE_LINE: 1085b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::SET_PROLOGUE_END: 1086b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::SET_EPILOGUE_BEGIN: { 1087b1994897Sopenharmony_ci break; 1088b1994897Sopenharmony_ci } 1089b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::START_LOCAL: { 1090b1994897Sopenharmony_ci [[maybe_unused]] int32_t reg_number; 1091b1994897Sopenharmony_ci size_t n; 1092b1994897Sopenharmony_ci bool is_full; 1093b1994897Sopenharmony_ci std::tie(reg_number, n, is_full) = leb128::DecodeSigned<int32_t>(&opcode_sp[i]); 1094b1994897Sopenharmony_ci LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number"; 1095b1994897Sopenharmony_ci i += n; 1096b1994897Sopenharmony_ci 1097b1994897Sopenharmony_ci auto name_id = File::EntityId(state.ReadULeb128()); 1098b1994897Sopenharmony_ci std::string name = utf::Mutf8AsCString(file_->GetStringData(name_id).data); 1099b1994897Sopenharmony_ci container_.GetOrCreateStringItem(name); 1100b1994897Sopenharmony_ci 1101b1994897Sopenharmony_ci auto type_id = File::EntityId(state.ReadULeb128()); 1102b1994897Sopenharmony_ci std::string type_name = utf::Mutf8AsCString(file_->GetStringData(type_id).data); 1103b1994897Sopenharmony_ci if (file_->IsExternal(type_id)) { 1104b1994897Sopenharmony_ci container_.GetOrCreateForeignClassItem(type_name); 1105b1994897Sopenharmony_ci } else { 1106b1994897Sopenharmony_ci container_.GetOrCreateClassItem(type_name); 1107b1994897Sopenharmony_ci } 1108b1994897Sopenharmony_ci break; 1109b1994897Sopenharmony_ci } 1110b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::START_LOCAL_EXTENDED: { 1111b1994897Sopenharmony_ci [[maybe_unused]] int32_t reg_number; 1112b1994897Sopenharmony_ci size_t n; 1113b1994897Sopenharmony_ci bool is_full; 1114b1994897Sopenharmony_ci std::tie(reg_number, n, is_full) = leb128::DecodeSigned<int32_t>(&opcode_sp[i]); 1115b1994897Sopenharmony_ci LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number"; 1116b1994897Sopenharmony_ci i += n; 1117b1994897Sopenharmony_ci 1118b1994897Sopenharmony_ci auto name_id = File::EntityId(state.ReadULeb128()); 1119b1994897Sopenharmony_ci std::string name = utf::Mutf8AsCString(file_->GetStringData(name_id).data); 1120b1994897Sopenharmony_ci container_.GetOrCreateStringItem(name); 1121b1994897Sopenharmony_ci 1122b1994897Sopenharmony_ci auto type_id = File::EntityId(state.ReadULeb128()); 1123b1994897Sopenharmony_ci std::string type_name = utf::Mutf8AsCString(file_->GetStringData(type_id).data); 1124b1994897Sopenharmony_ci if (file_->IsExternal(type_id)) { 1125b1994897Sopenharmony_ci container_.GetOrCreateForeignClassItem(type_name); 1126b1994897Sopenharmony_ci } else { 1127b1994897Sopenharmony_ci container_.GetOrCreateClassItem(type_name); 1128b1994897Sopenharmony_ci } 1129b1994897Sopenharmony_ci 1130b1994897Sopenharmony_ci auto type_signature_id = File::EntityId(state.ReadULeb128()); 1131b1994897Sopenharmony_ci std::string type_signature = utf::Mutf8AsCString(file_->GetStringData(type_signature_id).data); 1132b1994897Sopenharmony_ci container_.GetOrCreateStringItem(type_signature); 1133b1994897Sopenharmony_ci break; 1134b1994897Sopenharmony_ci } 1135b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::END_LOCAL: 1136b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::RESTART_LOCAL: { 1137b1994897Sopenharmony_ci [[maybe_unused]] int32_t reg_number; 1138b1994897Sopenharmony_ci size_t n; 1139b1994897Sopenharmony_ci bool is_full; 1140b1994897Sopenharmony_ci std::tie(reg_number, n, is_full) = leb128::DecodeSigned<int32_t>(&opcode_sp[i]); 1141b1994897Sopenharmony_ci LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number"; 1142b1994897Sopenharmony_ci i += n; 1143b1994897Sopenharmony_ci break; 1144b1994897Sopenharmony_ci } 1145b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::SET_FILE: { 1146b1994897Sopenharmony_ci auto source_file_id = File::EntityId(state.ReadULeb128()); 1147b1994897Sopenharmony_ci std::string source_file = utf::Mutf8AsCString(file_->GetStringData(source_file_id).data); 1148b1994897Sopenharmony_ci container_.GetOrCreateStringItem(source_file); 1149b1994897Sopenharmony_ci break; 1150b1994897Sopenharmony_ci } 1151b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::SET_SOURCE_CODE: { 1152b1994897Sopenharmony_ci auto source_code_id = File::EntityId(state.ReadULeb128()); 1153b1994897Sopenharmony_ci std::string source_code = utf::Mutf8AsCString(file_->GetStringData(source_code_id).data); 1154b1994897Sopenharmony_ci container_.GetOrCreateStringItem(source_code); 1155b1994897Sopenharmony_ci break; 1156b1994897Sopenharmony_ci } 1157b1994897Sopenharmony_ci default: { 1158b1994897Sopenharmony_ci break; 1159b1994897Sopenharmony_ci } 1160b1994897Sopenharmony_ci } 1161b1994897Sopenharmony_ci } 1162b1994897Sopenharmony_ci} 1163b1994897Sopenharmony_ci 1164b1994897Sopenharmony_civoid FileReader::UpdateDebugInfo(DebugInfoItem *debug_info_item, File::EntityId debug_info_id) 1165b1994897Sopenharmony_ci{ 1166b1994897Sopenharmony_ci auto *lnp_item = debug_info_item->GetLineNumberProgram(); 1167b1994897Sopenharmony_ci DebugInfoDataAccessor debug_acc(*file_, debug_info_id); 1168b1994897Sopenharmony_ci const uint8_t *program = debug_acc.GetLineNumberProgram(); 1169b1994897Sopenharmony_ci auto size = file_->GetSpanFromId(file_->GetIdFromPointer(program)).size(); 1170b1994897Sopenharmony_ci auto opcode_sp = Span(program, size); 1171b1994897Sopenharmony_ci 1172b1994897Sopenharmony_ci size_t i = 0; 1173b1994897Sopenharmony_ci LineNumberProgramItem::Opcode opcode; 1174b1994897Sopenharmony_ci panda_file::LineProgramState state(*file_, File::EntityId(0), debug_acc.GetLineStart(), 1175b1994897Sopenharmony_ci debug_acc.GetConstantPool()); 1176b1994897Sopenharmony_ci while ((opcode = LineNumberProgramItem::Opcode(opcode_sp[i++])) != LineNumberProgramItem::Opcode::END_SEQUENCE) { 1177b1994897Sopenharmony_ci switch (opcode) { 1178b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::ADVANCE_PC: { 1179b1994897Sopenharmony_ci lnp_item->EmitAdvancePc(debug_info_item->GetConstantPool(), state.ReadULeb128()); 1180b1994897Sopenharmony_ci break; 1181b1994897Sopenharmony_ci } 1182b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::ADVANCE_LINE: { 1183b1994897Sopenharmony_ci lnp_item->EmitAdvanceLine(debug_info_item->GetConstantPool(), state.ReadSLeb128()); 1184b1994897Sopenharmony_ci break; 1185b1994897Sopenharmony_ci } 1186b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::START_LOCAL: { 1187b1994897Sopenharmony_ci auto [reg_number, n, is_full] = leb128::DecodeSigned<int32_t>(&opcode_sp[i]); 1188b1994897Sopenharmony_ci LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number"; 1189b1994897Sopenharmony_ci i += n; 1190b1994897Sopenharmony_ci 1191b1994897Sopenharmony_ci auto name_id = File::EntityId(state.ReadULeb128()); 1192b1994897Sopenharmony_ci std::string name = utf::Mutf8AsCString(file_->GetStringData(name_id).data); 1193b1994897Sopenharmony_ci auto *name_item = container_.GetOrCreateStringItem(name); 1194b1994897Sopenharmony_ci 1195b1994897Sopenharmony_ci auto type_id = File::EntityId(state.ReadULeb128()); 1196b1994897Sopenharmony_ci std::string type_name = utf::Mutf8AsCString(file_->GetStringData(type_id).data); 1197b1994897Sopenharmony_ci auto *type_item = file_->IsExternal(type_id) 1198b1994897Sopenharmony_ci ? static_cast<BaseClassItem *>(container_.GetOrCreateForeignClassItem(type_name)) 1199b1994897Sopenharmony_ci : static_cast<BaseClassItem *>(container_.GetOrCreateClassItem(type_name)); 1200b1994897Sopenharmony_ci 1201b1994897Sopenharmony_ci lnp_item->EmitStartLocal(debug_info_item->GetConstantPool(), reg_number, name_item, 1202b1994897Sopenharmony_ci type_item->GetNameItem()); 1203b1994897Sopenharmony_ci break; 1204b1994897Sopenharmony_ci } 1205b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::START_LOCAL_EXTENDED: { 1206b1994897Sopenharmony_ci auto [reg_number, n, is_full] = leb128::DecodeSigned<int32_t>(&opcode_sp[i]); 1207b1994897Sopenharmony_ci LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number"; 1208b1994897Sopenharmony_ci i += n; 1209b1994897Sopenharmony_ci 1210b1994897Sopenharmony_ci auto name_id = File::EntityId(state.ReadULeb128()); 1211b1994897Sopenharmony_ci std::string name = utf::Mutf8AsCString(file_->GetStringData(name_id).data); 1212b1994897Sopenharmony_ci auto *name_item = container_.GetOrCreateStringItem(name); 1213b1994897Sopenharmony_ci 1214b1994897Sopenharmony_ci auto type_id = File::EntityId(state.ReadULeb128()); 1215b1994897Sopenharmony_ci std::string type_name = utf::Mutf8AsCString(file_->GetStringData(type_id).data); 1216b1994897Sopenharmony_ci auto *type_item = file_->IsExternal(type_id) 1217b1994897Sopenharmony_ci ? static_cast<BaseClassItem *>(container_.GetOrCreateForeignClassItem(type_name)) 1218b1994897Sopenharmony_ci : static_cast<BaseClassItem *>(container_.GetOrCreateClassItem(type_name)); 1219b1994897Sopenharmony_ci 1220b1994897Sopenharmony_ci auto type_signature_id = File::EntityId(state.ReadULeb128()); 1221b1994897Sopenharmony_ci std::string type_signature = utf::Mutf8AsCString(file_->GetStringData(type_signature_id).data); 1222b1994897Sopenharmony_ci auto *type_signature_item = container_.GetOrCreateStringItem(type_signature); 1223b1994897Sopenharmony_ci 1224b1994897Sopenharmony_ci lnp_item->EmitStartLocalExtended(debug_info_item->GetConstantPool(), reg_number, name_item, 1225b1994897Sopenharmony_ci type_item->GetNameItem(), type_signature_item); 1226b1994897Sopenharmony_ci break; 1227b1994897Sopenharmony_ci } 1228b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::END_LOCAL: { 1229b1994897Sopenharmony_ci auto [reg_number, n, is_full] = leb128::DecodeSigned<int32_t>(&opcode_sp[i]); 1230b1994897Sopenharmony_ci LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number"; 1231b1994897Sopenharmony_ci i += n; 1232b1994897Sopenharmony_ci 1233b1994897Sopenharmony_ci lnp_item->EmitEndLocal(reg_number); 1234b1994897Sopenharmony_ci break; 1235b1994897Sopenharmony_ci } 1236b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::RESTART_LOCAL: { 1237b1994897Sopenharmony_ci auto [reg_number, n, is_full] = leb128::DecodeSigned<int32_t>(&opcode_sp[i]); 1238b1994897Sopenharmony_ci LOG_IF(!is_full, FATAL, COMMON) << "Cannot read a register number"; 1239b1994897Sopenharmony_ci i += n; 1240b1994897Sopenharmony_ci 1241b1994897Sopenharmony_ci lnp_item->EmitRestartLocal(reg_number); 1242b1994897Sopenharmony_ci break; 1243b1994897Sopenharmony_ci } 1244b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::SET_PROLOGUE_END: { 1245b1994897Sopenharmony_ci lnp_item->EmitPrologEnd(); 1246b1994897Sopenharmony_ci break; 1247b1994897Sopenharmony_ci } 1248b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::SET_EPILOGUE_BEGIN: { 1249b1994897Sopenharmony_ci lnp_item->EmitEpilogBegin(); 1250b1994897Sopenharmony_ci break; 1251b1994897Sopenharmony_ci } 1252b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::SET_FILE: { 1253b1994897Sopenharmony_ci auto source_file_id = File::EntityId(state.ReadULeb128()); 1254b1994897Sopenharmony_ci std::string source_file = utf::Mutf8AsCString(file_->GetStringData(source_file_id).data); 1255b1994897Sopenharmony_ci auto *source_file_item = container_.GetOrCreateStringItem(source_file); 1256b1994897Sopenharmony_ci lnp_item->EmitSetFile(debug_info_item->GetConstantPool(), source_file_item); 1257b1994897Sopenharmony_ci break; 1258b1994897Sopenharmony_ci } 1259b1994897Sopenharmony_ci case LineNumberProgramItem::Opcode::SET_SOURCE_CODE: { 1260b1994897Sopenharmony_ci auto source_code_id = File::EntityId(state.ReadULeb128()); 1261b1994897Sopenharmony_ci std::string source_code = utf::Mutf8AsCString(file_->GetStringData(source_code_id).data); 1262b1994897Sopenharmony_ci auto *source_code_item = container_.GetOrCreateStringItem(source_code); 1263b1994897Sopenharmony_ci lnp_item->EmitSetFile(debug_info_item->GetConstantPool(), source_code_item); 1264b1994897Sopenharmony_ci break; 1265b1994897Sopenharmony_ci } 1266b1994897Sopenharmony_ci default: { 1267b1994897Sopenharmony_ci auto opcode_value = static_cast<uint8_t>(opcode); 1268b1994897Sopenharmony_ci auto adjust_opcode = opcode_value - LineNumberProgramItem::OPCODE_BASE; 1269b1994897Sopenharmony_ci uint32_t pc_diff = adjust_opcode / LineNumberProgramItem::LINE_RANGE; 1270b1994897Sopenharmony_ci int32_t line_diff = 1271b1994897Sopenharmony_ci adjust_opcode % LineNumberProgramItem::LINE_RANGE + LineNumberProgramItem::LINE_BASE; 1272b1994897Sopenharmony_ci lnp_item->EmitSpecialOpcode(pc_diff, line_diff); 1273b1994897Sopenharmony_ci break; 1274b1994897Sopenharmony_ci } 1275b1994897Sopenharmony_ci } 1276b1994897Sopenharmony_ci } 1277b1994897Sopenharmony_ci lnp_item->EmitEnd(); 1278b1994897Sopenharmony_ci} 1279b1994897Sopenharmony_ci 1280b1994897Sopenharmony_civoid AddIndexDependencyInstFlag(CodeItem *code_item, MethodItem *method_item, 1281b1994897Sopenharmony_ci const std::unordered_map<File::EntityId, File::EntityId> &reverse_done) 1282b1994897Sopenharmony_ci{ 1283b1994897Sopenharmony_ci using Flags = panda::BytecodeInst<panda::BytecodeInstMode::FAST>::Flags; 1284b1994897Sopenharmony_ci 1285b1994897Sopenharmony_ci size_t offset = 0; 1286b1994897Sopenharmony_ci BytecodeInstruction inst(code_item->GetInstructions()->data()); 1287b1994897Sopenharmony_ci while (offset < code_item->GetCodeSize()) { 1288b1994897Sopenharmony_ci if (inst.HasFlag(Flags::TYPE_ID)) { 1289b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1290b1994897Sopenharmony_ci File::Index idx = b_id.AsIndex(); 1291b1994897Sopenharmony_ci File::EntityId method_id = reverse_done.find(method_item)->second; 1292b1994897Sopenharmony_ci File::EntityId old_id = file_->ResolveClassIndex(method_id, idx); 1293b1994897Sopenharmony_ci ASSERT(items_done_.find(old_id) != items_done_.end()); 1294b1994897Sopenharmony_ci auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second); 1295b1994897Sopenharmony_ci method_item->AddIndexDependency(idx_item); 1296b1994897Sopenharmony_ci } else if (inst.HasFlag(Flags::METHOD_ID)) { 1297b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1298b1994897Sopenharmony_ci File::Index idx = b_id.AsIndex(); 1299b1994897Sopenharmony_ci File::EntityId method_id = reverse_done.find(method_item)->second; 1300b1994897Sopenharmony_ci File::EntityId old_id = file_->ResolveMethodIndex(method_id, idx); 1301b1994897Sopenharmony_ci ASSERT(items_done_.find(old_id) != items_done_.end()); 1302b1994897Sopenharmony_ci auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second); 1303b1994897Sopenharmony_ci method_item->AddIndexDependency(idx_item); 1304b1994897Sopenharmony_ci } else if (inst.HasFlag(Flags::FIELD_ID)) { 1305b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1306b1994897Sopenharmony_ci File::Index idx = b_id.AsIndex(); 1307b1994897Sopenharmony_ci File::EntityId method_id = reverse_done.find(method_item)->second; 1308b1994897Sopenharmony_ci File::EntityId old_id = file_->ResolveFieldIndex(method_id, idx); 1309b1994897Sopenharmony_ci ASSERT(items_done_.find(old_id) != items_done_.end()); 1310b1994897Sopenharmony_ci auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second); 1311b1994897Sopenharmony_ci method_item->AddIndexDependency(idx_item); 1312b1994897Sopenharmony_ci } else if (inst.HasFlag(Flags::STRING_ID)) { 1313b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1314b1994897Sopenharmony_ci File::EntityId old_id = b_id.AsFileId(); 1315b1994897Sopenharmony_ci auto data = file_->GetStringData(old_id); 1316b1994897Sopenharmony_ci std::string item_str(utf::Mutf8AsCString(data.data)); 1317b1994897Sopenharmony_ci container_.GetOrCreateStringItem(item_str); 1318b1994897Sopenharmony_ci } 1319b1994897Sopenharmony_ci offset += inst.GetSize(); 1320b1994897Sopenharmony_ci inst = inst.GetNext(); 1321b1994897Sopenharmony_ci } 1322b1994897Sopenharmony_ci} 1323b1994897Sopenharmony_ci 1324b1994897Sopenharmony_civoid FileReader::UpdateCodeAndDebugInfoDependencies(const std::map<BaseItem *, File::EntityId> &reverse_done) 1325b1994897Sopenharmony_ci{ 1326b1994897Sopenharmony_ci auto *class_map = container_.GetClassMap(); 1327b1994897Sopenharmony_ci 1328b1994897Sopenharmony_ci // First pass, add dependencies bytecode -> new items 1329b1994897Sopenharmony_ci for (const auto &it : *class_map) { 1330b1994897Sopenharmony_ci auto *base_class_item = it.second; 1331b1994897Sopenharmony_ci if (base_class_item->IsForeign()) { 1332b1994897Sopenharmony_ci continue; 1333b1994897Sopenharmony_ci } 1334b1994897Sopenharmony_ci auto *class_item = static_cast<ClassItem *>(base_class_item); 1335b1994897Sopenharmony_ci class_item->VisitMethods([this, &reverse_done](BaseItem *param_item) { 1336b1994897Sopenharmony_ci auto *method_item = static_cast<MethodItem *>(param_item); 1337b1994897Sopenharmony_ci auto *code_item = method_item->GetCode(); 1338b1994897Sopenharmony_ci if (code_item == nullptr) { 1339b1994897Sopenharmony_ci return true; 1340b1994897Sopenharmony_ci } 1341b1994897Sopenharmony_ci 1342b1994897Sopenharmony_ci auto *debug_info_item = method_item->GetDebugInfo(); 1343b1994897Sopenharmony_ci if (debug_info_item != nullptr) { 1344b1994897Sopenharmony_ci UpdateDebugInfoDependecies(reverse_done.find(debug_info_item)->second); 1345b1994897Sopenharmony_ci } 1346b1994897Sopenharmony_ci 1347b1994897Sopenharmony_ci AddIndexDependencyInstFlag(inst, method_item, reverse_done); 1348b1994897Sopenharmony_ci 1349b1994897Sopenharmony_ci return true; 1350b1994897Sopenharmony_ci }); 1351b1994897Sopenharmony_ci } 1352b1994897Sopenharmony_ci} 1353b1994897Sopenharmony_ci 1354b1994897Sopenharmony_civoid UpdateIdInstFlag(CodeItem *code_item, MethodItem *method_item, 1355b1994897Sopenharmony_ci const std::unordered_map<File::EntityId, File::EntityId> &reverse_done) 1356b1994897Sopenharmony_ci{ 1357b1994897Sopenharmony_ci using Flags = panda::BytecodeInst<panda::BytecodeInstMode::FAST>::Flags; 1358b1994897Sopenharmony_ci 1359b1994897Sopenharmony_ci size_t offset = 0; 1360b1994897Sopenharmony_ci BytecodeInstruction inst(code_item->GetInstructions()->data()); 1361b1994897Sopenharmony_ci while (offset < code_item->GetCodeSize()) { 1362b1994897Sopenharmony_ci if (inst.HasFlag(Flags::TYPE_ID)) { 1363b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1364b1994897Sopenharmony_ci File::Index idx = b_id.AsIndex(); 1365b1994897Sopenharmony_ci File::EntityId method_id = reverse_done.find(method_item)->second; 1366b1994897Sopenharmony_ci File::EntityId old_id = file_->ResolveClassIndex(method_id, idx); 1367b1994897Sopenharmony_ci ASSERT(items_done_.find(old_id) != items_done_.end()); 1368b1994897Sopenharmony_ci auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second); 1369b1994897Sopenharmony_ci uint32_t index = idx_item->GetIndex(method_item); 1370b1994897Sopenharmony_ci inst.UpdateId(BytecodeId(index)); 1371b1994897Sopenharmony_ci } else if (inst.HasFlag(Flags::METHOD_ID)) { 1372b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1373b1994897Sopenharmony_ci File::Index idx = b_id.AsIndex(); 1374b1994897Sopenharmony_ci File::EntityId method_id = reverse_done.find(method_item)->second; 1375b1994897Sopenharmony_ci File::EntityId old_id = file_->ResolveMethodIndex(method_id, idx); 1376b1994897Sopenharmony_ci ASSERT(items_done_.find(old_id) != items_done_.end()); 1377b1994897Sopenharmony_ci auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second); 1378b1994897Sopenharmony_ci uint32_t index = idx_item->GetIndex(method_item); 1379b1994897Sopenharmony_ci inst.UpdateId(BytecodeId(index)); 1380b1994897Sopenharmony_ci } else if (inst.HasFlag(Flags::FIELD_ID)) { 1381b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1382b1994897Sopenharmony_ci File::Index idx = b_id.AsIndex(); 1383b1994897Sopenharmony_ci File::EntityId method_id = reverse_done.find(method_item)->second; 1384b1994897Sopenharmony_ci File::EntityId old_id = file_->ResolveFieldIndex(method_id, idx); 1385b1994897Sopenharmony_ci ASSERT(items_done_.find(old_id) != items_done_.end()); 1386b1994897Sopenharmony_ci auto *idx_item = static_cast<IndexedItem *>(items_done_.find(old_id)->second); 1387b1994897Sopenharmony_ci uint32_t index = idx_item->GetIndex(method_item); 1388b1994897Sopenharmony_ci inst.UpdateId(BytecodeId(index)); 1389b1994897Sopenharmony_ci } else if (inst.HasFlag(Flags::STRING_ID)) { 1390b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1391b1994897Sopenharmony_ci File::EntityId old_id = b_id.AsFileId(); 1392b1994897Sopenharmony_ci auto data = file_->GetStringData(old_id); 1393b1994897Sopenharmony_ci std::string item_str(utf::Mutf8AsCString(data.data)); 1394b1994897Sopenharmony_ci auto *string_item = container_.GetOrCreateStringItem(item_str); 1395b1994897Sopenharmony_ci inst.UpdateId(BytecodeId(string_item->GetFileId().GetOffset())); 1396b1994897Sopenharmony_ci } else if (inst.HasFlag(Flags::LITERALARRAY_ID)) { 1397b1994897Sopenharmony_ci BytecodeId b_id = inst.GetId(); 1398b1994897Sopenharmony_ci File::EntityId old_id = b_id.AsFileId(); 1399b1994897Sopenharmony_ci ASSERT(items_done_.find(old_id) != items_done_.end()); 1400b1994897Sopenharmony_ci auto *array_item = items_done_.find(old_id)->second; 1401b1994897Sopenharmony_ci inst.UpdateId(BytecodeId(array_item->GetFileId().GetOffset())); 1402b1994897Sopenharmony_ci } 1403b1994897Sopenharmony_ci offset += inst.GetSize(); 1404b1994897Sopenharmony_ci inst = inst.GetNext(); 1405b1994897Sopenharmony_ci } 1406b1994897Sopenharmony_ci} 1407b1994897Sopenharmony_ci 1408b1994897Sopenharmony_civoid FileReader::ComputeLayoutAndUpdateIndices() 1409b1994897Sopenharmony_ci{ 1410b1994897Sopenharmony_ci std::map<BaseItem *, File::EntityId> reverse_done; 1411b1994897Sopenharmony_ci for (const auto &it : items_done_) { 1412b1994897Sopenharmony_ci reverse_done.insert({it.second, it.first}); 1413b1994897Sopenharmony_ci } 1414b1994897Sopenharmony_ci 1415b1994897Sopenharmony_ci auto *class_map = container_.GetClassMap(); 1416b1994897Sopenharmony_ci 1417b1994897Sopenharmony_ci UpdateCodeAndDebugInfoDependencies(reverse_done); 1418b1994897Sopenharmony_ci 1419b1994897Sopenharmony_ci container_.ComputeLayout(); 1420b1994897Sopenharmony_ci 1421b1994897Sopenharmony_ci // Second pass, update debug info 1422b1994897Sopenharmony_ci for (const auto &it : *class_map) { 1423b1994897Sopenharmony_ci auto *base_class_item = it.second; 1424b1994897Sopenharmony_ci if (base_class_item->IsForeign()) { 1425b1994897Sopenharmony_ci continue; 1426b1994897Sopenharmony_ci } 1427b1994897Sopenharmony_ci auto *class_item = static_cast<ClassItem *>(base_class_item); 1428b1994897Sopenharmony_ci class_item->VisitMethods([this, &reverse_done](BaseItem *param_item) { 1429b1994897Sopenharmony_ci auto *method_item = static_cast<MethodItem *>(param_item); 1430b1994897Sopenharmony_ci auto *code_item = method_item->GetCode(); 1431b1994897Sopenharmony_ci if (code_item == nullptr) { 1432b1994897Sopenharmony_ci return true; 1433b1994897Sopenharmony_ci } 1434b1994897Sopenharmony_ci 1435b1994897Sopenharmony_ci auto *debug_info_item = method_item->GetDebugInfo(); 1436b1994897Sopenharmony_ci if (debug_info_item != nullptr) { 1437b1994897Sopenharmony_ci UpdateDebugInfo(debug_info_item, reverse_done.find(debug_info_item)->second); 1438b1994897Sopenharmony_ci } 1439b1994897Sopenharmony_ci 1440b1994897Sopenharmony_ci return true; 1441b1994897Sopenharmony_ci }); 1442b1994897Sopenharmony_ci } 1443b1994897Sopenharmony_ci 1444b1994897Sopenharmony_ci container_.DeduplicateItems(false); 1445b1994897Sopenharmony_ci container_.ComputeLayout(); 1446b1994897Sopenharmony_ci 1447b1994897Sopenharmony_ci // Third pass, update bytecode indices 1448b1994897Sopenharmony_ci for (const auto &it : *class_map) { 1449b1994897Sopenharmony_ci auto *base_class_item = it.second; 1450b1994897Sopenharmony_ci if (base_class_item->IsForeign()) { 1451b1994897Sopenharmony_ci continue; 1452b1994897Sopenharmony_ci } 1453b1994897Sopenharmony_ci auto *class_item = static_cast<ClassItem *>(base_class_item); 1454b1994897Sopenharmony_ci class_item->VisitMethods([this, &reverse_done](BaseItem *param_item) { 1455b1994897Sopenharmony_ci auto *method_item = static_cast<MethodItem *>(param_item); 1456b1994897Sopenharmony_ci auto *code_item = method_item->GetCode(); 1457b1994897Sopenharmony_ci if (code_item == nullptr) { 1458b1994897Sopenharmony_ci return true; 1459b1994897Sopenharmony_ci } 1460b1994897Sopenharmony_ci 1461b1994897Sopenharmony_ci UpdateIdInstFlag(code_item, method_item, reverse_done); 1462b1994897Sopenharmony_ci 1463b1994897Sopenharmony_ci return true; 1464b1994897Sopenharmony_ci }); 1465b1994897Sopenharmony_ci } 1466b1994897Sopenharmony_ci} 1467b1994897Sopenharmony_ci 1468b1994897Sopenharmony_ci} // namespace panda::panda_file 1469