• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_KLASS_HELPER_H_
16 #define PANDA_RUNTIME_KLASS_HELPER_H_
17 
18 #include <cstdint>
19 
20 #include "libpandabase/utils/span.h"
21 #include "libpandafile/file_items.h"
22 #include "runtime/include/coretypes/tagged_value.h"
23 #include "runtime/include/mem/panda_string.h"
24 #include "runtime/object_header_config.h"
25 
26 namespace ark {
27 
28 // Small helper
29 template <class Config>
30 class ClassConfig {
31 public:
32     using ClassWordSize = typename Config::Size;
33 };
34 
35 class ClassHelper : private ClassConfig<MemoryModelConfig> {
36 public:
37     using ClassWordSize = typename ClassConfig::ClassWordSize;  // To be visible outside
38 
39     static constexpr size_t OBJECT_POINTER_SIZE = sizeof(ClassWordSize);
40     // In general for any T: sizeof(T*) != OBJECT_POINTER_SIZE
41     static constexpr size_t POINTER_SIZE = sizeof(uintptr_t);
42 
43     PANDA_PUBLIC_API static const uint8_t *GetDescriptor(const uint8_t *name, PandaString *storage);
44 
45     static const uint8_t *GetTypeDescriptor(const PandaString &name, PandaString *storage);
46 
47     static const uint8_t *GetArrayDescriptor(const uint8_t *componentName, size_t rank, PandaString *storage);
48 
49     static char GetPrimitiveTypeDescriptorChar(panda_file::Type::TypeId typeId);
50 
51     static const uint8_t *GetPrimitiveTypeDescriptorStr(panda_file::Type::TypeId typeId);
52 
53     static const char *GetPrimitiveTypeStr(panda_file::Type::TypeId typeId);
54 
55     static const uint8_t *GetPrimitiveDescriptor(panda_file::Type type, PandaString *storage);
56 
57     static const uint8_t *GetPrimitiveArrayDescriptor(panda_file::Type type, size_t rank, PandaString *storage);
58 
59     template <typename Str = std::string>
60     static Str GetName(const uint8_t *descriptor);
61 
62     template <typename Str = std::string>
63     static Str GetNameUndecorated(const uint8_t *descriptor);
64 
IsArrayDescriptor(const uint8_t * descriptor)65     static bool IsArrayDescriptor(const uint8_t *descriptor)
66     {
67         Span<const uint8_t> sp(descriptor, 1);
68         return sp[0] == '[';
69     }
70 
GetComponentDescriptor(const uint8_t * descriptor)71     static const uint8_t *GetComponentDescriptor(const uint8_t *descriptor)
72     {
73         ASSERT(IsArrayDescriptor(descriptor));
74         Span<const uint8_t> sp(descriptor, 1);
75         return sp.cend();
76     }
77 
GetDimensionality(const uint8_t * descriptor)78     static size_t GetDimensionality(const uint8_t *descriptor)
79     {
80         ASSERT(IsArrayDescriptor(descriptor));
81         size_t dim = 0;
82         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
83         while (*descriptor++ == '[') {
84             ++dim;
85         }
86         return dim;
87     }
88 };
89 
90 // Str is std::string or PandaString
91 /* static */
92 template <typename Str>
GetName(const uint8_t * descriptor)93 Str ClassHelper::GetName(const uint8_t *descriptor)
94 {
95     switch (*descriptor) {
96         case 'V':
97             return "void";
98         case 'Z':
99             return "u1";
100         case 'B':
101             return "i8";
102         case 'H':
103             return "u8";
104         case 'S':
105             return "i16";
106         case 'C':
107             return "u16";
108         case 'I':
109             return "i32";
110         case 'U':
111             return "u32";
112         case 'J':
113             return "i64";
114         case 'Q':
115             return "u64";
116         case 'F':
117             return "f32";
118         case 'D':
119             return "f64";
120         case 'A':
121             return "any";
122         default: {
123             break;
124         }
125     }
126 
127     Str name = utf::Mutf8AsCString(descriptor);
128     if (name[0] == '[') {
129         return name;
130     }
131 
132     std::replace(name.begin(), name.end(), '/', '.');
133 
134     ASSERT(name.size() > 2);  // 2 - L and ;
135 
136     name.erase(0, 1);
137     name.pop_back();
138 
139     return name;
140 }
141 
142 // Str is std::string or PandaString
143 /* static */
144 template <typename Str>
GetNameUndecorated(const uint8_t * descriptor)145 Str ClassHelper::GetNameUndecorated(const uint8_t *descriptor)
146 {
147     Str result;
148 
149     auto rank = 0;
150     while (descriptor[rank] == '[') {  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
151         rank++;
152     }
153 
154     switch (descriptor[rank]) {  // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
155         case 'V':
156             result.append("void");
157             break;
158         case 'Z':
159             result.append("u1");
160             break;
161         case 'B':
162             result.append("i8");
163             break;
164         case 'H':
165             result.append("u8");
166             break;
167         case 'S':
168             result.append("i16");
169             break;
170         case 'C':
171             result.append("u16");
172             break;
173         case 'I':
174             result.append("i32");
175             break;
176         case 'U':
177             result.append("u32");
178             break;
179         case 'J':
180             result.append("i64");
181             break;
182         case 'Q':
183             result.append("u64");
184             break;
185         case 'F':
186             result.append("f32");
187             break;
188         case 'D':
189             result.append("f64");
190             break;
191         case 'A':
192             result.append("any");
193             break;
194         case 'L':
195             // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
196             result.append(utf::Mutf8AsCString(descriptor + rank + 1));  // cut 'L' at the beginning
197             ASSERT(result.size() > 0);
198             result.pop_back();  // cut ';' at the end
199 
200             std::replace(result.begin(), result.end(), '/', '.');
201 
202             break;
203         default:
204             break;
205     }
206 
207     while (rank > 0) {
208         result.append("[]");
209         rank--;
210     }
211 
212     return result;
213 }
214 
215 }  // namespace ark
216 
217 #endif  // PANDA_RUNTIME_KLASS_HELPER_H_
218