1/**
2 * Copyright (c) 2021-2022 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#ifndef BYTECODE_OPTIMIZER_IR_INTERFACE_H
17#define BYTECODE_OPTIMIZER_IR_INTERFACE_H
18
19#include <string>
20
21#include "assembler/assembly-emitter.h"
22#include "libpandafile/method_data_accessor-inl.h"
23#include "compiler/optimizer/ir/constants.h"
24
25namespace panda::bytecodeopt {
26class BytecodeOptIrInterface {
27public:
28    explicit BytecodeOptIrInterface(const pandasm::AsmEmitter::PandaFileToPandaAsmMaps *maps,
29                                    pandasm::Program *prog = nullptr)
30        : prog_(prog), maps_(maps)
31    {
32    }
33
34    virtual ~BytecodeOptIrInterface() = default;
35
36    virtual std::string GetMethodIdByOffset(uint32_t offset) const
37    {
38        auto it = maps_->methods.find(offset);
39        ASSERT(it != maps_->methods.cend());
40
41        return std::string(it->second);
42    }
43
44    virtual std::string GetStringIdByOffset(uint32_t offset) const
45    {
46        auto it = maps_->strings.find(offset);
47        ASSERT(it != maps_->strings.cend());
48
49        return std::string(it->second);
50    }
51
52    virtual std::string GetLiteralArrayByOffset(uint32_t offset) const
53    {
54        auto it = maps_->literalarrays.find(offset);
55        ASSERT(it != maps_->strings.cend());
56
57        return std::string(it->second);
58    }
59
60    std::optional<std::string> GetLiteralArrayIdByOffset(uint32_t offset) const
61    {
62        ASSERT(prog_ != nullptr);
63        if (prog_ == nullptr) {
64            return std::nullopt;
65        }
66        auto id = std::to_string(offset);
67        auto it = prog_->literalarray_table.find(id);
68        ASSERT(it != prog_->literalarray_table.end());
69        return it != prog_->literalarray_table.end() ? std::optional<std::string>(id) : std::nullopt;
70    }
71
72    virtual std::string GetTypeIdByOffset(uint32_t offset) const
73    {
74        auto it = maps_->classes.find(offset);
75        ASSERT(it != maps_->classes.cend());
76
77        return std::string(it->second);
78    }
79
80    virtual std::string GetFieldIdByOffset(uint32_t offset) const
81    {
82        auto it = maps_->fields.find(offset);
83        ASSERT(it != maps_->fields.cend());
84
85        return std::string(it->second);
86    }
87
88    std::unordered_map<size_t, pandasm::Ins *> *GetPcInsMap()
89    {
90        return &pc_ins_map_;
91    }
92
93    size_t GetLineNumberByPc(size_t pc) const
94    {
95        if (pc == compiler::INVALID_PC || pc_ins_map_.size() == 0) {
96            return 0;
97        }
98        auto iter = pc_ins_map_.find(pc);
99        if (iter == pc_ins_map_.end()) {
100            return 0;
101        }
102        return iter->second->ins_debug.line_number;
103    }
104
105    uint32_t GetColumnNumberByPc(size_t pc) const
106    {
107        if (pc == compiler::INVALID_PC || pc_ins_map_.size() == 0) {
108            return compiler::INVALID_COLUMN_NUM;
109        }
110        auto iter = pc_ins_map_.find(pc);
111        if (iter == pc_ins_map_.end()) {
112            return compiler::INVALID_COLUMN_NUM;
113        }
114
115        return iter->second->ins_debug.column_number;
116    }
117
118    void ClearPcInsMap()
119    {
120        pc_ins_map_.clear();
121    }
122
123    void StoreLiteralArray(std::string id, pandasm::LiteralArray &&literalarray)
124    {
125        ASSERT(prog_ != nullptr);
126        if (prog_ == nullptr) {
127            return;
128        }
129        prog_->literalarray_table.emplace(id, std::move(literalarray));
130    }
131
132    size_t GetLiteralArrayTableSize() const
133    {
134        ASSERT(prog_ != nullptr);
135        if (prog_ == nullptr) {
136            return 0;
137        }
138        return prog_->literalarray_table.size();
139    }
140
141    bool IsMapsSet() const
142    {
143        return maps_ != nullptr;
144    }
145
146    panda_file::SourceLang GetSourceLang()
147    {
148        return prog_ != nullptr ? prog_->lang : panda_file::SourceLang::PANDA_ASSEMBLY;
149    }
150
151    pandasm::Program *GetProgram() const
152    {
153        return prog_;
154    }
155
156private:
157    pandasm::Program *prog_ {nullptr};
158    const pandasm::AsmEmitter::PandaFileToPandaAsmMaps *maps_ {nullptr};
159    std::unordered_map<size_t, pandasm::Ins *> pc_ins_map_;
160};
161}  // namespace panda::bytecodeopt
162
163#endif  // BYTECODE_OPTIMIZER_IR_INTERFACE_H
164