• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 panda::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     if (!ignorePrimitive) {
51         auto iter = pandaTypes.find(name);
52         if (iter == pandaTypes.end()) {
53             return panda_file::Type::TypeId::REFERENCE;
54         }
55         return iter->second;
56     }
57 
58     return panda_file::Type::TypeId::REFERENCE;
59 }
60 
61 /* static */
FromPrimitiveId(panda_file::Type::TypeId id)62 pandasm::Type Type::FromPrimitiveId(panda_file::Type::TypeId id)
63 {
64     static std::unordered_map<panda_file::Type::TypeId, std::string_view> pandaTypes = {
65 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
66 #define PANDATYPE(name, inst_code) {panda_file::Type::TypeId::inst_code, std::string_view(name)},
67         PANDA_ASSEMBLER_TYPES(PANDATYPE)
68 #undef PANDATYPE
69     };
70     auto iter = pandaTypes.find(id);
71     ASSERT(iter != pandaTypes.end());
72     pandasm::Type ret {iter->second, 0};
73     ASSERT(ret.typeId_ == id);
74     return ret;
75 }
76 
77 /* static */
GetName(std::string_view componentName,size_t rank)78 std::string Type::GetName(std::string_view componentName, size_t rank)
79 {
80     std::string name(componentName);
81     while (rank-- > 0) {
82         name += "[]";
83     }
84     return name;
85 }
86 
87 /* static */
FromDescriptor(std::string_view descriptor)88 Type Type::FromDescriptor(std::string_view descriptor)
89 {
90     static std::unordered_map<std::string_view, std::string_view> reversePrimitiveTypes = {
91         {"Z", "u1"},  {"B", "i8"},  {"H", "u8"},  {"S", "i16"}, {"C", "u16"},  {"I", "i32"}, {"U", "u32"},
92         {"F", "f32"}, {"D", "f64"}, {"J", "i64"}, {"Q", "u64"}, {"V", "void"}, {"A", "any"}};
93 
94     size_t i = 0;
95     while (descriptor[i] == '[') {
96         ++i;
97     }
98 
99     size_t rank = i;
100     bool isRefType = descriptor[i] == 'L';
101     if (isRefType) {
102         descriptor.remove_suffix(1); /* Remove semicolon */
103         ++i;
104     }
105 
106     descriptor.remove_prefix(i);
107 
108     if (isRefType) {
109         return Type(descriptor, rank);
110     }
111 
112     return Type(reversePrimitiveTypes[descriptor], rank);
113 }
114 
115 /* static */
FromName(std::string_view name,bool ignorePrimitive)116 Type Type::FromName(std::string_view name, bool ignorePrimitive)
117 {
118     constexpr size_t STEP = 2;
119 
120     size_t size = name.size();
121     size_t i = 0;
122 
123     while (name[size - i - 1] == ']') {
124         i += STEP;
125     }
126 
127     name.remove_suffix(i);
128 
129     return Type(name, i / STEP, ignorePrimitive);
130 }
131 
132 /* static */
IsStringType(const std::string & name,panda::panda_file::SourceLang lang)133 bool Type::IsStringType(const std::string &name, panda::panda_file::SourceLang lang)
134 {
135     auto stringType = Type::FromDescriptor(panda::panda_file::GetStringClassDescriptor(lang));
136     return name == stringType.GetName();
137 }
138 
139 /* static */
IsPandaPrimitiveType(const std::string & name)140 bool Type::IsPandaPrimitiveType(const std::string &name)
141 {
142     auto it = g_primitiveTypes.find(name);
143     return it != g_primitiveTypes.cend();
144 }
145 
146 }  // namespace panda::pandasm
147