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 #ifndef LIBPANDAFILE_LITERAL_DATA_ACCESSOR_INL_H
17 #define LIBPANDAFILE_LITERAL_DATA_ACCESSOR_INL_H
18 
19 #include <string>
20 #include "file_items.h"
21 #include "literal_data_accessor.h"
22 #include "utils/utf.h"
23 
24 namespace panda::panda_file {
25 
GetLiteralValsNum(File::EntityId id) const26 inline size_t LiteralDataAccessor::GetLiteralValsNum(File::EntityId id) const
27 {
28     auto sp = panda_file_.GetSpanFromId(id);
29     return helpers::Read<ID_SIZE>(&sp);
30 }
31 
GetLiteralValsNum(size_t index) const32 inline size_t LiteralDataAccessor::GetLiteralValsNum(size_t index) const
33 {
34     return GetLiteralValsNum(File::EntityId(
35         static_cast<uint32_t>(helpers::Read<sizeof(uint32_t)>(literal_data_sp_.SubSpan(index * ID_SIZE)))));
36 }
37 
38 template <class Callback>
EnumerateLiteralVals(size_t index, const Callback &cb)39 inline void LiteralDataAccessor::EnumerateLiteralVals(size_t index, const Callback &cb)
40 {
41     EnumerateLiteralVals(GetLiteralArrayId(index), cb);
42 }
43 
44 template <class Callback>
EnumerateLiteralVals(File::EntityId id, const Callback &cb)45 inline void LiteralDataAccessor::EnumerateLiteralVals(File::EntityId id, const Callback &cb)
46 {
47     auto sp = panda_file_.GetSpanFromId(id);
48     auto literal_vals_num = helpers::Read<LEN_SIZE>(&sp);
49     LiteralValue value;
50 
51     for (size_t i = 0; i < literal_vals_num; i += 2U) {
52         auto tag = static_cast<LiteralTag>(helpers::Read<TAG_SIZE>(&sp));
53         switch (tag) {
54             case LiteralTag::INTEGER:
55             case LiteralTag::LITERALBUFFERINDEX: {
56                 value = static_cast<uint32_t>(helpers::Read<sizeof(uint32_t)>(&sp));
57                 break;
58             }
59             case LiteralTag::DOUBLE: {
60                 value = bit_cast<double>(helpers::Read<sizeof(uint64_t)>(&sp));
61                 break;
62             }
63             case LiteralTag::BOOL: {
64                 value = static_cast<bool>(helpers::Read<sizeof(uint8_t)>(&sp));
65                 break;
66             }
67             case LiteralTag::FLOAT: {
68                 value = static_cast<float>(helpers::Read<sizeof(uint32_t)>(&sp));
69                 break;
70             }
71             case LiteralTag::STRING:
72             case LiteralTag::METHOD:
73             case LiteralTag::GETTER:
74             case LiteralTag::SETTER:
75             case LiteralTag::GENERATORMETHOD:
76             case LiteralTag::LITERALARRAY:
77             case LiteralTag::ASYNCGENERATORMETHOD: {
78                 value = static_cast<uint32_t>(helpers::Read<sizeof(uint32_t)>(&sp));
79                 break;
80             }
81             case LiteralTag::METHODAFFILIATE: {
82                 value = static_cast<uint16_t>(helpers::Read<sizeof(uint16_t)>(&sp));
83                 break;
84             }
85             case LiteralTag::BUILTINTYPEINDEX:
86             case LiteralTag::ACCESSOR:
87             case LiteralTag::NULLVALUE: {
88                 value = static_cast<uint8_t>(helpers::Read<sizeof(uint8_t)>(&sp));
89                 break;
90             }
91             // in statically-typed languages we don't need tag for every element,
92             // thus treat literal array as array of one element with corresponding type
93             case LiteralTag::ARRAY_U1:
94             case LiteralTag::ARRAY_U8:
95             case LiteralTag::ARRAY_I8:
96             case LiteralTag::ARRAY_U16:
97             case LiteralTag::ARRAY_I16:
98             case LiteralTag::ARRAY_U32:
99             case LiteralTag::ARRAY_I32:
100             case LiteralTag::ARRAY_U64:
101             case LiteralTag::ARRAY_I64:
102             case LiteralTag::ARRAY_F32:
103             case LiteralTag::ARRAY_F64:
104             case LiteralTag::ARRAY_STRING: {
105                 value = panda_file_.GetIdFromPointer(sp.data()).GetOffset();
106                 i = literal_vals_num;
107                 break;
108             }
109             default: {
110                 UNREACHABLE();
111                 break;
112             }
113         }
114         cb(value, tag);
115     }
116 }
117 
118 }  // namespace panda::panda_file
119 
120 #endif  // LIBPANDAFILE_LITERAL_DATA_ACCESSOR_INL_H
121