GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/out/../src/util.h Lines: 30 31 96.8 %
Date: 2016-09-05 Branches: 74 116 63.8 %

Line Branch Exec Source
1
#ifndef SRC_UTIL_H_
2
#define SRC_UTIL_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "v8.h"
7
8
#include <assert.h>
9
#include <signal.h>
10
#include <stddef.h>
11
#include <stdio.h>
12
#include <stdlib.h>
13
14
// OSX 10.9 defaults to libc++ which provides a C++11 <type_traits> header.
15
#if defined(__APPLE__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1090
16
#define USE_TR1_TYPE_TRAITS
17
#endif
18
19
#ifdef USE_TR1_TYPE_TRAITS
20
#include <tr1/type_traits>  // NOLINT(build/c++tr1)
21
#else
22
#include <type_traits>  // std::remove_reference
23
#endif
24
25
namespace node {
26
27
#ifdef __GNUC__
28
#define NO_RETURN __attribute__((noreturn))
29
#else
30
#define NO_RETURN
31
#endif
32
33
// The slightly odd function signature for Assert() is to ease
34
// instruction cache pressure in calls from ASSERT and CHECK.
35
NO_RETURN void Abort();
36
NO_RETURN void Assert(const char* const (*args)[4]);
37
void DumpBacktrace(FILE* fp);
38
39
#ifdef USE_TR1_TYPE_TRAITS
40
template <typename T> using remove_reference = std::tr1::remove_reference<T>;
41
#else
42
template <typename T> using remove_reference = std::remove_reference<T>;
43
#endif
44
45
#define FIXED_ONE_BYTE_STRING(isolate, string)                                \
46
  (node::OneByteString((isolate), (string), sizeof(string) - 1))
47
48
#define DISALLOW_COPY_AND_ASSIGN(TypeName)                                    \
49
  void operator=(const TypeName&) = delete;                                   \
50
  void operator=(TypeName&&) = delete;                                        \
51
  TypeName(const TypeName&) = delete;                                         \
52
  TypeName(TypeName&&) = delete
53
54
// Windows 8+ does not like abort() in Release mode
55
#ifdef _WIN32
56
#define ABORT_NO_BACKTRACE() raise(SIGABRT)
57
#else
58
#define ABORT_NO_BACKTRACE() abort()
59
#endif
60
61
#define ABORT() node::Abort()
62
63
#ifdef __GNUC__
64
#define LIKELY(expr) __builtin_expect(!!(expr), 1)
65
#define UNLIKELY(expr) __builtin_expect(!!(expr), 0)
66
#define PRETTY_FUNCTION_NAME __PRETTY_FUNCTION__
67
#else
68
#define LIKELY(expr) expr
69
#define UNLIKELY(expr) expr
70
#define PRETTY_FUNCTION_NAME ""
71
#endif
72
73
#define STRINGIFY_(x) #x
74
#define STRINGIFY(x) STRINGIFY_(x)
75
76
#define CHECK(expr)                                                           \
77
  do {                                                                        \
78
    if (UNLIKELY(!(expr))) {                                                  \
79
      static const char* const args[] = { __FILE__, STRINGIFY(__LINE__),      \
80
                                          #expr, PRETTY_FUNCTION_NAME };      \
81
      node::Assert(&args);                                                    \
82
    }                                                                         \
83
  } while (0)
84
85
// FIXME(bnoordhuis) cctests don't link in node::Abort() and node::Assert().
86
#ifdef GTEST_DONT_DEFINE_ASSERT_EQ
87
#undef ABORT
88
#undef CHECK
89
#define ABORT ABORT_NO_BACKTRACE
90
#define CHECK assert
91
#endif
92
93
#ifdef NDEBUG
94
#define ASSERT(expr)
95
#else
96
#define ASSERT(expr) CHECK(expr)
97
#endif
98
99
#define ASSERT_EQ(a, b) ASSERT((a) == (b))
100
#define ASSERT_GE(a, b) ASSERT((a) >= (b))
101
#define ASSERT_GT(a, b) ASSERT((a) > (b))
102
#define ASSERT_LE(a, b) ASSERT((a) <= (b))
103
#define ASSERT_LT(a, b) ASSERT((a) < (b))
104
#define ASSERT_NE(a, b) ASSERT((a) != (b))
105
106
#define CHECK_EQ(a, b) CHECK((a) == (b))
107
#define CHECK_GE(a, b) CHECK((a) >= (b))
108
#define CHECK_GT(a, b) CHECK((a) > (b))
109
#define CHECK_LE(a, b) CHECK((a) <= (b))
110
#define CHECK_LT(a, b) CHECK((a) < (b))
111
#define CHECK_NE(a, b) CHECK((a) != (b))
112
113
#define UNREACHABLE() ABORT()
114
115
#define ASSIGN_OR_RETURN_UNWRAP(ptr, obj, ...)                                \
116
  do {                                                                        \
117
    *ptr =                                                                    \
118
        Unwrap<typename node::remove_reference<decltype(**ptr)>::type>(obj);  \
119
    if (*ptr == nullptr)                                                      \
120
      return __VA_ARGS__;                                                     \
121
  } while (0)
122
123
// TAILQ-style intrusive list node.
124
template <typename T>
125
class ListNode;
126
127
template <typename T>
128
using ListNodeMember = ListNode<T> T::*;
129
130
// VS 2013 doesn't understand dependent templates.
131
#ifdef _MSC_VER
132
#define ListNodeMember(T) ListNodeMember
133
#else
134
#define ListNodeMember(T) ListNodeMember<T>
135
#endif
136
137
// TAILQ-style intrusive list head.
138
template <typename T, ListNodeMember(T) M>
139
class ListHead;
140
141
template <typename T>
142
class ListNode {
143
 public:
144
  inline ListNode();
145
  inline ~ListNode();
146
  inline void Remove();
147
  inline bool IsEmpty() const;
148
149
 private:
150
  template <typename U, ListNodeMember(U) M> friend class ListHead;
151
  ListNode* prev_;
152
  ListNode* next_;
153
  DISALLOW_COPY_AND_ASSIGN(ListNode);
154
};
155
156
template <typename T, ListNodeMember(T) M>
157
class ListHead {
158
 public:
159
  class Iterator {
160
   public:
161
    inline T* operator*() const;
162
    inline const Iterator& operator++();
163
    inline bool operator!=(const Iterator& that) const;
164
165
   private:
166
    friend class ListHead;
167
    inline explicit Iterator(ListNode<T>* node);
168
    ListNode<T>* node_;
169
  };
170
171
17192
  inline ListHead() = default;
172
  inline ~ListHead();
173
  inline void MoveBack(ListHead* that);
174
  inline void PushBack(T* element);
175
  inline void PushFront(T* element);
176
  inline bool IsEmpty() const;
177
  inline T* PopFront();
178
  inline Iterator begin() const;
179
  inline Iterator end() const;
180
181
 private:
182
  ListNode<T> head_;
183
  DISALLOW_COPY_AND_ASSIGN(ListHead);
184
};
185
186
// The helper is for doing safe downcasts from base types to derived types.
187
template <typename Inner, typename Outer>
188
class ContainerOfHelper {
189
 public:
190
  inline ContainerOfHelper(Inner Outer::*field, Inner* pointer);
191
  template <typename TypeName>
192
  inline operator TypeName*() const;
193
 private:
194
  Outer* const pointer_;
195
};
196
197
// Calculate the address of the outer (i.e. embedding) struct from
198
// the interior pointer to a data member.
199
template <typename Inner, typename Outer>
200
inline ContainerOfHelper<Inner, Outer> ContainerOf(Inner Outer::*field,
201
                                                   Inner* pointer);
202
203
// If persistent.IsWeak() == false, then do not call persistent.Reset()
204
// while the returned Local<T> is still in scope, it will destroy the
205
// reference to the object.
206
template <class TypeName>
207
inline v8::Local<TypeName> PersistentToLocal(
208
    v8::Isolate* isolate,
209
    const v8::Persistent<TypeName>& persistent);
210
211
// Unchecked conversion from a non-weak Persistent<T> to Local<TLocal<T>,
212
// use with care!
213
//
214
// Do not call persistent.Reset() while the returned Local<T> is still in
215
// scope, it will destroy the reference to the object.
216
template <class TypeName>
217
inline v8::Local<TypeName> StrongPersistentToLocal(
218
    const v8::Persistent<TypeName>& persistent);
219
220
template <class TypeName>
221
inline v8::Local<TypeName> WeakPersistentToLocal(
222
    v8::Isolate* isolate,
223
    const v8::Persistent<TypeName>& persistent);
224
225
// Convenience wrapper around v8::String::NewFromOneByte().
226
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
227
                                           const char* data,
228
                                           int length = -1);
229
230
// For the people that compile with -funsigned-char.
231
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
232
                                           const signed char* data,
233
                                           int length = -1);
234
235
inline v8::Local<v8::String> OneByteString(v8::Isolate* isolate,
236
                                           const unsigned char* data,
237
                                           int length = -1);
238
239
inline void Wrap(v8::Local<v8::Object> object, void* pointer);
240
241
inline void ClearWrap(v8::Local<v8::Object> object);
242
243
template <typename TypeName>
244
inline TypeName* Unwrap(v8::Local<v8::Object> object);
245
246
inline void SwapBytes(uint16_t* dst, const uint16_t* src, size_t buflen);
247
248
// tolower() is locale-sensitive.  Use ToLower() instead.
249
inline char ToLower(char c);
250
251
// strcasecmp() is locale-sensitive.  Use StringEqualNoCase() instead.
252
inline bool StringEqualNoCase(const char* a, const char* b);
253
254
// strncasecmp() is locale-sensitive.  Use StringEqualNoCaseN() instead.
255
inline bool StringEqualNoCaseN(const char* a, const char* b, size_t length);
256
257
// Allocates an array of member type T. For up to kStackStorageSize items,
258
// the stack is used, otherwise malloc().
259
template <typename T, size_t kStackStorageSize = 1024>
260
class MaybeStackBuffer {
261
 public:
262
  const T* out() const {
263
    return buf_;
264
  }
265
266
  T* out() {
267
    return buf_;
268
  }
269
270
  // operator* for compatibility with `v8::String::(Utf8)Value`
271
  T* operator*() {
272
    return buf_;
273
  }
274
275
  const T* operator*() const {
276
    return buf_;
277
  }
278
279
  T& operator[](size_t index) {
280
420
    CHECK_LT(index, length());
281
420
    return buf_[index];
282
  }
283
284
  const T& operator[](size_t index) const {
285
    CHECK_LT(index, length());
286
    return buf_[index];
287
  }
288
289
  size_t length() const {
290
    return length_;
291
  }
292
293
  // Call to make sure enough space for `storage` entries is available.
294
  // There can only be 1 call to AllocateSufficientStorage or Invalidate
295
  // per instance.
296
333859
  void AllocateSufficientStorage(size_t storage) {
297

333859
    if (storage <= kStackStorageSize) {
298
333716
      buf_ = buf_st_;
299
    } else {
300
      // Guard against overflow.
301
      CHECK_LE(storage, sizeof(T) * storage);
302
303
143
      buf_ = static_cast<T*>(malloc(sizeof(T) * storage));
304

143
      CHECK_NE(buf_, nullptr);
305
    }
306
307
    // Remember how much was allocated to check against that in SetLength().
308
333859
    length_ = storage;
309
333859
  }
310
311
  void SetLength(size_t length) {
312
    // length_ stores how much memory was allocated.
313

331665
    CHECK_LE(length, length_);
314
331665
    length_ = length;
315
  }
316
317
331312
  void SetLengthAndZeroTerminate(size_t length) {
318
    // length_ stores how much memory was allocated.
319

331312
    CHECK_LE(length + 1, length_);
320
662624
    SetLength(length);
321
322
    // T() is 0 for integer types, nullptr for pointers, etc.
323
331312
    buf_[length] = T();
324
331312
  }
325
326
  // Make derefencing this object return nullptr.
327
  // Calling this is mutually exclusive with calling
328
  // AllocateSufficientStorage.
329
  void Invalidate() {
330
4
    CHECK_EQ(buf_, buf_st_);
331
4
    length_ = 0;
332
4
    buf_ = nullptr;
333
  }
334
335
335028
  MaybeStackBuffer() : length_(0), buf_(buf_st_) {
336
    // Default to a zero-length, null-terminated buffer.
337
335028
    buf_[0] = T();
338
  }
339
340
4
  explicit MaybeStackBuffer(size_t storage) : MaybeStackBuffer() {
341
4
    AllocateSufficientStorage(storage);
342
  }
343
344
  ~MaybeStackBuffer() {
345























335028
    if (buf_ != buf_st_)
346
147
      free(buf_);
347
335028
  }
348
349
 private:
350
  size_t length_;
351
  T* buf_;
352
  T buf_st_[kStackStorageSize];
353
};
354
355
454269
class Utf8Value : public MaybeStackBuffer<char> {
356
 public:
357
  explicit Utf8Value(v8::Isolate* isolate, v8::Local<v8::Value> value);
358
};
359
360
66
class TwoByteValue : public MaybeStackBuffer<uint16_t> {
361
 public:
362
  explicit TwoByteValue(v8::Isolate* isolate, v8::Local<v8::Value> value);
363
};
364
365
209687
class BufferValue : public MaybeStackBuffer<char> {
366
 public:
367
  explicit BufferValue(v8::Isolate* isolate, v8::Local<v8::Value> value);
368
};
369
370
}  // namespace node
371
372
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
373
374
#endif  // SRC_UTIL_H_