src: replace naive search in Buffer::IndexOf
[platform/upstream/nodejs.git] / src / node.h
1 #ifndef SRC_NODE_H_
2 #define SRC_NODE_H_
3
4 #ifdef _WIN32
5 # ifndef BUILDING_NODE_EXTENSION
6 #   define NODE_EXTERN __declspec(dllexport)
7 # else
8 #   define NODE_EXTERN __declspec(dllimport)
9 # endif
10 #else
11 # define NODE_EXTERN /* nothing */
12 #endif
13
14 #ifdef BUILDING_NODE_EXTENSION
15 # undef BUILDING_V8_SHARED
16 # undef BUILDING_UV_SHARED
17 # define USING_V8_SHARED 1
18 # define USING_UV_SHARED 1
19 #endif
20
21 // This should be defined in make system.
22 // See issue https://github.com/joyent/node/issues/1236
23 #if defined(__MINGW32__) || defined(_MSC_VER)
24 #ifndef _WIN32_WINNT
25 # define _WIN32_WINNT   0x0501
26 #endif
27
28 #ifndef NOMINMAX
29 # define NOMINMAX
30 #endif
31
32 #endif
33
34 #if defined(_MSC_VER)
35 #define PATH_MAX MAX_PATH
36 #endif
37
38 #ifdef _WIN32
39 # define SIGKILL         9
40 #endif
41
42 #include "v8.h"  // NOLINT(build/include_order)
43 #include "node_version.h"  // NODE_MODULE_VERSION
44
45 #define NODE_MAKE_VERSION(major, minor, patch)                                \
46   ((major) * 0x1000 + (minor) * 0x100 + (patch))
47
48 #ifdef __clang__
49 # define NODE_CLANG_AT_LEAST(major, minor, patch)                             \
50   (NODE_MAKE_VERSION(major, minor, patch) <=                                  \
51       NODE_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__))
52 #else
53 # define NODE_CLANG_AT_LEAST(major, minor, patch) (0)
54 #endif
55
56 #ifdef __GNUC__
57 # define NODE_GNUC_AT_LEAST(major, minor, patch)                              \
58   (NODE_MAKE_VERSION(major, minor, patch) <=                                  \
59       NODE_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__))
60 #else
61 # define NODE_GNUC_AT_LEAST(major, minor, patch) (0)
62 #endif
63
64 #if NODE_CLANG_AT_LEAST(2, 9, 0) || NODE_GNUC_AT_LEAST(4, 5, 0)
65 # define NODE_DEPRECATED(message, declarator)                                 \
66     __attribute__((deprecated(message))) declarator
67 #elif defined(_MSC_VER)
68 # define NODE_DEPRECATED(message, declarator)                                 \
69     __declspec(deprecated) declarator
70 #else
71 # define NODE_DEPRECATED(message, declarator)                                 \
72     declarator
73 #endif
74
75 // Forward-declare libuv loop
76 struct uv_loop_s;
77
78 // Forward-declare these functions now to stop MSVS from becoming
79 // terminally confused when it's done in node_internals.h
80 namespace node {
81
82 NODE_EXTERN v8::Local<v8::Value> ErrnoException(v8::Isolate* isolate,
83                                                 int errorno,
84                                                 const char* syscall = NULL,
85                                                 const char* message = NULL,
86                                                 const char* path = NULL);
87 NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
88                                              int errorno,
89                                              const char* syscall = NULL,
90                                              const char* message = NULL,
91                                              const char* path = NULL);
92 NODE_EXTERN v8::Local<v8::Value> UVException(v8::Isolate* isolate,
93                                              int errorno,
94                                              const char* syscall,
95                                              const char* message,
96                                              const char* path,
97                                              const char* dest);
98
99 NODE_DEPRECATED("Use UVException(isolate, ...)",
100                 inline v8::Local<v8::Value> ErrnoException(
101       int errorno,
102       const char* syscall = NULL,
103       const char* message = NULL,
104       const char* path = NULL) {
105   return ErrnoException(v8::Isolate::GetCurrent(),
106                         errorno,
107                         syscall,
108                         message,
109                         path);
110 })
111
112 inline v8::Local<v8::Value> UVException(int errorno,
113                                         const char* syscall = NULL,
114                                         const char* message = NULL,
115                                         const char* path = NULL) {
116   return UVException(v8::Isolate::GetCurrent(),
117                      errorno,
118                      syscall,
119                      message,
120                      path);
121 }
122
123 /*
124  * MakeCallback doesn't have a HandleScope. That means the callers scope
125  * will retain ownership of created handles from MakeCallback and related.
126  * There is by default a wrapping HandleScope before uv_run, if the caller
127  * doesn't have a HandleScope on the stack the global will take ownership
128  * which won't be reaped until the uv loop exits.
129  *
130  * If a uv callback is fired, and there is no enclosing HandleScope in the
131  * cb, you will appear to leak 4-bytes for every invocation. Take heed.
132  */
133
134 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
135     v8::Isolate* isolate,
136     v8::Local<v8::Object> recv,
137     const char* method,
138     int argc,
139     v8::Local<v8::Value>* argv);
140 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
141     v8::Isolate* isolate,
142     v8::Local<v8::Object> recv,
143     v8::Local<v8::String> symbol,
144     int argc,
145     v8::Local<v8::Value>* argv);
146 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
147     v8::Isolate* isolate,
148     v8::Local<v8::Object> recv,
149     v8::Local<v8::Function> callback,
150     int argc,
151     v8::Local<v8::Value>* argv);
152
153 }  // namespace node
154
155 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
156 #include "node_internals.h"
157 #endif
158
159 #include <assert.h>
160 #include <stdint.h>
161
162 #ifndef NODE_STRINGIFY
163 #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)
164 #define NODE_STRINGIFY_HELPER(n) #n
165 #endif
166
167 #ifdef _WIN32
168 // TODO(tjfontaine) consider changing the usage of ssize_t to ptrdiff_t
169 #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
170 typedef intptr_t ssize_t;
171 # define _SSIZE_T_
172 # define _SSIZE_T_DEFINED
173 #endif
174 #else  // !_WIN32
175 # include <sys/types.h>  // size_t, ssize_t
176 #endif  // _WIN32
177
178
179 namespace node {
180
181 NODE_EXTERN extern bool no_deprecation;
182
183 NODE_EXTERN int Start(int argc, char *argv[]);
184 NODE_EXTERN void Init(int* argc,
185                       const char** argv,
186                       int* exec_argc,
187                       const char*** exec_argv);
188
189 class Environment;
190
191 NODE_EXTERN Environment* CreateEnvironment(v8::Isolate* isolate,
192                                            struct uv_loop_s* loop,
193                                            v8::Local<v8::Context> context,
194                                            int argc,
195                                            const char* const* argv,
196                                            int exec_argc,
197                                            const char* const* exec_argv);
198 NODE_EXTERN void LoadEnvironment(Environment* env);
199
200 // NOTE: Calling this is the same as calling
201 // CreateEnvironment() + LoadEnvironment() from above.
202 // `uv_default_loop()` will be passed as `loop`.
203 NODE_EXTERN Environment* CreateEnvironment(v8::Isolate* isolate,
204                                            v8::Local<v8::Context> context,
205                                            int argc,
206                                            const char* const* argv,
207                                            int exec_argc,
208                                            const char* const* exec_argv);
209
210
211 NODE_EXTERN void EmitBeforeExit(Environment* env);
212 NODE_EXTERN int EmitExit(Environment* env);
213 NODE_EXTERN void RunAtExit(Environment* env);
214
215 /* Converts a unixtime to V8 Date */
216 #define NODE_UNIXTIME_V8(t) v8::Date::New(v8::Isolate::GetCurrent(),          \
217     1000 * static_cast<double>(t))
218 #define NODE_V8_UNIXTIME(v) (static_cast<double>((v)->NumberValue())/1000.0);
219
220 // Used to be a macro, hence the uppercase name.
221 #define NODE_DEFINE_CONSTANT(target, constant)                                \
222   do {                                                                        \
223     v8::Isolate* isolate = target->GetIsolate();                              \
224     v8::Local<v8::String> constant_name =                                     \
225         v8::String::NewFromUtf8(isolate, #constant);                          \
226     v8::Local<v8::Number> constant_value =                                    \
227         v8::Number::New(isolate, static_cast<double>(constant));              \
228     v8::PropertyAttribute constant_attributes =                               \
229         static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete);    \
230     (target)->ForceSet(constant_name, constant_value, constant_attributes);   \
231   }                                                                           \
232   while (0)
233
234 // Used to be a macro, hence the uppercase name.
235 template <typename TypeName>
236 inline void NODE_SET_METHOD(const TypeName& recv,
237                             const char* name,
238                             v8::FunctionCallback callback) {
239   v8::Isolate* isolate = v8::Isolate::GetCurrent();
240   v8::HandleScope handle_scope(isolate);
241   v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate,
242                                                                 callback);
243   v8::Local<v8::Function> fn = t->GetFunction();
244   v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name);
245   fn->SetName(fn_name);
246   recv->Set(fn_name, fn);
247 }
248 #define NODE_SET_METHOD node::NODE_SET_METHOD
249
250 // Used to be a macro, hence the uppercase name.
251 // Not a template because it only makes sense for FunctionTemplates.
252 inline void NODE_SET_PROTOTYPE_METHOD(v8::Local<v8::FunctionTemplate> recv,
253                                       const char* name,
254                                       v8::FunctionCallback callback) {
255   v8::Isolate* isolate = v8::Isolate::GetCurrent();
256   v8::HandleScope handle_scope(isolate);
257   v8::Local<v8::Signature> s = v8::Signature::New(isolate, recv);
258   v8::Local<v8::FunctionTemplate> t =
259       v8::FunctionTemplate::New(isolate, callback, v8::Local<v8::Value>(), s);
260   v8::Local<v8::Function> fn = t->GetFunction();
261   recv->PrototypeTemplate()->Set(v8::String::NewFromUtf8(isolate, name), fn);
262   v8::Local<v8::String> fn_name = v8::String::NewFromUtf8(isolate, name);
263   fn->SetName(fn_name);
264 }
265 #define NODE_SET_PROTOTYPE_METHOD node::NODE_SET_PROTOTYPE_METHOD
266
267 enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
268 NODE_EXTERN enum encoding ParseEncoding(
269     v8::Isolate* isolate,
270     v8::Local<v8::Value> encoding_v,
271     enum encoding default_encoding = BINARY);
272 NODE_DEPRECATED("Use ParseEncoding(isolate, ...)",
273                 inline enum encoding ParseEncoding(
274       v8::Local<v8::Value> encoding_v,
275       enum encoding default_encoding = BINARY) {
276   return ParseEncoding(v8::Isolate::GetCurrent(), encoding_v, default_encoding);
277 })
278
279 NODE_EXTERN void FatalException(v8::Isolate* isolate,
280                                 const v8::TryCatch& try_catch);
281
282 NODE_DEPRECATED("Use FatalException(isolate, ...)",
283                 inline void FatalException(const v8::TryCatch& try_catch) {
284   return FatalException(v8::Isolate::GetCurrent(), try_catch);
285 })
286
287 // Don't call with encoding=UCS2.
288 NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
289                                         const char* buf,
290                                         size_t len,
291                                         enum encoding encoding = BINARY);
292
293 // The input buffer should be in host endianness.
294 NODE_EXTERN v8::Local<v8::Value> Encode(v8::Isolate* isolate,
295                                         const uint16_t* buf,
296                                         size_t len);
297
298 NODE_DEPRECATED("Use Encode(isolate, ...)",
299                 inline v8::Local<v8::Value> Encode(
300     const void* buf,
301     size_t len,
302     enum encoding encoding = BINARY) {
303   v8::Isolate* isolate = v8::Isolate::GetCurrent();
304   if (encoding == UCS2) {
305     assert(reinterpret_cast<uintptr_t>(buf) % sizeof(uint16_t) == 0 &&
306            "UCS2 buffer must be aligned on two-byte boundary.");
307     const uint16_t* that = static_cast<const uint16_t*>(buf);
308     return Encode(isolate, that, len / sizeof(*that));
309   }
310   return Encode(isolate, static_cast<const char*>(buf), len, encoding);
311 })
312
313 // Returns -1 if the handle was not valid for decoding
314 NODE_EXTERN ssize_t DecodeBytes(v8::Isolate* isolate,
315                                 v8::Local<v8::Value>,
316                                 enum encoding encoding = BINARY);
317 NODE_DEPRECATED("Use DecodeBytes(isolate, ...)",
318                 inline ssize_t DecodeBytes(
319     v8::Local<v8::Value> val,
320     enum encoding encoding = BINARY) {
321   return DecodeBytes(v8::Isolate::GetCurrent(), val, encoding);
322 })
323
324 // returns bytes written.
325 NODE_EXTERN ssize_t DecodeWrite(v8::Isolate* isolate,
326                                 char* buf,
327                                 size_t buflen,
328                                 v8::Local<v8::Value>,
329                                 enum encoding encoding = BINARY);
330 NODE_DEPRECATED("Use DecodeWrite(isolate, ...)",
331                 inline ssize_t DecodeWrite(char* buf,
332                                            size_t buflen,
333                                            v8::Local<v8::Value> val,
334                                            enum encoding encoding = BINARY) {
335   return DecodeWrite(v8::Isolate::GetCurrent(), buf, buflen, val, encoding);
336 })
337
338 #ifdef _WIN32
339 NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(
340     v8::Isolate* isolate,
341     int errorno,
342     const char *syscall = NULL,
343     const char *msg = "",
344     const char *path = NULL);
345
346 NODE_DEPRECATED("Use WinapiErrnoException(isolate, ...)",
347                 inline v8::Local<v8::Value> WinapiErrnoException(int errorno,
348     const char *syscall = NULL,  const char *msg = "",
349     const char *path = NULL) {
350   return WinapiErrnoException(v8::Isolate::GetCurrent(),
351                               errorno,
352                               syscall,
353                               msg,
354                               path);
355 })
356 #endif
357
358 const char *signo_string(int errorno);
359
360
361 typedef void (*addon_register_func)(
362     v8::Local<v8::Object> exports,
363     v8::Local<v8::Value> module,
364     void* priv);
365
366 typedef void (*addon_context_register_func)(
367     v8::Local<v8::Object> exports,
368     v8::Local<v8::Value> module,
369     v8::Local<v8::Context> context,
370     void* priv);
371
372 #define NM_F_BUILTIN 0x01
373 #define NM_F_LINKED  0x02
374
375 struct node_module {
376   int nm_version;
377   unsigned int nm_flags;
378   void* nm_dso_handle;
379   const char* nm_filename;
380   node::addon_register_func nm_register_func;
381   node::addon_context_register_func nm_context_register_func;
382   const char* nm_modname;
383   void* nm_priv;
384   struct node_module* nm_link;
385 };
386
387 node_module* get_builtin_module(const char *name);
388 node_module* get_linked_module(const char *name);
389
390 extern "C" NODE_EXTERN void node_module_register(void* mod);
391
392 #ifdef _WIN32
393 # define NODE_MODULE_EXPORT __declspec(dllexport)
394 #else
395 # define NODE_MODULE_EXPORT __attribute__((visibility("default")))
396 #endif
397
398 #if defined(_MSC_VER)
399 #pragma section(".CRT$XCU", read)
400 #define NODE_C_CTOR(fn)                                               \
401   static void __cdecl fn(void);                                       \
402   __declspec(dllexport, allocate(".CRT$XCU"))                         \
403       void (__cdecl*fn ## _)(void) = fn;                              \
404   static void __cdecl fn(void)
405 #else
406 #define NODE_C_CTOR(fn)                                               \
407   static void fn(void) __attribute__((constructor));                  \
408   static void fn(void)
409 #endif
410
411 #define NODE_MODULE_X(modname, regfunc, priv, flags)                  \
412   extern "C" {                                                        \
413     static node::node_module _module =                                \
414     {                                                                 \
415       NODE_MODULE_VERSION,                                            \
416       flags,                                                          \
417       NULL,                                                           \
418       __FILE__,                                                       \
419       (node::addon_register_func) (regfunc),                          \
420       NULL,                                                           \
421       NODE_STRINGIFY(modname),                                        \
422       priv,                                                           \
423       NULL                                                            \
424     };                                                                \
425     NODE_C_CTOR(_register_ ## modname) {                              \
426       node_module_register(&_module);                                 \
427     }                                                                 \
428   }
429
430 #define NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, priv, flags)    \
431   extern "C" {                                                        \
432     static node::node_module _module =                                \
433     {                                                                 \
434       NODE_MODULE_VERSION,                                            \
435       flags,                                                          \
436       NULL,                                                           \
437       __FILE__,                                                       \
438       NULL,                                                           \
439       (node::addon_context_register_func) (regfunc),                  \
440       NODE_STRINGIFY(modname),                                        \
441       priv,                                                           \
442       NULL                                                            \
443     };                                                                \
444     NODE_C_CTOR(_register_ ## modname) {                              \
445       node_module_register(&_module);                                 \
446     }                                                                 \
447   }
448
449 #define NODE_MODULE(modname, regfunc)                                 \
450   NODE_MODULE_X(modname, regfunc, NULL, 0)
451
452 #define NODE_MODULE_CONTEXT_AWARE(modname, regfunc)                   \
453   NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0)
454
455 #define NODE_MODULE_CONTEXT_AWARE_BUILTIN(modname, regfunc)           \
456   NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, NM_F_BUILTIN)   \
457
458 /*
459  * For backward compatibility in add-on modules.
460  */
461 #define NODE_MODULE_DECL /* nothing */
462
463 /* Called after the event loop exits but before the VM is disposed.
464  * Callbacks are run in reverse order of registration, i.e. newest first.
465  */
466 NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = 0);
467
468 }  // namespace node
469
470 #endif  // SRC_NODE_H_