• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 static std::unordered_map<std::string_view, std::string_view> primitive_types = {
23     {"u1", "Z"},  {"i8", "B"},  {"u8", "H"},  {"i16", "S"}, {"u16", "C"},  {"i32", "I"}, {"u32", "U"},
24     {"f32", "F"}, {"f64", "D"}, {"i64", "J"}, {"u64", "Q"}, {"void", "V"}, {"any", "A"}};
25 
GetDescriptor(bool ignore_primitive) const26 std::string Type::GetDescriptor(bool ignore_primitive) const
27 {
28     if (!ignore_primitive) {
29         auto it = primitive_types.find(component_name_);
30         if (it != primitive_types.cend()) {
31             return std::string(rank_, '[') + it->second.data();
32         }
33     }
34 
35     std::string res = std::string(rank_, '[') + "L" + component_name_ + ";";
36     return res;
37 }
38 
39 /* static */
GetId(std::string_view name,bool ignore_primitive)40 panda_file::Type::TypeId Type::GetId(std::string_view name, bool ignore_primitive)
41 {
42     static std::unordered_map<std::string_view, panda_file::Type::TypeId> panda_types = {
43 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
44 #define PANDATYPE(name, inst_code) {std::string_view(name), panda_file::Type::TypeId::inst_code},
45         PANDA_ASSEMBLER_TYPES(PANDATYPE)
46 #undef PANDATYPE
47     };
48 
49     if (!ignore_primitive) {
50         auto iter = panda_types.find(name);
51 
52         if (iter == panda_types.end()) {
53             return panda_file::Type::TypeId::REFERENCE;
54         }
55         return iter->second;
56     } else {
57         return panda_file::Type::TypeId::REFERENCE;
58     }
59 }
60 
61 /* static */
GetName(std::string_view component_name,size_t rank)62 std::string Type::GetName(std::string_view component_name, size_t rank)
63 {
64     std::string name(component_name);
65     while (rank-- > 0) {
66         name += "[]";
67     }
68     return name;
69 }
70 
71 /* static */
FromDescriptor(std::string_view descriptor)72 Type Type::FromDescriptor(std::string_view descriptor)
73 {
74     static std::unordered_map<std::string_view, std::string_view> reverse_primitive_types = {
75         {"Z", "u1"},  {"B", "i8"},  {"H", "u8"},  {"S", "i16"}, {"C", "u16"},  {"I", "i32"}, {"U", "u32"},
76         {"F", "f32"}, {"D", "f64"}, {"J", "i64"}, {"Q", "u64"}, {"V", "void"}, {"A", "any"}};
77 
78     size_t i = 0;
79     while (descriptor[i] == '[') {
80         ++i;
81     }
82 
83     size_t rank = i;
84     bool is_ref_type = descriptor[i] == 'L';
85     if (is_ref_type) {
86         descriptor.remove_suffix(1); /* Remove semicolon */
87         ++i;
88     }
89 
90     descriptor.remove_prefix(i);
91 
92     if (is_ref_type) {
93         return Type(descriptor, rank);
94     }
95 
96     return Type(reverse_primitive_types[descriptor], rank);
97 }
98 
99 /* static */
FromName(std::string_view name,bool ignore_primitive)100 Type Type::FromName(std::string_view name, bool ignore_primitive)
101 {
102     constexpr size_t STEP = 2;
103 
104     size_t size = name.size();
105     size_t i = 0;
106 
107     while (name[size - i - 1] == ']') {
108         i += STEP;
109     }
110 
111     name.remove_suffix(i);
112 
113     return Type(name, i / STEP, ignore_primitive);
114 }
115 
116 /* static */
IsStringType(const std::string & name,panda::panda_file::SourceLang lang)117 bool Type::IsStringType(const std::string &name, panda::panda_file::SourceLang lang)
118 {
119     auto string_type = Type::FromDescriptor(panda::panda_file::GetStringClassDescriptor(lang));
120     if (name == string_type.GetName()) {
121         return true;
122     } else {
123         return false;
124     }
125 }
126 
127 /* static */
IsPandaPrimitiveType(const std::string & name)128 bool Type::IsPandaPrimitiveType(const std::string &name)
129 {
130     auto it = primitive_types.find(name);
131     if (it != primitive_types.cend()) {
132         return true;
133     } else {
134         return false;
135     }
136 }
137 
138 }  // namespace panda::pandasm
139