• 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 "meta.h"
17 
18 #include <cstdlib>
19 
20 #include <algorithm>
21 #include <limits>
22 
23 #include "utils/expected.h"
24 
25 namespace ark::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 integer 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 ark::pandasm::Value::Type GetType(std::string_view value)
49 {
50     using VType = ark::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         {"record", 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     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
120     if (end != value.data() + value.length()) {
121         return Unexpected(Metadata::Error("Excepted integer literal", Metadata::Error::Type::INVALID_VALUE));
122     }
123 
124     if (errno == ERANGE) {
125         errno = 0;
126         return Unexpected(Metadata::Error("Value is out of range", Metadata::Error::Type::INVALID_VALUE));
127     }
128 
129     return static_cast<T>(v);
130 }
131 
132 template <Value::Type TYPE, class T = ValueTypeHelperT<TYPE>>
CreatePrimitiveValue(std::string_view value,T maxValue=std::numeric_limits<T>::max ())133 static Expected<ScalarValue, Metadata::Error> CreatePrimitiveValue(std::string_view value,
134                                                                    T maxValue = std::numeric_limits<T>::max())
135 {
136     auto res = ConvertFromString<T>(value);
137     if (!res) {
138         return Unexpected(res.Error());
139     }
140 
141     auto converted = res.Value();
142     if (converted > maxValue) {
143         return Unexpected(Metadata::Error("Value is out of range", Metadata::Error::Type::INVALID_VALUE));
144     }
145 
146     return ScalarValue::Create<TYPE>(converted);
147 }
148 
CreateValue(Value::Type type,std::string_view value,const std::unordered_map<std::string,std::unique_ptr<AnnotationData>> & annotationIdMap={})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>> &annotationIdMap = {})
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 = annotationIdMap.find(std::string(value));
201             if (it == annotationIdMap.cend()) {
202                 return Unexpected(Metadata::Error("Unknown annotation id", Metadata::Error::Type::INVALID_VALUE));
203             }
204 
205             auto annotationValue = it->second.get();
206             return ScalarValue::Create<Value::Type::ANNOTATION>(*annotationValue);
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>> & annotationIdMap)216 std::optional<Metadata::Error> AnnotationMetadata::AnnotationElementBuilder::AddValue(
217     std::string_view value, const std::unordered_map<std::string, std::unique_ptr<AnnotationData>> &annotationIdMap)
218 {
219     ASSERT(type_.has_value());
220 
221     auto type = type_.value();
222     if (type == Value::Type::ARRAY) {
223         ASSERT(componentType_.has_value());
224         type = componentType_.value();
225     }
226 
227     auto res = CreateValue(type, value, annotationIdMap);
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() && !annotationElementBuilder_.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() && !annotationElementBuilder_.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 (annotationBuilder_.HasId()) {
276         return Error(std::string("Unexpected attribute '").append(attribute) +
277                          "'. Annotation id attribute already defined",
278                      Error::Type::UNEXPECTED_ATTRIBUTE);
279     }
280 
281     annotationBuilder_.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() && !annotationElementBuilder_.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 (annotationElementBuilder_.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     annotationElementBuilder_.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 (!annotationElementBuilder_.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 (annotationElementBuilder_.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     annotationElementBuilder_.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 (!annotationElementBuilder_.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 (annotationElementBuilder_.IsArray() && !annotationElementBuilder_.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 (!annotationElementBuilder_.IsArray() && annotationElementBuilder_.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 annotationElementBuilder_.AddValue(value, idMap_);
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() && !annotationElementBuilder_.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() && !annotationElementBuilder_.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     auto base = GetAttributeValue("extends");
441     if (base) {
442         return base.value();
443     }
444 
445     return "";
446 }
447 
GetInterfaces() const448 std::vector<std::string> RecordMetadata::GetInterfaces() const
449 {
450     return {};
451 }
452 
IsAnnotation() const453 bool RecordMetadata::IsAnnotation() const
454 {
455     return false;
456 }
457 
IsRuntimeAnnotation() const458 bool RecordMetadata::IsRuntimeAnnotation() const
459 {
460     return false;
461 }
462 
IsTypeAnnotation() const463 bool RecordMetadata::IsTypeAnnotation() const
464 {
465     return false;
466 }
467 
IsRuntimeTypeAnnotation() const468 bool RecordMetadata::IsRuntimeTypeAnnotation() const
469 {
470     return false;
471 }
472 
HasImplementation() const473 bool FunctionMetadata::HasImplementation() const
474 {
475     return ((ACC_ABSTRACT & GetAccessFlags()) == 0) && ((ACC_NATIVE & GetAccessFlags()) == 0);
476 }
477 
IsCtor() const478 bool FunctionMetadata::IsCtor() const
479 {
480     return GetAttribute("ctor");
481 }
482 
IsCctor() const483 bool FunctionMetadata::IsCctor() const
484 {
485     return GetAttribute("cctor");
486 }
487 
StoreValue(std::string_view attribute,std::string_view value)488 std::optional<Metadata::Error> FieldMetadata::StoreValue(std::string_view attribute, std::string_view value)
489 {
490     auto err = ItemMetadata::StoreValue(attribute, value);
491     if (err) {
492         return err;
493     }
494 
495     if (IsValueAttribute(attribute)) {
496         Value::Type valueType;
497         if (!fieldType_.IsObject()) {
498             valueType = GetType(fieldType_.GetName());
499         } else {
500             valueType = Value::Type::STRING;
501         }
502 
503         auto res = CreateValue(valueType, value);
504         if (!res) {
505             return res.Error();
506         }
507 
508         value_ = res.Value();
509     }
510 
511     return {};
512 }
513 
514 #include <meta_gen.h>
515 
516 }  // namespace ark::pandasm
517