1b1994897Sopenharmony_ci/* 2b1994897Sopenharmony_ci * Copyright (c) 2024 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 "abc2program_compiler.h" 17b1994897Sopenharmony_ci#include "abc_class_processor.h" 18b1994897Sopenharmony_ci#include "file_format_version.h" 19b1994897Sopenharmony_ci#include "utils/timers.h" 20b1994897Sopenharmony_ci 21b1994897Sopenharmony_cinamespace panda::abc2program { 22b1994897Sopenharmony_ci 23b1994897Sopenharmony_ciAbc2ProgramCompiler::~Abc2ProgramCompiler() 24b1994897Sopenharmony_ci{ 25b1994897Sopenharmony_ci if (prog_ != nullptr) { 26b1994897Sopenharmony_ci delete prog_; 27b1994897Sopenharmony_ci prog_ = nullptr; 28b1994897Sopenharmony_ci } 29b1994897Sopenharmony_ci} 30b1994897Sopenharmony_ci 31b1994897Sopenharmony_cibool Abc2ProgramCompiler::OpenAbcFile(const std::string &file_path) 32b1994897Sopenharmony_ci{ 33b1994897Sopenharmony_ci file_ = panda_file::File::Open(file_path); 34b1994897Sopenharmony_ci if (file_ == nullptr) { 35b1994897Sopenharmony_ci return false; 36b1994897Sopenharmony_ci } 37b1994897Sopenharmony_ci debug_info_extractor_ = std::make_unique<panda_file::DebugInfoExtractor>(file_.get()); 38b1994897Sopenharmony_ci return true; 39b1994897Sopenharmony_ci} 40b1994897Sopenharmony_ci 41b1994897Sopenharmony_cibool Abc2ProgramCompiler::CheckFileVersionIsSupported(std::array<uint8_t, panda_file::File::VERSION_SIZE> min_version, 42b1994897Sopenharmony_ci uint8_t target_api_version, 43b1994897Sopenharmony_ci std::string target_api_sub_version) const 44b1994897Sopenharmony_ci{ 45b1994897Sopenharmony_ci auto target_version = panda_file::GetVersionByApi(target_api_version, target_api_sub_version); 46b1994897Sopenharmony_ci if (!target_version.has_value()) { 47b1994897Sopenharmony_ci return false; 48b1994897Sopenharmony_ci } 49b1994897Sopenharmony_ci const auto &file_version = file_->GetHeader()->version; 50b1994897Sopenharmony_ci return panda::panda_file::IsVersionLessOrEqual(min_version, file_version) && 51b1994897Sopenharmony_ci panda::panda_file::IsVersionLessOrEqual(file_version, target_version.value()); 52b1994897Sopenharmony_ci} 53b1994897Sopenharmony_ci 54b1994897Sopenharmony_ciconst panda_file::File &Abc2ProgramCompiler::GetAbcFile() const 55b1994897Sopenharmony_ci{ 56b1994897Sopenharmony_ci return *file_; 57b1994897Sopenharmony_ci} 58b1994897Sopenharmony_ci 59b1994897Sopenharmony_ciconst panda_file::DebugInfoExtractor &Abc2ProgramCompiler::GetDebugInfoExtractor() const 60b1994897Sopenharmony_ci{ 61b1994897Sopenharmony_ci return *debug_info_extractor_; 62b1994897Sopenharmony_ci} 63b1994897Sopenharmony_ci 64b1994897Sopenharmony_cipandasm::Program *Abc2ProgramCompiler::CompileAbcFile() 65b1994897Sopenharmony_ci{ 66b1994897Sopenharmony_ci prog_ = new pandasm::Program(); 67b1994897Sopenharmony_ci prog_->lang = LANG_ECMA; 68b1994897Sopenharmony_ci auto classes = file_->GetClasses(); 69b1994897Sopenharmony_ci std::string record_name = ""; 70b1994897Sopenharmony_ci for (size_t i = 0; i < classes.size(); i++) { 71b1994897Sopenharmony_ci panda_file::File::EntityId record_id(classes[i]); 72b1994897Sopenharmony_ci CompileAbcClass(record_id, *prog_, record_name); 73b1994897Sopenharmony_ci } 74b1994897Sopenharmony_ci return prog_; 75b1994897Sopenharmony_ci} 76b1994897Sopenharmony_ci 77b1994897Sopenharmony_civoid Abc2ProgramCompiler::CompileAbcClass(const panda_file::File::EntityId &record_id, 78b1994897Sopenharmony_ci pandasm::Program &program, std::string &record_name) 79b1994897Sopenharmony_ci{ 80b1994897Sopenharmony_ci Abc2ProgramEntityContainer entity_container(*file_, program, *debug_info_extractor_, record_id.GetOffset()); 81b1994897Sopenharmony_ci record_name = entity_container.GetFullRecordNameById(record_id); 82b1994897Sopenharmony_ci panda::Timer::timerStart(EVENT_COMPILE_ABC_FILE_RECORD, record_name); 83b1994897Sopenharmony_ci AbcClassProcessor class_processor(record_id, entity_container); 84b1994897Sopenharmony_ci class_processor.FillProgramData(); 85b1994897Sopenharmony_ci panda::Timer::timerEnd(EVENT_COMPILE_ABC_FILE_RECORD, record_name); 86b1994897Sopenharmony_ci} 87b1994897Sopenharmony_ci 88b1994897Sopenharmony_cibool Abc2ProgramCompiler::CheckClassId(uint32_t class_id, size_t offset) const 89b1994897Sopenharmony_ci{ 90b1994897Sopenharmony_ci auto *header = file_->GetHeader(); 91b1994897Sopenharmony_ci auto class_off = header->class_idx_off + sizeof(uint32_t) * offset; 92b1994897Sopenharmony_ci if (class_id > header->file_size) { 93b1994897Sopenharmony_ci LOG(FATAL, ABC2PROGRAM) << "> error encountered in record at " << class_off << " (0x" << std::hex 94b1994897Sopenharmony_ci << class_off << "). binary file corrupted. record offset (0x" << class_id 95b1994897Sopenharmony_ci << ") out of bounds (0x" << header->file_size << ")!"; 96b1994897Sopenharmony_ci } 97b1994897Sopenharmony_ci return !file_->IsExternal(panda_file::File::EntityId(class_id)); 98b1994897Sopenharmony_ci} 99b1994897Sopenharmony_ci 100b1994897Sopenharmony_ci} // namespace panda::abc2program 101