• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
20 namespace panda::abc2program {
21 
~Abc2ProgramCompiler()22 Abc2ProgramCompiler::~Abc2ProgramCompiler()
23 {
24     if (prog_ != nullptr) {
25         delete prog_;
26         prog_ = nullptr;
27     }
28 }
29 
OpenAbcFile(const std::string & file_path)30 bool Abc2ProgramCompiler::OpenAbcFile(const std::string &file_path)
31 {
32     file_ = panda_file::File::Open(file_path);
33     if (file_ == nullptr) {
34         return false;
35     }
36     debug_info_extractor_ = std::make_unique<panda_file::DebugInfoExtractor>(file_.get());
37     return true;
38 }
39 
IsVersionLessEqual(const std::array<uint8_t,panda_file::File::VERSION_SIZE> & version_1,const std::array<uint8_t,panda_file::File::VERSION_SIZE> & version_2) const40 bool Abc2ProgramCompiler::IsVersionLessEqual(
41     const std::array<uint8_t, panda_file::File::VERSION_SIZE> &version_1,
42     const std::array<uint8_t, panda_file::File::VERSION_SIZE> &version_2) const
43 {
44     for (size_t i = 0; i < panda_file::File::VERSION_SIZE; ++i) {
45         if (version_1[i] != version_2[i]) {
46             return version_1[i] < version_2[i];
47         }
48     }
49     return true;
50 }
51 
CheckFileVersionIsSupported(std::array<uint8_t,panda_file::File::VERSION_SIZE> min_version,uint8_t target_api_version,std::string target_api_sub_version) const52 bool Abc2ProgramCompiler::CheckFileVersionIsSupported(std::array<uint8_t, panda_file::File::VERSION_SIZE> min_version,
53                                                       uint8_t target_api_version,
54                                                       std::string target_api_sub_version) const
55 {
56     auto target_version = panda_file::GetVersionByApi(target_api_version, target_api_sub_version);
57     if (!target_version.has_value()) {
58         return false;
59     }
60     const auto &file_version = file_->GetHeader()->version;
61     return IsVersionLessEqual(min_version, file_version) &&
62         IsVersionLessEqual(file_version, target_version.value());
63 }
64 
GetAbcFile() const65 const panda_file::File &Abc2ProgramCompiler::GetAbcFile() const
66 {
67     return *file_;
68 }
69 
GetDebugInfoExtractor() const70 const panda_file::DebugInfoExtractor &Abc2ProgramCompiler::GetDebugInfoExtractor() const
71 {
72     return *debug_info_extractor_;
73 }
74 
CompileAbcFile()75 pandasm::Program *Abc2ProgramCompiler::CompileAbcFile()
76 {
77     prog_ = new pandasm::Program();
78     prog_->lang = LANG_ECMA;
79     auto classes = file_->GetClasses();
80     for (size_t i = 0; i < classes.size(); i++) {
81         panda_file::File::EntityId record_id(classes[i]);
82         if (file_->IsExternal(record_id)) {
83             UNREACHABLE();
84         }
85         CompileAbcClass(record_id, *prog_);
86     }
87     return prog_;
88 }
89 
CompileAbcClass(const panda_file::File::EntityId & record_id,pandasm::Program & program)90 void Abc2ProgramCompiler::CompileAbcClass(const panda_file::File::EntityId &record_id,
91                                           pandasm::Program &program)
92 {
93     ASSERT(!file_->IsExternal(record_id));
94     Abc2ProgramEntityContainer entity_container(*file_, program, *debug_info_extractor_, record_id.GetOffset());
95     AbcClassProcessor class_processor(record_id, entity_container);
96     class_processor.FillProgramData();
97 }
98 
CheckClassId(uint32_t class_id,size_t offset) const99 bool Abc2ProgramCompiler::CheckClassId(uint32_t class_id, size_t offset) const
100 {
101     auto *header = file_->GetHeader();
102     auto class_off = header->class_idx_off + sizeof(uint32_t) * offset;
103     if (class_id > header->file_size) {
104         LOG(FATAL, ABC2PROGRAM) << "> error encountered in record at " << class_off << " (0x" << std::hex
105                                 << class_off << "). binary file corrupted. record offset (0x" << class_id
106                                 << ") out of bounds (0x" << header->file_size << ")!";
107     }
108     return !file_->IsExternal(panda_file::File::EntityId(class_id));
109 }
110 
111 } // namespace panda::abc2program
112