1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "abc2program_compiler.h" 17#include "abc_class_processor.h" 18#include "file_format_version.h" 19#include "utils/timers.h" 20 21namespace panda::abc2program { 22 23Abc2ProgramCompiler::~Abc2ProgramCompiler() 24{ 25 if (prog_ != nullptr) { 26 delete prog_; 27 prog_ = nullptr; 28 } 29} 30 31bool Abc2ProgramCompiler::OpenAbcFile(const std::string &file_path) 32{ 33 file_ = panda_file::File::Open(file_path); 34 if (file_ == nullptr) { 35 return false; 36 } 37 debug_info_extractor_ = std::make_unique<panda_file::DebugInfoExtractor>(file_.get()); 38 return true; 39} 40 41bool Abc2ProgramCompiler::CheckFileVersionIsSupported(std::array<uint8_t, panda_file::File::VERSION_SIZE> min_version, 42 uint8_t target_api_version, 43 std::string target_api_sub_version) const 44{ 45 auto target_version = panda_file::GetVersionByApi(target_api_version, target_api_sub_version); 46 if (!target_version.has_value()) { 47 return false; 48 } 49 const auto &file_version = file_->GetHeader()->version; 50 return panda::panda_file::IsVersionLessOrEqual(min_version, file_version) && 51 panda::panda_file::IsVersionLessOrEqual(file_version, target_version.value()); 52} 53 54const panda_file::File &Abc2ProgramCompiler::GetAbcFile() const 55{ 56 return *file_; 57} 58 59const panda_file::DebugInfoExtractor &Abc2ProgramCompiler::GetDebugInfoExtractor() const 60{ 61 return *debug_info_extractor_; 62} 63 64pandasm::Program *Abc2ProgramCompiler::CompileAbcFile() 65{ 66 prog_ = new pandasm::Program(); 67 prog_->lang = LANG_ECMA; 68 auto classes = file_->GetClasses(); 69 std::string record_name = ""; 70 for (size_t i = 0; i < classes.size(); i++) { 71 panda_file::File::EntityId record_id(classes[i]); 72 CompileAbcClass(record_id, *prog_, record_name); 73 } 74 return prog_; 75} 76 77void Abc2ProgramCompiler::CompileAbcClass(const panda_file::File::EntityId &record_id, 78 pandasm::Program &program, std::string &record_name) 79{ 80 Abc2ProgramEntityContainer entity_container(*file_, program, *debug_info_extractor_, record_id.GetOffset()); 81 record_name = entity_container.GetFullRecordNameById(record_id); 82 panda::Timer::timerStart(EVENT_COMPILE_ABC_FILE_RECORD, record_name); 83 AbcClassProcessor class_processor(record_id, entity_container); 84 class_processor.FillProgramData(); 85 panda::Timer::timerEnd(EVENT_COMPILE_ABC_FILE_RECORD, record_name); 86} 87 88bool Abc2ProgramCompiler::CheckClassId(uint32_t class_id, size_t offset) const 89{ 90 auto *header = file_->GetHeader(); 91 auto class_off = header->class_idx_off + sizeof(uint32_t) * offset; 92 if (class_id > header->file_size) { 93 LOG(FATAL, ABC2PROGRAM) << "> error encountered in record at " << class_off << " (0x" << std::hex 94 << class_off << "). binary file corrupted. record offset (0x" << class_id 95 << ") out of bounds (0x" << header->file_size << ")!"; 96 } 97 return !file_->IsExternal(panda_file::File::EntityId(class_id)); 98} 99 100} // namespace panda::abc2program 101