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_CODE_DATA_ACCESSOR_INL_H
17 #define LIBPANDAFILE_CODE_DATA_ACCESSOR_INL_H
18
19 #include "code_data_accessor.h"
20
21 namespace panda::panda_file {
22
23 template <class Callback>
EnumerateCatchBlocks(const Callback & cb)24 inline void CodeDataAccessor::TryBlock::EnumerateCatchBlocks(const Callback &cb)
25 {
26 auto sp = catch_blocks_sp_;
27 for (size_t i = 0; i < num_catches_; i++) {
28 CatchBlock catch_block(sp);
29 if (!cb(catch_block)) {
30 return;
31 }
32 sp = sp.SubSpan(catch_block.GetSize());
33 }
34 size_ = sp.data() - data_.data();
35 }
36
SkipCatchBlocks()37 inline void CodeDataAccessor::TryBlock::SkipCatchBlocks()
38 {
39 EnumerateCatchBlocks([](const CatchBlock & /* unused */) { return true; });
40 }
41
42 template <class Callback>
EnumerateTryBlocks(const Callback & cb)43 inline void CodeDataAccessor::EnumerateTryBlocks(const Callback &cb)
44 {
45 auto sp = try_blocks_sp_;
46 for (size_t i = 0; i < tries_size_; i++) {
47 TryBlock try_block(sp);
48 if (!cb(try_block)) {
49 return;
50 }
51 sp = sp.SubSpan(try_block.GetSize());
52 }
53 size_ = panda_file_.GetIdFromPointer(sp.data()).GetOffset() - code_id_.GetOffset();
54 }
55
SkipTryBlocks()56 inline void CodeDataAccessor::SkipTryBlocks()
57 {
58 EnumerateTryBlocks([](const TryBlock & /* unused */) { return true; });
59 }
60
61 // static
GetNumVregs(const File & pf,File::EntityId code_id)62 inline uint32_t CodeDataAccessor::GetNumVregs(const File &pf, File::EntityId code_id)
63 {
64 uint32_t num_vregs_;
65 auto sp = pf.GetSpanFromId(code_id);
66 num_vregs_ = helpers::ReadULeb128(&sp);
67 return num_vregs_;
68 }
69
70 // static
GetInstructions(const File & pf,File::EntityId code_id,uint32_t * vregs)71 inline const uint8_t *CodeDataAccessor::GetInstructions(const File &pf, File::EntityId code_id, uint32_t *vregs)
72 {
73 auto sp = pf.GetSpanFromId(code_id);
74 *vregs = helpers::ReadULeb128(&sp);
75 helpers::SkipULeb128(&sp); // num_args
76 helpers::SkipULeb128(&sp); // code_size
77 helpers::SkipULeb128(&sp); // tries_size
78 return sp.data();
79 }
80
81 // static
GetInstructions(const File & pf,File::EntityId code_id)82 inline const uint8_t *CodeDataAccessor::GetInstructions(const File &pf, File::EntityId code_id)
83 {
84 auto sp = pf.GetSpanFromId(code_id);
85 helpers::SkipULeb128(&sp); // num_vregs
86 helpers::SkipULeb128(&sp); // num_args
87 helpers::SkipULeb128(&sp); // code_size
88 helpers::SkipULeb128(&sp); // tries_size
89 return sp.data();
90 }
91
92 } // namespace panda::panda_file
93
94 #endif // LIBPANDAFILE_CODE_DATA_ACCESSOR_INL_H
95