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 #ifndef ES2PANDA_EVALUATE_DEBUG_INFO_STORAGE_H
17 #define ES2PANDA_EVALUATE_DEBUG_INFO_STORAGE_H
18 
19 #include "evaluate/evaluateContext.h"
20 #include "evaluate/importExportTable.h"
21 #include "util/ustring.h"
22 
23 #include "libpandafile/debug_info_extractor.h"
24 #include "libpandafile/file.h"
25 #include "libpandafile/class_data_accessor.h"
26 
27 #include <memory>
28 #include <optional>
29 #include <string_view>
30 #include <unordered_map>
31 #include <utility>
32 
33 namespace ark::es2panda::evaluate {
34 
35 struct FileDebugInfo final {
36     using RecordsMap = ArenaUnorderedMap<util::StringView, panda_file::File::EntityId>;
37 
38     FileDebugInfo() = delete;
FileDebugInfoark::es2panda::evaluate::final39     explicit FileDebugInfo(std::unique_ptr<const panda_file::File> &&pandaFile, panda_file::File::EntityId classId,
40                            std::string_view module)
41         : pf(std::move(pandaFile)), globalClassAcc(*pf, classId), moduleName(module)
42     {
43         ASSERT(pf);
44     }
45 
46     // NOLINTBEGIN(misc-non-private-member-variables-in-classes)
47     std::unique_ptr<const panda_file::File> pf {nullptr};
48     panda_file::ClassDataAccessor globalClassAcc;
49     std::string_view moduleName;
50     std::string_view sourceFilePath;
51     std::optional<ImportExportTable> importExportTable;
52     std::optional<RecordsMap> records;
53     // NOLINTEND(misc-non-private-member-variables-in-classes)
54 };
55 
56 // Context-independent debug info lazy-loading storage.
57 // All "find" methods must accept paths to source files.
58 class DebugInfoStorage final {
59 public:
60     explicit DebugInfoStorage(const CompilerOptions &options, ArenaAllocator *allocator);
61 
62     NO_COPY_SEMANTIC(DebugInfoStorage);
63     NO_MOVE_SEMANTIC(DebugInfoStorage);
64 
65     ~DebugInfoStorage() = default;
66 
Allocator()67     ArenaAllocator *Allocator()
68     {
69         return allocator_;
70     }
71 
72     [[nodiscard]] bool FillEvaluateContext(EvaluateContext &context);
73 
74     const panda_file::File *GetPandaFile(std::string_view filePath);
75     const ImportExportTable *GetImportExportTable(std::string_view filePath);
76     panda_file::ClassDataAccessor *GetGlobalClassAccessor(std::string_view filePath);
77     std::string_view GetModuleName(std::string_view filePath);
78 
79     FileDebugInfo *GetDebugInfoByModuleName(std::string_view moduleName) const;
80 
81     /**
82      * @brief Returns class'es panda file Id on success, invalid EntityId otherwise
83      */
84     panda_file::File::EntityId FindClass(std::string_view filePath, std::string_view className);
85 
86     template <typename Callback>
EnumerateContextFiles(const Callback &cb)87     void EnumerateContextFiles(const Callback &cb)
88     {
89         for (const auto &[sourceFilePath, debugInfo] : sourceFileToDebugInfo_) {
90             if (!cb(sourceFilePath, debugInfo->pf.get(), debugInfo->globalClassAcc, debugInfo->moduleName)) {
91                 return;
92             }
93         }
94     }
95 
96 private:
97     using DebugInfoMap = ArenaUnorderedMap<std::string_view, FileDebugInfo *>;
98 
99 private:
100     void LoadFileDebugInfo(std::string_view pfPath);
101 
102     const ImportExportTable &LazyLoadImportExportTable(FileDebugInfo *info);
103     const FileDebugInfo::RecordsMap &LazyLoadRecords(FileDebugInfo *info);
104 
105 private:
106     ArenaAllocator *allocator_ {nullptr};
107 
108     // Mapping from sources' files names into the corresponding debug information struct.
109     // Used for fast lookups basing on imports/exports tables.
110     DebugInfoMap sourceFileToDebugInfo_;
111     // Mapping from module names into the corresponding debug information struct.
112     // Used for fast lookups during inheritance chain resolution.
113     DebugInfoMap moduleNameToDebugInfo_;
114 };
115 
116 }  // namespace ark::es2panda::evaluate
117 
118 #endif  // ES2PANDA_EVALUATE_DEBUG_INFO_STORAGE_H
119