• 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 
16 #include <unordered_map>
17 
18 #include "assembly-type.h"
19 
20 namespace ark::pandasm {
21 
22 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
23 static std::unordered_map<std::string_view, std::string_view> g_primitiveTypes = {
24     {"u1", "Z"},  {"i8", "B"},  {"u8", "H"},  {"i16", "S"}, {"u16", "C"},  {"i32", "I"}, {"u32", "U"},
25     {"f32", "F"}, {"f64", "D"}, {"i64", "J"}, {"u64", "Q"}, {"void", "V"}, {"any", "A"}};
26 
GetDescriptor(bool ignorePrimitive) const27 std::string Type::GetDescriptor(bool ignorePrimitive) const
28 {
29     if (!ignorePrimitive) {
30         auto it = g_primitiveTypes.find(componentName_);
31         if (it != g_primitiveTypes.cend()) {
32             return std::string(rank_, '[') + it->second.data();
33         }
34     }
35 
36     std::string res = std::string(rank_, '[') + "L" + componentName_ + ";";
37     std::replace(res.begin(), res.end(), '.', '/');
38     return res;
39 }
40 
41 /* static */
GetId(std::string_view name,bool ignorePrimitive)42 panda_file::Type::TypeId Type::GetId(std::string_view name, bool ignorePrimitive)
43 {
44     static std::unordered_map<std::string_view, panda_file::Type::TypeId> pandaTypes = {
45 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
46 #define PANDATYPE(name, inst_code) {std::string_view(name), panda_file::Type::TypeId::inst_code},
47         PANDA_ASSEMBLER_TYPES(PANDATYPE)
48 #undef PANDATYPE
49     };
50 
51     if (!ignorePrimitive) {
52         auto iter = pandaTypes.find(name);
53         if (iter == pandaTypes.end()) {
54             return panda_file::Type::TypeId::REFERENCE;
55         }
56         return iter->second;
57     }
58 
59     return panda_file::Type::TypeId::REFERENCE;
60 }
61 
62 /* static */
FromPrimitiveId(panda_file::Type::TypeId id)63 pandasm::Type Type::FromPrimitiveId(panda_file::Type::TypeId id)
64 {
65     static std::unordered_map<panda_file::Type::TypeId, std::string_view> pandaTypes = {
66 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
67 #define PANDATYPE(name, inst_code) {panda_file::Type::TypeId::inst_code, std::string_view(name)},
68         PANDA_ASSEMBLER_TYPES(PANDATYPE)
69 #undef PANDATYPE
70     };
71     auto iter = pandaTypes.find(id);
72     ASSERT(iter != pandaTypes.end());
73     pandasm::Type ret {iter->second, 0};
74     ASSERT(ret.typeId_ == id);
75     return ret;
76 }
77 
78 /* static */
GetName(std::string_view componentName,size_t rank)79 std::string Type::GetName(std::string_view componentName, size_t rank)
80 {
81     std::string name(componentName);
82     while (rank-- > 0) {
83         name += "[]";
84     }
85     return name;
86 }
87 
88 /* static */
FromDescriptor(std::string_view descriptor)89 Type Type::FromDescriptor(std::string_view descriptor)
90 {
91     static std::unordered_map<std::string_view, std::string_view> reversePrimitiveTypes = {
92         {"Z", "u1"},  {"B", "i8"},  {"H", "u8"},  {"S", "i16"}, {"C", "u16"},  {"I", "i32"}, {"U", "u32"},
93         {"F", "f32"}, {"D", "f64"}, {"J", "i64"}, {"Q", "u64"}, {"V", "void"}, {"A", "any"}};
94 
95     size_t i = 0;
96     while (descriptor[i] == '[') {
97         ++i;
98     }
99 
100     size_t rank = i;
101     bool isRefType = descriptor[i] == 'L';
102     if (isRefType) {
103         descriptor.remove_suffix(1); /* Remove semicolon */
104         ++i;
105     }
106 
107     descriptor.remove_prefix(i);
108 
109     if (isRefType) {
110         return Type(descriptor, rank);
111     }
112 
113     return Type(reversePrimitiveTypes[descriptor], rank);
114 }
115 
116 /* static */
FromName(std::string_view name,bool ignorePrimitive)117 Type Type::FromName(std::string_view name, bool ignorePrimitive)
118 {
119     constexpr size_t STEP = 2;
120 
121     size_t size = name.size();
122     size_t i = 0;
123 
124     while (name[size - i - 1] == ']') {
125         i += STEP;
126     }
127 
128     name.remove_suffix(i);
129 
130     return Type(name, i / STEP, ignorePrimitive);
131 }
132 
133 /* static */
IsStringType(const std::string & name,ark::panda_file::SourceLang lang)134 bool Type::IsStringType(const std::string &name, ark::panda_file::SourceLang lang)
135 {
136     auto stringType = Type::FromDescriptor(ark::panda_file::GetStringClassDescriptor(lang));
137     return name == stringType.GetName();
138 }
139 
140 /* static */
IsPandaPrimitiveType(const std::string & name)141 bool Type::IsPandaPrimitiveType(const std::string &name)
142 {
143     auto it = g_primitiveTypes.find(name);
144     return it != g_primitiveTypes.cend();
145 }
146 
147 }  // namespace ark::pandasm
148