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)26 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)32 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::GENERATORMETHOD:
74 case LiteralTag::LITERALARRAY:
75 case LiteralTag::ASYNCGENERATORMETHOD: {
76 value = static_cast<uint32_t>(helpers::Read<sizeof(uint32_t)>(&sp));
77 break;
78 }
79 case LiteralTag::METHODAFFILIATE: {
80 value = static_cast<uint16_t>(helpers::Read<sizeof(uint16_t)>(&sp));
81 break;
82 }
83 case LiteralTag::BUILTINTYPEINDEX:
84 case LiteralTag::ACCESSOR:
85 case LiteralTag::NULLVALUE: {
86 value = static_cast<uint8_t>(helpers::Read<sizeof(uint8_t)>(&sp));
87 break;
88 }
89 // in statically-typed languages we don't need tag for every element,
90 // thus treat literal array as array of one element with corresponding type
91 case LiteralTag::ARRAY_U1:
92 case LiteralTag::ARRAY_U8:
93 case LiteralTag::ARRAY_I8:
94 case LiteralTag::ARRAY_U16:
95 case LiteralTag::ARRAY_I16:
96 case LiteralTag::ARRAY_U32:
97 case LiteralTag::ARRAY_I32:
98 case LiteralTag::ARRAY_U64:
99 case LiteralTag::ARRAY_I64:
100 case LiteralTag::ARRAY_F32:
101 case LiteralTag::ARRAY_F64:
102 case LiteralTag::ARRAY_STRING: {
103 value = panda_file_.GetIdFromPointer(sp.data()).GetOffset();
104 i = literal_vals_num;
105 break;
106 }
107 default: {
108 UNREACHABLE();
109 break;
110 }
111 }
112 cb(value, tag);
113 }
114 }
115
116 } // namespace panda::panda_file
117
118 #endif // LIBPANDAFILE_LITERAL_DATA_ACCESSOR_INL_H
119