• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 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 PANDA_RUNTIME_DYN_BUFFER_H
17 #define PANDA_RUNTIME_DYN_BUFFER_H
18 
19 #include <cstring>
20 #include "libpandabase/macros.h"
21 #include "runtime/include/runtime.h"
22 namespace ark {
23 
24 template <typename T>
UnalignedLoad(T const * p)25 inline T UnalignedLoad(T const *p)
26 {
27     struct Wrapper {
28         T x;
29     } __attribute__((packed, aligned(1)));
30     return reinterpret_cast<Wrapper const *>(p)->x;
31 }
32 
33 template <typename T>
UnalignedStore(T * p,T v)34 inline void UnalignedStore(T *p, T v)
35 {
36     struct Wrapper {
37         T x;
38     } __attribute__((packed, aligned(1)));
39     reinterpret_cast<Wrapper *>(p)->x = v;
40 }
41 
42 class DynChunk {
43 public:
44     static constexpr size_t ALLOCATE_MIN_SIZE = 64;
45     static constexpr int FAILURE = -1;
46     static constexpr int SUCCESS = 0;
47 
48     explicit DynChunk() = default;
49 
~DynChunk()50     ~DynChunk()
51     {
52         if (!isInternalBuffer_) {
53             Runtime::GetCurrent()->GetInternalAllocator()->DeleteArray(buf_);
54         }
55     }
56 
57     NO_COPY_SEMANTIC(DynChunk);
58     NO_MOVE_SEMANTIC(DynChunk);
59 
60     int Expand(size_t newSize);
61 
62     int Insert(uint32_t position, size_t len);
63 
64     int Emit(const uint8_t *data, size_t length);
65 
66     int EmitSelf(size_t offset, size_t length);
67 
68     int EmitChar(uint8_t c);
69 
70     int EmitStr(const char *str);
71 
EmitU16(uint16_t data)72     inline int EmitU16(uint16_t data)
73     {
74         return Emit(reinterpret_cast<uint8_t *>(&data), U16_SIZE);
75     }
76 
EmitU32(uint32_t data)77     inline int EmitU32(uint32_t data)
78     {
79         return Emit(reinterpret_cast<uint8_t *>(&data), U32_SIZE);
80     }
81 
EmitU64(uint64_t data)82     inline int EmitU64(uint64_t data)
83     {
84         return Emit(reinterpret_cast<uint8_t *>(&data), U64_SIZE);
85     }
86 
SetError()87     inline void SetError()
88     {
89         error_ = true;
90     }
91 
GetSize()92     inline size_t GetSize() const
93     {
94         return size_;
95     }
96 
GetAllocatedSize()97     inline size_t GetAllocatedSize() const
98     {
99         return allocatedSize_;
100     }
101 
GetError()102     inline bool GetError() const
103     {
104         return error_;
105     }
106 
GetU32(size_t offset)107     inline uint32_t GetU32(size_t offset) const
108     {
109         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
110         return UnalignedLoad(reinterpret_cast<uint32_t *>(buf_ + offset));
111     }
112 
PutU32(size_t offset,uint32_t data)113     inline void PutU32(size_t offset, uint32_t data) const
114     {
115         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
116         UnalignedStore(reinterpret_cast<uint32_t *>(buf_ + offset), data);
117     }
118 
GetU16(size_t offset)119     inline uint32_t GetU16(size_t offset) const
120     {
121         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
122         return UnalignedLoad(reinterpret_cast<uint16_t *>(buf_ + offset));
123     }
124 
PutU16(size_t offset,uint16_t data)125     inline void PutU16(size_t offset, uint16_t data) const
126     {
127         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
128         UnalignedStore(reinterpret_cast<uint16_t *>(buf_ + offset), data);
129     }
130 
GetU8(size_t offset)131     inline uint32_t GetU8(size_t offset) const
132     {
133         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
134         return *(buf_ + offset);
135     }
136 
PutU8(size_t offset,uint8_t data)137     inline void PutU8(size_t offset, uint8_t data) const
138     {
139         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
140         *(buf_ + offset) = data;
141     }
142 
GetBufferOffset()143     ALWAYS_INLINE static inline constexpr uint32_t GetBufferOffset()
144     {
145         return MEMBER_OFFSET(DynChunk, buf_);
146     }
147 
148 private:
149     static constexpr size_t ALLOCATE_MULTIPLIER = 2;
150     static constexpr size_t U16_SIZE = 2;
151     static constexpr size_t U32_SIZE = 4;
152     static constexpr size_t U64_SIZE = 8;
153     friend class RegExpParser;
154     friend class RegExpOpCode;
155     friend class RegExpExecutor;
156 
DynChunk(uint8_t * buf)157     explicit DynChunk(uint8_t *buf) : buf_(buf), isInternalBuffer_(true) {};
158 
159     uint8_t *buf_ {nullptr};
160     bool isInternalBuffer_ {false};
161     size_t size_ {0};
162     size_t allocatedSize_ {0};
163     bool error_ {false};
164 };
165 }  // namespace ark
166 
167 #endif