1 /**
2  * Copyright (c) 2021-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 #ifndef PANDA_RUNTIME_ITABLE_H_
16 #define PANDA_RUNTIME_ITABLE_H_
17 
18 #include "libpandabase/utils/span.h"
19 #include "runtime/include/mem/allocator.h"
20 
21 namespace ark {
22 
23 class Class;
24 class Method;
25 
26 class ITable {
27 public:
28     class Entry {
29     public:
SetInterface(Class *interface)30         void SetInterface(Class *interface)
31         {
32             interface_ = interface;
33         }
34 
GetInterface() const35         Class *GetInterface() const
36         {
37             return interface_;
38         }
39 
SetMethods(Span<Method *> methods)40         void SetMethods(Span<Method *> methods)
41         {
42             methods_ = methods;
43         }
44 
GetMethods() const45         Span<Method *> GetMethods() const
46         {
47             return methods_;
48         }
49 
Copy(mem::InternalAllocatorPtr allocator) const50         Entry Copy(mem::InternalAllocatorPtr allocator) const
51         {
52             Entry entry;
53             entry.interface_ = interface_;
54             if (methods_.data() != nullptr) {
55                 entry.methods_ = {allocator->AllocArray<Method *>(methods_.size()), methods_.size()};
56                 for (size_t idx = 0; idx < methods_.size(); idx++) {
57                     entry.methods_[idx] = methods_[idx];
58                 }
59             }
60             return entry;
61         }
62 
GetInterfaceOffset()63         static constexpr uint32_t GetInterfaceOffset()
64         {
65             return MEMBER_OFFSET(Entry, interface_);
66         }
67 
68     private:
69         Class *interface_ {nullptr};
70         Span<Method *> methods_ {nullptr, nullptr};
71     };
72 
73     ITable() = default;
74 
ITable(Span<Entry> elements)75     explicit ITable(Span<Entry> elements) : elements_(elements) {}
76 
Get()77     Span<Entry> Get()
78     {
79         return elements_;
80     }
81 
Get() const82     Span<const Entry> Get() const
83     {
84         return Span<const Entry>(elements_.data(), elements_.size());
85     }
86 
Size() const87     size_t Size() const
88     {
89         return elements_.size();
90     }
91 
operator [](size_t i)92     Entry &operator[](size_t i)
93     {
94         return elements_[i];
95     }
96 
operator [](size_t i) const97     const Entry &operator[](size_t i) const
98     {
99         return elements_[i];
100     }
101 
102     ~ITable() = default;
103 
104     DEFAULT_COPY_SEMANTIC(ITable);
105     DEFAULT_MOVE_SEMANTIC(ITable);
106 
GetEntriesDataOffset()107     static constexpr uint32_t GetEntriesDataOffset()
108     {
109         return GetElementsOffset() + decltype(elements_)::GetDataOffset();
110     }
GetEntriesSizeOffset()111     static constexpr uint32_t GetEntriesSizeOffset()
112     {
113         return GetElementsOffset() + decltype(elements_)::GetSizeOffset();
114     }
GetEntrySize()115     static constexpr uint32_t GetEntrySize()
116     {
117         return sizeof(Entry);
118     }
119 
120 private:
GetElementsOffset()121     static constexpr uint32_t GetElementsOffset()
122     {
123         return MEMBER_OFFSET(ITable, elements_);
124     }
125     Span<Entry> elements_ {nullptr, nullptr};
126 };
127 
128 }  // namespace ark
129 
130 #endif  // PANDA_RUNTIME_ITABLE_H_
131