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