GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/node-core-coverage/node-core-coverage/workdir/node/src/node_internals.h Lines: 22 23 95.7 %
Date: 2016-07-23 Branches: 16 26 61.5 %

Line Exec Source
1
#ifndef SRC_NODE_INTERNALS_H_
2
#define SRC_NODE_INTERNALS_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "node.h"
7
#include "util.h"
8
#include "util-inl.h"
9
#include "uv.h"
10
#include "v8.h"
11
12
#include <stdint.h>
13
#include <stdlib.h>
14
15
struct sockaddr;
16
17
// Variation on NODE_DEFINE_CONSTANT that sets a String value.
18
#define NODE_DEFINE_STRING_CONSTANT(target, name, constant)                   \
19
  do {                                                                        \
20
    v8::Isolate* isolate = target->GetIsolate();                              \
21
    v8::Local<v8::String> constant_name =                                     \
22
        v8::String::NewFromUtf8(isolate, name);                               \
23
    v8::Local<v8::String> constant_value =                                    \
24
        v8::String::NewFromUtf8(isolate, constant);                           \
25
    v8::PropertyAttribute constant_attributes =                               \
26
        static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);    \
27
    target->DefineOwnProperty(isolate->GetCurrentContext(),                   \
28
                              constant_name,                                  \
29
                              constant_value,                                 \
30
                              constant_attributes).FromJust();                \
31
  } while (0)
32
33
namespace node {
34
35
// Set in node.cc by ParseArgs when --preserve-symlinks is used.
36
// Used in node_config.cc to set a constant on process.binding('config')
37
// that is used by lib/module.js
38
extern bool config_preserve_symlinks;
39
40
// Forward declaration
41
class Environment;
42
43
// If persistent.IsWeak() == false, then do not call persistent.Reset()
44
// while the returned Local<T> is still in scope, it will destroy the
45
// reference to the object.
46
template <class TypeName>
47
inline v8::Local<TypeName> PersistentToLocal(
48
    v8::Isolate* isolate,
49
    const v8::Persistent<TypeName>& persistent);
50
51
// Call with valid HandleScope and while inside Context scope.
52
v8::Local<v8::Value> MakeCallback(Environment* env,
53
                                   v8::Local<v8::Object> recv,
54
                                   const char* method,
55
                                   int argc = 0,
56
                                   v8::Local<v8::Value>* argv = nullptr);
57
58
// Call with valid HandleScope and while inside Context scope.
59
v8::Local<v8::Value> MakeCallback(Environment* env,
60
                                   v8::Local<v8::Object> recv,
61
                                   v8::Local<v8::String> symbol,
62
                                   int argc = 0,
63
                                   v8::Local<v8::Value>* argv = nullptr);
64
65
// Call with valid HandleScope and while inside Context scope.
66
v8::Local<v8::Value> MakeCallback(Environment* env,
67
                                   v8::Local<v8::Value> recv,
68
                                   v8::Local<v8::Function> callback,
69
                                   int argc = 0,
70
                                   v8::Local<v8::Value>* argv = nullptr);
71
72
// Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object.
73
// Sets address and port properties on the info object and returns it.
74
// If |info| is omitted, a new object is returned.
75
v8::Local<v8::Object> AddressToJS(
76
    Environment* env,
77
    const sockaddr* addr,
78
    v8::Local<v8::Object> info = v8::Local<v8::Object>());
79
80
template <typename T, int (*F)(const typename T::HandleType*, sockaddr*, int*)>
81
1638
void GetSockOrPeerName(const v8::FunctionCallbackInfo<v8::Value>& args) {
82
1638
  T* const wrap = Unwrap<T>(args.Holder());
83
1638
  if (wrap == nullptr)
84
    return args.GetReturnValue().Set(UV_EBADF);
85
1638
  CHECK(args[0]->IsObject());
86
  sockaddr_storage storage;
87
1638
  int addrlen = sizeof(storage);
88
1638
  sockaddr* const addr = reinterpret_cast<sockaddr*>(&storage);
89
1638
  const int err = F(&wrap->handle_, addr, &addrlen);
90
1638
  if (err == 0)
91
3270
    AddressToJS(wrap->env(), addr, args[0].As<v8::Object>());
92
3276
  args.GetReturnValue().Set(err);
93
}
94
95
void SignalExit(int signo);
96
#ifdef __POSIX__
97
void RegisterSignalHandler(int signal,
98
                           void (*handler)(int signal),
99
                           bool reset_handler = false);
100
#endif
101
102
#ifdef _WIN32
103
// emulate snprintf() on windows, _snprintf() doesn't zero-terminate the buffer
104
// on overflow...
105
// VS 2015 added a standard conform snprintf
106
#if defined( _MSC_VER ) && (_MSC_VER < 1900)
107
#include <stdarg.h>
108
inline static int snprintf(char *buffer, size_t n, const char *format, ...) {
109
  va_list argp;
110
  va_start(argp, format);
111
  int ret = _vscprintf(format, argp);
112
  vsnprintf_s(buffer, n, _TRUNCATE, format, argp);
113
  va_end(argp);
114
  return ret;
115
}
116
#endif
117
#endif
118
119
#if defined(_MSC_VER) && _MSC_VER < 1900
120
#define arraysize(a) (sizeof(a) / sizeof(*a))  // Workaround for VS 2013.
121
#else
122
template <typename T, size_t N>
123
constexpr size_t arraysize(const T(&)[N]) { return N; }
124
#endif
125
126
#ifndef ROUND_UP
127
# define ROUND_UP(a, b) ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a))
128
#endif
129
130
#ifdef __GNUC__
131
# define MUST_USE_RESULT __attribute__((warn_unused_result))
132
#else
133
# define MUST_USE_RESULT
134
#endif
135
136
bool IsExceptionDecorated(Environment* env, v8::Local<v8::Value> er);
137
138
enum ErrorHandlingMode { FATAL_ERROR, CONTEXTIFY_ERROR };
139
void AppendExceptionLine(Environment* env,
140
                         v8::Local<v8::Value> er,
141
                         v8::Local<v8::Message> message,
142
                         enum ErrorHandlingMode mode);
143
144
NO_RETURN void FatalError(const char* location, const char* message);
145
146
v8::Local<v8::Value> BuildStatsObject(Environment* env, const uv_stat_t* s);
147
148
void SetupProcessObject(Environment* env,
149
                        int argc,
150
                        const char* const* argv,
151
                        int exec_argc,
152
                        const char* const* exec_argv);
153
154
enum Endianness {
155
  kLittleEndian,  // _Not_ LITTLE_ENDIAN, clashes with endian.h.
156
  kBigEndian
157
};
158
159
inline enum Endianness GetEndianness() {
160
  // Constant-folded by the compiler.
161
  const union {
162
    uint8_t u8[2];
163
    uint16_t u16;
164
  } u = {
165
    { 1, 0 }
166
7093
  };
167
7093
  return u.u16 == 1 ? kLittleEndian : kBigEndian;
168
}
169
170
inline bool IsLittleEndian() {
171
  return GetEndianness() == kLittleEndian;
172
}
173
174
inline bool IsBigEndian() {
175
  return GetEndianness() == kBigEndian;
176
}
177
178
2736
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
179
 public:
180
  inline uint32_t* zero_fill_field() { return &zero_fill_field_; }
181
182
  virtual void* Allocate(size_t size);  // Defined in src/node.cc
183
323
  virtual void* AllocateUninitialized(size_t size) { return malloc(size); }
184
29638
  virtual void Free(void* data, size_t) { free(data); }
185
186
 private:
187
  uint32_t zero_fill_field_ = 1;  // Boolean but exposed as uint32 to JS land.
188
};
189
190
// Clear any domain and/or uncaughtException handlers to force the error's
191
// propagation and shutdown the process. Use this to force the process to exit
192
// by clearing all callbacks that could handle the error.
193
void ClearFatalExceptionHandlers(Environment* env);
194
195
enum NodeInstanceType { MAIN, WORKER, REMOTE_DEBUG_SERVER };
196
197
class NodeInstanceData {
198
 public:
199
  NodeInstanceData(NodeInstanceType node_instance_type,
200
                   uv_loop_t* event_loop,
201
                   int argc,
202
                   const char** argv,
203
                   int exec_argc,
204
                   const char** exec_argv,
205
                   bool use_debug_agent_flag)
206
      : node_instance_type_(node_instance_type),
207
        exit_code_(1),
208
        event_loop_(event_loop),
209
        argc_(argc),
210
        argv_(argv),
211
        exec_argc_(exec_argc),
212
        exec_argv_(exec_argv),
213
1557
        use_debug_agent_flag_(use_debug_agent_flag) {
214
1557
    CHECK_NE(event_loop_, nullptr);
215
  }
216
217
  uv_loop_t* event_loop() const {
218
    return event_loop_;
219
  }
220
221
  int exit_code() {
222
1368
    CHECK(is_main());
223
1368
    return exit_code_;
224
  }
225
226
  void set_exit_code(int exit_code) {
227
1368
    CHECK(is_main());
228
1368
    exit_code_ = exit_code;
229
  }
230
231
  bool is_main() {
232
    return node_instance_type_ == MAIN;
233
  }
234
235
  bool is_worker() {
236
    return node_instance_type_ == WORKER;
237
  }
238
239
  bool is_remote_debug_server() {
240
    return node_instance_type_ == REMOTE_DEBUG_SERVER;
241
  }
242
243
  int argc() {
244
    return argc_;
245
  }
246
247
  const char** argv() {
248
    return argv_;
249
  }
250
251
  int exec_argc() {
252
    return exec_argc_;
253
  }
254
255
  const char** exec_argv() {
256
    return exec_argv_;
257
  }
258
259
  bool use_debug_agent() {
260
3038
    return is_main() && use_debug_agent_flag_;
261
  }
262
263
 private:
264
  const NodeInstanceType node_instance_type_;
265
  int exit_code_;
266
  uv_loop_t* const event_loop_;
267
  const int argc_;
268
  const char** argv_;
269
  const int exec_argc_;
270
  const char** exec_argv_;
271
  const bool use_debug_agent_flag_;
272
273
  DISALLOW_COPY_AND_ASSIGN(NodeInstanceData);
274
};
275
276
namespace Buffer {
277
v8::MaybeLocal<v8::Object> Copy(Environment* env, const char* data, size_t len);
278
v8::MaybeLocal<v8::Object> New(Environment* env, size_t size);
279
// Takes ownership of |data|.
280
v8::MaybeLocal<v8::Object> New(Environment* env,
281
                               char* data,
282
                               size_t length,
283
                               void (*callback)(char* data, void* hint),
284
                               void* hint);
285
// Takes ownership of |data|.  Must allocate |data| with malloc() or realloc()
286
// because ArrayBufferAllocator::Free() deallocates it again with free().
287
// Mixing operator new and free() is undefined behavior so don't do that.
288
v8::MaybeLocal<v8::Object> New(Environment* env, char* data, size_t length);
289
}  // namespace Buffer
290
291
}  // namespace node
292
293
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
294
295
#endif  // SRC_NODE_INTERNALS_H_