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