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