• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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