22 #ifndef SRC_UTIL_INL_H_ 23 #define SRC_UTIL_INL_H_ 25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 32 #define BSWAP_2(x) _byteswap_ushort(x) 33 #define BSWAP_4(x) _byteswap_ulong(x) 34 #define BSWAP_8(x) _byteswap_uint64(x) 36 #define BSWAP_2(x) ((x) << 8) | ((x) >> 8) 38 (((x) & 0xFF) << 24) | \ 39 (((x) & 0xFF00) << 8) | \ 40 (((x) >> 8) & 0xFF00) | \ 43 (((x) & 0xFF00000000000000ull) >> 56) | \ 44 (((x) & 0x00FF000000000000ull) >> 40) | \ 45 (((x) & 0x0000FF0000000000ull) >> 24) | \ 46 (((x) & 0x000000FF00000000ull) >> 8) | \ 47 (((x) & 0x00000000FF000000ull) << 8) | \ 48 (((x) & 0x0000000000FF0000ull) << 24) | \ 49 (((x) & 0x000000000000FF00ull) << 40) | \ 50 (((x) & 0x00000000000000FFull) << 56) 56 ListNode<T>::ListNode() : prev_(this), next_(this) {}
59 ListNode<T>::~ListNode() {
64 void ListNode<T>::Remove() {
72 bool ListNode<T>::IsEmpty()
const {
76 template <
typename T, ListNode<T> (T::*M)>
77 ListHead<T, M>::Iterator::Iterator(ListNode<T>*
node) : node_(node) {}
79 template <
typename T, ListNode<T> (T::*M)>
80 T* ListHead<T, M>::Iterator::operator*()
const {
81 return ContainerOf(M, node_);
84 template <
typename T, ListNode<T> (T::*M)>
85 const typename ListHead<T, M>::Iterator&
86 ListHead<T, M>::Iterator::operator++() {
91 template <
typename T, ListNode<T> (T::*M)>
92 bool ListHead<T, M>::Iterator::operator!=(
const Iterator& that)
const {
93 return node_ != that.node_;
96 template <
typename T, ListNode<T> (T::*M)>
97 ListHead<T, M>::~ListHead() {
98 while (IsEmpty() ==
false)
99 head_.next_->Remove();
102 template <
typename T, ListNode<T> (T::*M)>
103 void ListHead<T, M>::MoveBack(ListHead* that) {
106 ListNode<T>* to = &that->head_;
107 head_.next_->prev_ = to->prev_;
108 to->prev_->next_ = head_.next_;
109 head_.prev_->next_ = to;
110 to->prev_ = head_.prev_;
111 head_.prev_ = &head_;
112 head_.next_ = &head_;
115 template <
typename T, ListNode<T> (T::*M)>
116 void ListHead<T, M>::PushBack(T* element) {
117 ListNode<T>* that = &(element->*M);
118 head_.prev_->next_ = that;
119 that->prev_ = head_.prev_;
120 that->next_ = &head_;
124 template <
typename T, ListNode<T> (T::*M)>
125 void ListHead<T, M>::PushFront(T* element) {
126 ListNode<T>* that = &(element->*M);
127 head_.next_->prev_ = that;
128 that->prev_ = &head_;
129 that->next_ = head_.next_;
133 template <
typename T, ListNode<T> (T::*M)>
134 bool ListHead<T, M>::IsEmpty()
const {
135 return head_.IsEmpty();
138 template <
typename T, ListNode<T> (T::*M)>
139 T* ListHead<T, M>::PopFront() {
142 ListNode<T>*
node = head_.next_;
144 return ContainerOf(M, node);
147 template <
typename T, ListNode<T> (T::*M)>
148 typename ListHead<T, M>::Iterator ListHead<T, M>::begin()
const {
149 return Iterator(head_.next_);
152 template <
typename T, ListNode<T> (T::*M)>
153 typename ListHead<T, M>::Iterator ListHead<T, M>::end()
const {
154 return Iterator(
const_cast<ListNode<T>*
>(&head_));
157 template <
typename Inner,
typename Outer>
158 ContainerOfHelper<Inner, Outer>::ContainerOfHelper(Inner Outer::*field,
160 : pointer_(reinterpret_cast<Outer*>(
161 reinterpret_cast<uintptr_t>(pointer) -
162 reinterpret_cast<uintptr_t>(&(static_cast<Outer*>(0)->*field)))) {
165 template <
typename Inner,
typename Outer>
166 template <
typename TypeName>
167 ContainerOfHelper<Inner, Outer>::operator TypeName*()
const {
168 return static_cast<TypeName*
>(pointer_);
171 template <
typename Inner,
typename Outer>
172 inline ContainerOfHelper<Inner, Outer> ContainerOf(Inner Outer::*field,
174 return ContainerOfHelper<Inner, Outer>(field, pointer);
177 template <
class TypeName>
178 inline v8::Local<TypeName> PersistentToLocal(
179 v8::Isolate* isolate,
180 const v8::Persistent<TypeName>& persistent) {
181 if (persistent.IsWeak()) {
182 return WeakPersistentToLocal(isolate, persistent);
184 return StrongPersistentToLocal(persistent);
188 template <
class TypeName>
189 inline v8::Local<TypeName> StrongPersistentToLocal(
190 const v8::Persistent<TypeName>& persistent) {
191 return *
reinterpret_cast<v8::Local<TypeName>*
>(
192 const_cast<v8::Persistent<TypeName>*
>(&persistent));
195 template <
class TypeName>
196 inline v8::Local<TypeName> WeakPersistentToLocal(
197 v8::Isolate* isolate,
198 const v8::Persistent<TypeName>& persistent) {
202 inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
205 return v8::String::NewFromOneByte(isolate,
206 reinterpret_cast<const uint8_t*>(data),
207 v8::NewStringType::kNormal,
208 length).ToLocalChecked();
211 inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
212 const signed char* data,
214 return v8::String::NewFromOneByte(isolate,
215 reinterpret_cast<const uint8_t*>(data),
216 v8::NewStringType::kNormal,
217 length).ToLocalChecked();
220 inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
221 const unsigned char* data,
223 return v8::String::NewFromOneByte(isolate,
224 reinterpret_cast<const uint8_t*>(data),
225 v8::NewStringType::kNormal,
226 length).ToLocalChecked();
229 template <
typename TypeName>
230 void Wrap(v8::Local<v8::Object>
object, TypeName* pointer) {
231 CHECK_EQ(
false,
object.IsEmpty());
232 CHECK_GT(object->InternalFieldCount(), 0);
233 object->SetAlignedPointerInInternalField(0, pointer);
236 void ClearWrap(v8::Local<v8::Object>
object) {
237 Wrap<void>(object,
nullptr);
240 template <
typename TypeName>
241 TypeName* Unwrap(v8::Local<v8::Object>
object) {
242 CHECK_EQ(
false,
object.IsEmpty());
243 CHECK_GT(object->InternalFieldCount(), 0);
244 void* pointer =
object->GetAlignedPointerFromInternalField(0);
245 return static_cast<TypeName*
>(pointer);
248 void SwapBytes16(
char* data,
size_t nbytes) {
249 CHECK_EQ(nbytes % 2, 0);
251 #if defined(_MSC_VER) 252 int align =
reinterpret_cast<uintptr_t
>(
data) %
sizeof(uint16_t);
255 uint16_t* data16 =
reinterpret_cast<uint16_t*
>(
data);
256 size_t len16 = nbytes /
sizeof(*data16);
257 for (
size_t i = 0; i < len16; i++) {
258 data16[i] = BSWAP_2(data16[i]);
265 for (
size_t i = 0; i < nbytes; i +=
sizeof(temp)) {
266 memcpy(&temp, &data[i],
sizeof(temp));
267 temp = BSWAP_2(temp);
268 memcpy(&data[i], &temp,
sizeof(temp));
272 void SwapBytes32(
char* data,
size_t nbytes) {
273 CHECK_EQ(nbytes % 4, 0);
275 #if defined(_MSC_VER) 276 int align =
reinterpret_cast<uintptr_t
>(
data) %
sizeof(uint32_t);
279 uint32_t* data32 =
reinterpret_cast<uint32_t*
>(
data);
280 size_t len32 = nbytes /
sizeof(*data32);
281 for (
size_t i = 0; i < len32; i++) {
282 data32[i] = BSWAP_4(data32[i]);
289 for (
size_t i = 0; i < nbytes; i +=
sizeof(temp)) {
290 memcpy(&temp, &data[i],
sizeof(temp));
291 temp = BSWAP_4(temp);
292 memcpy(&data[i], &temp,
sizeof(temp));
296 void SwapBytes64(
char* data,
size_t nbytes) {
297 CHECK_EQ(nbytes % 8, 0);
299 #if defined(_MSC_VER) 300 int align =
reinterpret_cast<uintptr_t
>(
data) %
sizeof(uint64_t);
303 uint64_t* data64 =
reinterpret_cast<uint64_t*
>(
data);
304 size_t len64 = nbytes /
sizeof(*data64);
305 for (
size_t i = 0; i < len64; i++) {
306 data64[i] = BSWAP_8(data64[i]);
313 for (
size_t i = 0; i < nbytes; i +=
sizeof(temp)) {
314 memcpy(&temp, &data[i],
sizeof(temp));
315 temp = BSWAP_8(temp);
316 memcpy(&data[i], &temp,
sizeof(temp));
320 char ToLower(
char c) {
321 return c >=
'A' && c <=
'Z' ? c + (
'a' -
'A') : c;
324 bool StringEqualNoCase(
const char*
a,
const char* b) {
330 }
while (ToLower(*a++) == ToLower(*b++));
334 bool StringEqualNoCaseN(
const char* a,
const char* b,
size_t length) {
335 for (
size_t i = 0; i < length; i++) {
336 if (ToLower(a[i]) != ToLower(b[i]))
344 inline size_t MultiplyWithOverflowCheck(
size_t a,
size_t b) {
347 CHECK_EQ(b, ret / a);
359 template <
typename T>
360 T* UncheckedRealloc(T* pointer,
size_t n) {
361 size_t full_size = MultiplyWithOverflowCheck(
sizeof(T), n);
363 if (full_size == 0) {
368 void* allocated = realloc(pointer, full_size);
370 if (UNLIKELY(allocated ==
nullptr)) {
373 allocated = realloc(pointer, full_size);
376 return static_cast<T*
>(allocated);
380 template <
typename T>
381 inline T* UncheckedMalloc(
size_t n) {
383 return UncheckedRealloc<T>(
nullptr,
n);
386 template <
typename T>
387 inline T* UncheckedCalloc(
size_t n) {
389 MultiplyWithOverflowCheck(
sizeof(T), n);
390 return static_cast<T*
>(calloc(n,
sizeof(T)));
393 template <
typename T>
394 inline T* Realloc(T* pointer,
size_t n) {
395 T* ret = UncheckedRealloc(pointer, n);
396 if (n > 0) CHECK_NE(ret,
nullptr);
400 template <
typename T>
401 inline T* Malloc(
size_t n) {
402 T* ret = UncheckedMalloc<T>(
n);
403 if (n > 0) CHECK_NE(ret,
nullptr);
407 template <
typename T>
408 inline T* Calloc(
size_t n) {
409 T* ret = UncheckedCalloc<T>(
n);
410 if (n > 0) CHECK_NE(ret,
nullptr);
415 inline char* Malloc(
size_t n) {
return Malloc<char>(
n); }
416 inline char* Calloc(
size_t n) {
return Calloc<char>(
n); }
417 inline char* UncheckedMalloc(
size_t n) {
return UncheckedMalloc<char>(
n); }
418 inline char* UncheckedCalloc(
size_t n) {
return UncheckedCalloc<char>(
n); }
422 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 424 #endif // SRC_UTIL_INL_H_ union node::cares_wrap::@8::CaresAsyncData::@0 data
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
void LowMemoryNotification()