• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "meta.h"
17 
18 #include <stdlib.h>
19 
20 #include <algorithm>
21 #include <limits>
22 
23 #include "utils/expected.h"
24 
25 namespace panda::pandasm {
26 
ValidateSize(std::string_view value) const27 std::optional<Metadata::Error> Metadata::ValidateSize(std::string_view value) const
28 {
29     constexpr size_t SIZE = 10;
30 
31     if (!std::all_of(value.cbegin(), value.cend(), ::isdigit)) {
32         return Error("Unsigned interger value expected", Error::Type::INVALID_VALUE);
33     }
34 
35     strtoul(value.data(), nullptr, SIZE);
36     if (errno == ERANGE) {
37         return Error("Value is out of range", Error::Type::INVALID_VALUE);
38     }
39 
40     return {};
41 }
42 
IsForeign() const43 bool ItemMetadata::IsForeign() const
44 {
45     return GetAttribute("external");
46 }
47 
GetType(std::string_view value)48 static panda::pandasm::Value::Type GetType(std::string_view value)
49 {
50     using VType = panda::pandasm::Value::Type;
51     static std::unordered_map<std::string_view, VType> types {
52         {"u1", VType::U1},        {"i8", VType::I8},        {"u8", VType::U8},
53         {"i16", VType::I16},      {"u16", VType::U16},      {"i32", VType::I32},
54         {"u32", VType::U32},      {"i64", VType::I64},      {"u64", VType::U64},
55         {"f32", VType::F32},      {"f64", VType::F64},      {"string", VType::STRING},
56         {"class", VType::RECORD}, {"enum", VType::ENUM},    {"annotation", VType::ANNOTATION},
57         {"array", VType::ARRAY},  {"method", VType::METHOD}};
58 
59     return types[value];
60 }
61 
62 template <class T>
ConvertFromString(std::string_view value,char ** end)63 static T ConvertFromString(std::string_view value, char **end)
64 {
65     static_assert(std::is_integral_v<T>, "T must be integral type");
66 
67     constexpr T MIN = std::numeric_limits<T>::min();
68     constexpr T MAX = std::numeric_limits<T>::max();
69 
70     if constexpr (std::is_signed_v<T>) {
71         auto v = ConvertFromString<int64_t>(value, end);
72         if (v < MIN || v > MAX) {
73             errno = ERANGE;
74         }
75         return static_cast<T>(v);
76     }
77 
78     if constexpr (!std::is_signed_v<T>) {
79         auto v = ConvertFromString<uint64_t>(value, end);
80         if (v < MIN || v > MAX) {
81             errno = ERANGE;
82         }
83         return static_cast<T>(v);
84     }
85 }
86 
87 template <>
ConvertFromString(std::string_view value,char ** end)88 int64_t ConvertFromString(std::string_view value, char **end)
89 {
90     return static_cast<int64_t>(strtoll(value.data(), end, 0));
91 }
92 
93 template <>
ConvertFromString(std::string_view value,char ** end)94 uint64_t ConvertFromString(std::string_view value, char **end)
95 {
96     return static_cast<uint64_t>(strtoull(value.data(), end, 0));
97 }
98 
99 template <>
ConvertFromString(std::string_view value,char ** end)100 float ConvertFromString(std::string_view value, char **end)
101 {
102     return strtof(value.data(), end);
103 }
104 
105 template <>
ConvertFromString(std::string_view value,char ** end)106 double ConvertFromString(std::string_view value, char **end)
107 {
108     return strtod(value.data(), end);
109 }
110 
111 template <class T>
ConvertFromString(std::string_view value)112 static Expected<T, Metadata::Error> ConvertFromString(std::string_view value)
113 {
114     static_assert(std::is_arithmetic_v<T>, "T must be arithmetic type");
115 
116     char *end = nullptr;
117     auto v = ConvertFromString<T>(value, &end);
118 
119     if (end != value.data() + value.length()) {
120         return Unexpected(Metadata::Error("Excepted integer literal", Metadata::Error::Type::INVALID_VALUE));
121     }
122 
123     if (errno == ERANGE) {
124         errno = 0;
125         return Unexpected(Metadata::Error("Value is out of range", Metadata::Error::Type::INVALID_VALUE));
126     }
127 
128     return static_cast<T>(v);
129 }
130 
131 template <Value::Type type, class T = ValueTypeHelperT<type>>
CreatePrimitiveValue(std::string_view value,T max_value=std::numeric_limits<T>::max ())132 static Expected<ScalarValue, Metadata::Error> CreatePrimitiveValue(std::string_view value,
133                                                                    T max_value = std::numeric_limits<T>::max())
134 {
135     auto res = ConvertFromString<T>(value);
136     if (!res) {
137         return Unexpected(res.Error());
138     }
139 
140     auto converted = res.Value();
141     if (converted > max_value) {
142         return Unexpected(Metadata::Error("Value is out of range", Metadata::Error::Type::INVALID_VALUE));
143     }
144 
145     return ScalarValue::Create<type>(converted);
146 }
147 
148 // CODECHECK-NOLINTNEXTLINE(C_RULE_ID_FUNCTION_SIZE)
CreateValue(Value::Type type,std::string_view value,const std::unordered_map<std::string,std::unique_ptr<AnnotationData>> & annotation_id_map={})149 static Expected<ScalarValue, Metadata::Error> CreateValue(
150     Value::Type type, std::string_view value,
151     const std::unordered_map<std::string, std::unique_ptr<AnnotationData>> &annotation_id_map = {})
152 {
153     switch (type) {
154         case Value::Type::U1: {
155             return CreatePrimitiveValue<Value::Type::U1>(value, 1);
156         }
157         case Value::Type::I8: {
158             return CreatePrimitiveValue<Value::Type::I8>(value);
159         }
160         case Value::Type::U8: {
161             return CreatePrimitiveValue<Value::Type::U8>(value);
162         }
163         case Value::Type::I16: {
164             return CreatePrimitiveValue<Value::Type::I16>(value);
165         }
166         case Value::Type::U16: {
167             return CreatePrimitiveValue<Value::Type::U16>(value);
168         }
169         case Value::Type::I32: {
170             return CreatePrimitiveValue<Value::Type::I32>(value);
171         }
172         case Value::Type::U32: {
173             return CreatePrimitiveValue<Value::Type::U32>(value);
174         }
175         case Value::Type::I64: {
176             return CreatePrimitiveValue<Value::Type::I64>(value);
177         }
178         case Value::Type::U64: {
179             return CreatePrimitiveValue<Value::Type::U64>(value);
180         }
181         case Value::Type::F32: {
182             return CreatePrimitiveValue<Value::Type::F32>(value);
183         }
184         case Value::Type::F64: {
185             return CreatePrimitiveValue<Value::Type::F64>(value);
186         }
187         case Value::Type::STRING: {
188             return ScalarValue::Create<Value::Type::STRING>(value);
189         }
190         case Value::Type::RECORD: {
191             return ScalarValue::Create<Value::Type::RECORD>(Type::FromName(value));
192         }
193         case Value::Type::METHOD: {
194             return ScalarValue::Create<Value::Type::METHOD>(value);
195         }
196         case Value::Type::ENUM: {
197             return ScalarValue::Create<Value::Type::ENUM>(value);
198         }
199         case Value::Type::ANNOTATION: {
200             auto it = annotation_id_map.find(std::string(value));
201             if (it == annotation_id_map.cend()) {
202                 return Unexpected(Metadata::Error("Unknown annotation id", Metadata::Error::Type::INVALID_VALUE));
203             }
204 
205             auto annotation_value = it->second.get();
206             return ScalarValue::Create<Value::Type::ANNOTATION>(*annotation_value);
207         }
208         default: {
209             break;
210         }
211     }
212 
213     UNREACHABLE();
214 }
215 
AddValue(std::string_view value,const std::unordered_map<std::string,std::unique_ptr<AnnotationData>> & annotation_id_map)216 std::optional<Metadata::Error> AnnotationMetadata::AnnotationElementBuilder::AddValue(
217     std::string_view value, const std::unordered_map<std::string, std::unique_ptr<AnnotationData>> &annotation_id_map)
218 {
219     ASSERT(type_.has_value());
220 
221     auto type = type_.value();
222     if (type == Value::Type::ARRAY) {
223         ASSERT(component_type_.has_value());
224         type = component_type_.value();
225     }
226 
227     auto res = CreateValue(type, value, annotation_id_map);
228     if (!res) {
229         return res.Error();
230     }
231 
232     values_.push_back(res.Value());
233 
234     return {};
235 }
236 
Store(std::string_view attribute)237 std::optional<Metadata::Error> AnnotationMetadata::Store(std::string_view attribute)
238 {
239     if (IsParseAnnotationElement() && !annotation_element_builder_.IsCompleted()) {
240         return Error(std::string("Unexpected attribute '").append(attribute) +
241                          "'. Annotation element isn't completely defined",
242                      Error::Type::UNEXPECTED_ATTRIBUTE);
243     }
244 
245     if (IsParseAnnotation()) {
246         ResetAnnotationBuilder();
247     }
248 
249     return Metadata::Store(attribute);
250 }
251 
MeetExpRecordAttribute(std::string_view attribute,std::string_view value)252 std::optional<Metadata::Error> AnnotationMetadata::MeetExpRecordAttribute(std::string_view attribute,
253                                                                           std::string_view value)
254 {
255     if (IsParseAnnotationElement() && !annotation_element_builder_.IsCompleted()) {
256         return Error(std::string("Unexpected attribute '").append(attribute) +
257                          "'. Annotation element isn't completely defined",
258                      Error::Type::UNEXPECTED_ATTRIBUTE);
259     }
260 
261     InitializeAnnotationBuilder(value);
262 
263     return {};
264 }
265 
MeetExpIdAttribute(std::string_view attribute,std::string_view value)266 std::optional<Metadata::Error> AnnotationMetadata::MeetExpIdAttribute(std::string_view attribute,
267                                                                       std::string_view value)
268 {
269     if (!IsParseAnnotation() || IsParseAnnotationElement()) {
270         return Error(std::string("Unexpected attribute '").append(attribute) +
271                          "'. Annotation record attribute must be defined first",
272                      Error::Type::UNEXPECTED_ATTRIBUTE);
273     }
274 
275     if (annotation_builder_.HasId()) {
276         return Error(std::string("Unexpected attribute '").append(attribute) +
277                          "'. Annotation id attribute already defined",
278                      Error::Type::UNEXPECTED_ATTRIBUTE);
279     }
280 
281     annotation_builder_.SetId(value);
282 
283     return {};
284 }
285 
MeetExpElementNameAttribute(std::string_view attribute,std::string_view value)286 std::optional<Metadata::Error> AnnotationMetadata::MeetExpElementNameAttribute(std::string_view attribute,
287                                                                                std::string_view value)
288 {
289     if (!IsParseAnnotation()) {
290         return Error(std::string("Unexpected attribute '").append(attribute) +
291                          "'. Annotation record attribute must be defined first",
292                      Error::Type::UNEXPECTED_ATTRIBUTE);
293     }
294 
295     if (IsParseAnnotationElement() && !annotation_element_builder_.IsCompleted()) {
296         return Error(std::string("Unexpected attribute '").append(attribute) +
297                          "'. Previous annotation element isn't defined completely",
298                      Error::Type::UNEXPECTED_ATTRIBUTE);
299     }
300 
301     InitializeAnnotationElementBuilder(value);
302 
303     return {};
304 }
305 
MeetExpElementTypeAttribute(std::string_view attribute,std::string_view value)306 std::optional<Metadata::Error> AnnotationMetadata::MeetExpElementTypeAttribute(std::string_view attribute,
307                                                                                std::string_view value)
308 {
309     if (!IsParseAnnotationElement()) {
310         return Error(std::string("Unexpected attribute '").append(attribute) +
311                          "'. Annotation element name attribute must be defined first",
312                      Error::Type::UNEXPECTED_ATTRIBUTE);
313     }
314 
315     if (annotation_element_builder_.IsTypeSet()) {
316         return Error(std::string("Unexpected attribute '").append(attribute) +
317                          "'. Annotation element type attribute already defined",
318                      Error::Type::UNEXPECTED_ATTRIBUTE);
319     }
320 
321     annotation_element_builder_.SetType(GetType(value));
322 
323     return {};
324 }
325 
MeetExpElementArrayComponentTypeAttribute(std::string_view attribute,std::string_view value)326 std::optional<Metadata::Error> AnnotationMetadata::MeetExpElementArrayComponentTypeAttribute(std::string_view attribute,
327                                                                                              std::string_view value)
328 {
329     if (!IsParseAnnotationElement()) {
330         return Error(std::string("Unexpected attribute '").append(attribute) +
331                          "'. Annotation element name attribute must be defined first",
332                      Error::Type::UNEXPECTED_ATTRIBUTE);
333     }
334 
335     if (!annotation_element_builder_.IsArray()) {
336         return Error(std::string("Unexpected attribute '").append(attribute) + "'. Annotation element type isn't array",
337                      Error::Type::UNEXPECTED_ATTRIBUTE);
338     }
339 
340     if (annotation_element_builder_.IsComponentTypeSet()) {
341         return Error(std::string("Unexpected attribute '").append(attribute) +
342                          "'. Annotation element array component type attribute already defined",
343                      Error::Type::UNEXPECTED_ATTRIBUTE);
344     }
345 
346     annotation_element_builder_.SetComponentType(GetType(value));
347 
348     return {};
349 }
350 
MeetExpElementValueAttribute(std::string_view attribute,std::string_view value)351 std::optional<Metadata::Error> AnnotationMetadata::MeetExpElementValueAttribute(std::string_view attribute,
352                                                                                 std::string_view value)
353 {
354     if (!IsParseAnnotationElement()) {
355         return Error(std::string("Unexpected attribute '").append(attribute) +
356                          "'. Annotation element name attribute must be defined first",
357                      Error::Type::UNEXPECTED_ATTRIBUTE);
358     }
359 
360     if (!annotation_element_builder_.IsTypeSet()) {
361         return Error(std::string("Unexpected attribute '").append(attribute) +
362                          "'. Annotation element type attribute isn't defined",
363                      Error::Type::UNEXPECTED_ATTRIBUTE);
364     }
365 
366     if (annotation_element_builder_.IsArray() && !annotation_element_builder_.IsComponentTypeSet()) {
367         return Error(std::string("Unexpected attribute '").append(attribute) +
368                          "'. Annotation element array component type attribute isn't defined",
369                      Error::Type::UNEXPECTED_ATTRIBUTE);
370     }
371 
372     if (!annotation_element_builder_.IsArray() && annotation_element_builder_.IsCompleted()) {
373         return Error(std::string("Unexpected attribute '").append(attribute) +
374                          "'. Annotation element is completely defined",
375                      Error::Type::UNEXPECTED_ATTRIBUTE);
376     }
377 
378     return annotation_element_builder_.AddValue(value, id_map_);
379 }
380 
StoreValue(std::string_view attribute,std::string_view value)381 std::optional<Metadata::Error> AnnotationMetadata::StoreValue(std::string_view attribute, std::string_view value)
382 {
383     auto err = Metadata::StoreValue(attribute, value);
384     if (err) {
385         return err;
386     }
387 
388     if (IsAnnotationRecordAttribute(attribute)) {
389         return MeetExpRecordAttribute(attribute, value);
390     }
391 
392     if (IsAnnotationIdAttribute(attribute)) {
393         return MeetExpIdAttribute(attribute, value);
394     }
395 
396     if (IsAnnotationElementNameAttribute(attribute)) {
397         return MeetExpElementNameAttribute(attribute, value);
398     }
399 
400     if (IsAnnotationElementTypeAttribute(attribute)) {
401         return MeetExpElementTypeAttribute(attribute, value);
402     }
403 
404     if (IsAnnotationElementArrayComponentTypeAttribute(attribute)) {
405         return MeetExpElementArrayComponentTypeAttribute(attribute, value);
406     }
407 
408     if (IsAnnotationElementValueAttribute(attribute)) {
409         return MeetExpElementValueAttribute(attribute, value);
410     }
411 
412     if (IsParseAnnotationElement() && !annotation_element_builder_.IsCompleted()) {
413         return Error(std::string("Unexpected attribute '").append(attribute) +
414                          "'. Annotation element isn't completely defined",
415                      Error::Type::UNEXPECTED_ATTRIBUTE);
416     }
417 
418     if (IsParseAnnotation()) {
419         ResetAnnotationBuilder();
420     }
421 
422     return {};
423 }
424 
ValidateData()425 std::optional<Metadata::Error> AnnotationMetadata::ValidateData()
426 {
427     if (IsParseAnnotationElement() && !annotation_element_builder_.IsCompleted()) {
428         return Error("Annotation element isn't completely defined", Error::Type::MISSING_ATTRIBUTE);
429     }
430 
431     if (IsParseAnnotation()) {
432         ResetAnnotationBuilder();
433     }
434 
435     return Metadata::ValidateData();
436 }
437 
GetBase() const438 std::string RecordMetadata::GetBase() const
439 {
440     return "";
441 }
442 
GetInterfaces() const443 std::vector<std::string> RecordMetadata::GetInterfaces() const
444 {
445     return {};
446 }
447 
IsAnnotation() const448 bool RecordMetadata::IsAnnotation() const
449 {
450     return false;
451 }
452 
IsRuntimeAnnotation() const453 bool RecordMetadata::IsRuntimeAnnotation() const
454 {
455     return false;
456 }
457 
IsTypeAnnotation() const458 bool RecordMetadata::IsTypeAnnotation() const
459 {
460     return false;
461 }
462 
IsRuntimeTypeAnnotation() const463 bool RecordMetadata::IsRuntimeTypeAnnotation() const
464 {
465     return false;
466 }
467 
HasImplementation() const468 bool FunctionMetadata::HasImplementation() const
469 {
470     return !(ACC_ABSTRACT & GetAccessFlags()) && !(ACC_NATIVE & GetAccessFlags());
471 }
472 
IsCtor() const473 bool FunctionMetadata::IsCtor() const
474 {
475     return GetAttribute("ctor");
476 }
477 
IsCctor() const478 bool FunctionMetadata::IsCctor() const
479 {
480     return GetAttribute("cctor");
481 }
482 
StoreValue(std::string_view attribute,std::string_view value)483 std::optional<Metadata::Error> FieldMetadata::StoreValue(std::string_view attribute, std::string_view value)
484 {
485     auto err = ItemMetadata::StoreValue(attribute, value);
486     if (err) {
487         return err;
488     }
489 
490     if (IsValueAttribute(attribute)) {
491         Value::Type value_type;
492         if (!field_type_.IsObject()) {
493             value_type = GetType(field_type_.GetName());
494         } else {
495             value_type = Value::Type::STRING;
496         }
497 
498         auto res = CreateValue(value_type, value);
499         if (!res) {
500             return res.Error();
501         }
502 
503         value_ = res.Value();
504     }
505 
506     return {};
507 }
508 
509 #include <meta_gen.h>
510 
511 }  // namespace panda::pandasm
512