UNPKG

89.7 kBtext/x-cView Raw
1/*********************************************************************
2 * NAN - Native Abstractions for Node.js
3 *
4 * Copyright (c) 2018 NAN contributors:
5 * - Rod Vagg <https://github.com/rvagg>
6 * - Benjamin Byholm <https://github.com/kkoopa>
7 * - Trevor Norris <https://github.com/trevnorris>
8 * - Nathan Rajlich <https://github.com/TooTallNate>
9 * - Brett Lawson <https://github.com/brett19>
10 * - Ben Noordhuis <https://github.com/bnoordhuis>
11 * - David Siegel <https://github.com/agnat>
12 * - Michael Ira Krufky <https://github.com/mkrufky>
13 *
14 * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
15 *
16 * Version 2.19.0: current Node 21.6.2, Node 0.12: 0.12.18, Node 0.10: 0.10.48, iojs: 3.3.1
17 *
18 * See https://github.com/nodejs/nan for the latest update to this file
19 **********************************************************************************/
20
21#ifndef NAN_H_
22#define NAN_H_
23
24#include <node_version.h>
25
26#define NODE_0_10_MODULE_VERSION 11
27#define NODE_0_12_MODULE_VERSION 14
28#define ATOM_0_21_MODULE_VERSION 41
29#define IOJS_1_0_MODULE_VERSION 42
30#define IOJS_1_1_MODULE_VERSION 43
31#define IOJS_2_0_MODULE_VERSION 44
32#define IOJS_3_0_MODULE_VERSION 45
33#define NODE_4_0_MODULE_VERSION 46
34#define NODE_5_0_MODULE_VERSION 47
35#define NODE_6_0_MODULE_VERSION 48
36#define NODE_7_0_MODULE_VERSION 51
37#define NODE_8_0_MODULE_VERSION 57
38#define NODE_9_0_MODULE_VERSION 59
39#define NODE_10_0_MODULE_VERSION 64
40#define NODE_11_0_MODULE_VERSION 67
41#define NODE_12_0_MODULE_VERSION 72
42#define NODE_13_0_MODULE_VERSION 79
43#define NODE_14_0_MODULE_VERSION 83
44#define NODE_15_0_MODULE_VERSION 88
45#define NODE_16_0_MODULE_VERSION 93
46#define NODE_17_0_MODULE_VERSION 102
47#define NODE_18_0_MODULE_VERSION 108
48#define NODE_19_0_MODULE_VERSION 111
49#define NODE_20_0_MODULE_VERSION 115
50
51#ifdef _MSC_VER
52# define NAN_HAS_CPLUSPLUS_11 (_MSC_VER >= 1800)
53#else
54# define NAN_HAS_CPLUSPLUS_11 (__cplusplus >= 201103L)
55#endif
56
57#if NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION && !NAN_HAS_CPLUSPLUS_11
58# error This version of node/NAN/v8 requires a C++11 compiler
59#endif
60
61#include <uv.h>
62#include <node.h>
63#include <node_buffer.h>
64#include <node_object_wrap.h>
65#include <algorithm>
66#include <cstring>
67#include <climits>
68#include <cstdlib>
69#include <utility>
70#if defined(_MSC_VER)
71# pragma warning( push )
72# pragma warning( disable : 4530 )
73# include <queue>
74# include <string>
75# include <vector>
76# pragma warning( pop )
77#else
78# include <queue>
79# include <string>
80# include <vector>
81#endif
82
83// uv helpers
84#ifdef UV_VERSION_MAJOR
85# ifndef UV_VERSION_PATCH
86# define UV_VERSION_PATCH 0
87# endif
88# define NAUV_UVVERSION ((UV_VERSION_MAJOR << 16) | \
89 (UV_VERSION_MINOR << 8) | \
90 (UV_VERSION_PATCH))
91#else
92# define NAUV_UVVERSION 0x000b00
93#endif
94
95#if NAUV_UVVERSION < 0x000b0b
96# ifdef WIN32
97# include <windows.h>
98# else
99# include <pthread.h>
100# endif
101#endif
102
103namespace Nan {
104
105#define NAN_CONCAT(a, b) NAN_CONCAT_HELPER(a, b)
106#define NAN_CONCAT_HELPER(a, b) a##b
107
108#define NAN_INLINE inline // TODO(bnoordhuis) Remove in v3.0.0.
109
110#if defined(__GNUC__) && \
111 !(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
112# define NAN_DEPRECATED __attribute__((deprecated))
113#elif defined(_MSC_VER) && \
114 !(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
115# define NAN_DEPRECATED __declspec(deprecated)
116#else
117# define NAN_DEPRECATED
118#endif
119
120#if NAN_HAS_CPLUSPLUS_11
121# define NAN_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete;
122# define NAN_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete;
123# define NAN_DISALLOW_MOVE(CLASS) \
124 CLASS(CLASS&&) = delete; /* NOLINT(build/c++11) */ \
125 void operator=(CLASS&&) = delete;
126#else
127# define NAN_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&);
128# define NAN_DISALLOW_COPY(CLASS) CLASS(const CLASS&);
129# define NAN_DISALLOW_MOVE(CLASS)
130#endif
131
132#define NAN_DISALLOW_ASSIGN_COPY(CLASS) \
133 NAN_DISALLOW_ASSIGN(CLASS) \
134 NAN_DISALLOW_COPY(CLASS)
135
136#define NAN_DISALLOW_ASSIGN_MOVE(CLASS) \
137 NAN_DISALLOW_ASSIGN(CLASS) \
138 NAN_DISALLOW_MOVE(CLASS)
139
140#define NAN_DISALLOW_COPY_MOVE(CLASS) \
141 NAN_DISALLOW_COPY(CLASS) \
142 NAN_DISALLOW_MOVE(CLASS)
143
144#define NAN_DISALLOW_ASSIGN_COPY_MOVE(CLASS) \
145 NAN_DISALLOW_ASSIGN(CLASS) \
146 NAN_DISALLOW_COPY(CLASS) \
147 NAN_DISALLOW_MOVE(CLASS)
148
149#define TYPE_CHECK(T, S) \
150 while (false) { \
151 *(static_cast<T *volatile *>(0)) = static_cast<S*>(0); \
152 }
153
154//=== RegistrationFunction =====================================================
155
156#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
157 typedef v8::Handle<v8::Object> ADDON_REGISTER_FUNCTION_ARGS_TYPE;
158#else
159 typedef v8::Local<v8::Object> ADDON_REGISTER_FUNCTION_ARGS_TYPE;
160#endif
161
162#define NAN_MODULE_INIT(name) \
163 void name(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target)
164
165#if NODE_MAJOR_VERSION >= 10 || \
166 NODE_MAJOR_VERSION == 9 && NODE_MINOR_VERSION >= 3
167#define NAN_MODULE_WORKER_ENABLED(module_name, registration) \
168 extern "C" NODE_MODULE_EXPORT void \
169 NAN_CONCAT(node_register_module_v, NODE_MODULE_VERSION)( \
170 v8::Local<v8::Object> exports, v8::Local<v8::Value> module, \
171 v8::Local<v8::Context> context) \
172 { \
173 registration(exports); \
174 }
175#else
176#define NAN_MODULE_WORKER_ENABLED(module_name, registration) \
177 NODE_MODULE(module_name, registration)
178#endif
179
180//=== CallbackInfo =============================================================
181
182#include "nan_callbacks.h" // NOLINT(build/include)
183
184//==============================================================================
185
186#if (NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION)
187typedef v8::Script UnboundScript;
188typedef v8::Script BoundScript;
189#else
190typedef v8::UnboundScript UnboundScript;
191typedef v8::Script BoundScript;
192#endif
193
194#if (NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION)
195typedef v8::String::ExternalAsciiStringResource
196 ExternalOneByteStringResource;
197#else
198typedef v8::String::ExternalOneByteStringResource
199 ExternalOneByteStringResource;
200#endif
201
202#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
203template<typename T>
204class NonCopyablePersistentTraits :
205 public v8::NonCopyablePersistentTraits<T> {};
206template<typename T>
207class CopyablePersistentTraits :
208 public v8::CopyablePersistentTraits<T> {};
209
210template<typename T>
211class PersistentBase :
212 public v8::PersistentBase<T> {};
213
214template<typename T, typename M = v8::NonCopyablePersistentTraits<T> >
215class Persistent;
216#else
217template<typename T> class NonCopyablePersistentTraits;
218template<typename T> class PersistentBase;
219template<typename T, typename P> class WeakCallbackData;
220template<typename T, typename M = NonCopyablePersistentTraits<T> >
221class Persistent;
222#endif // NODE_MODULE_VERSION
223
224template<typename T>
225class Maybe {
226 public:
227 inline bool IsNothing() const { return !has_value_; }
228 inline bool IsJust() const { return has_value_; }
229
230 inline T ToChecked() const { return FromJust(); }
231 inline void Check() const { FromJust(); }
232
233 inline bool To(T* out) const {
234 if (IsJust()) *out = value_;
235 return IsJust();
236 }
237
238 inline T FromJust() const {
239#if defined(V8_ENABLE_CHECKS)
240 assert(IsJust() && "FromJust is Nothing");
241#endif // V8_ENABLE_CHECKS
242 return value_;
243 }
244
245 inline T FromMaybe(const T& default_value) const {
246 return has_value_ ? value_ : default_value;
247 }
248
249 inline bool operator==(const Maybe &other) const {
250 return (IsJust() == other.IsJust()) &&
251 (!IsJust() || FromJust() == other.FromJust());
252 }
253
254 inline bool operator!=(const Maybe &other) const {
255 return !operator==(other);
256 }
257
258#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
259 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
260 // Allow implicit conversions from v8::Maybe<T> to Nan::Maybe<T>.
261 Maybe(const v8::Maybe<T>& that) // NOLINT(runtime/explicit)
262 : has_value_(that.IsJust())
263 , value_(that.FromMaybe(T())) {}
264#endif
265
266 private:
267 Maybe() : has_value_(false) {}
268 explicit Maybe(const T& t) : has_value_(true), value_(t) {}
269 bool has_value_;
270 T value_;
271
272 template<typename U>
273 friend Maybe<U> Nothing();
274 template<typename U>
275 friend Maybe<U> Just(const U& u);
276};
277
278template<typename T>
279inline Maybe<T> Nothing() {
280 return Maybe<T>();
281}
282
283template<typename T>
284inline Maybe<T> Just(const T& t) {
285 return Maybe<T>(t);
286}
287
288#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
289 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
290# include "nan_maybe_43_inl.h" // NOLINT(build/include)
291#else
292# include "nan_maybe_pre_43_inl.h" // NOLINT(build/include)
293#endif
294
295#include "nan_converters.h" // NOLINT(build/include)
296#include "nan_new.h" // NOLINT(build/include)
297
298#if NAUV_UVVERSION < 0x000b17
299#define NAUV_WORK_CB(func) \
300 void func(uv_async_t *async, int)
301#else
302#define NAUV_WORK_CB(func) \
303 void func(uv_async_t *async)
304#endif
305
306#if NAUV_UVVERSION >= 0x000b0b
307
308typedef uv_key_t nauv_key_t;
309
310inline int nauv_key_create(nauv_key_t *key) {
311 return uv_key_create(key);
312}
313
314inline void nauv_key_delete(nauv_key_t *key) {
315 uv_key_delete(key);
316}
317
318inline void* nauv_key_get(nauv_key_t *key) {
319 return uv_key_get(key);
320}
321
322inline void nauv_key_set(nauv_key_t *key, void *value) {
323 uv_key_set(key, value);
324}
325
326#else
327
328/* Implement thread local storage for older versions of libuv.
329 * This is essentially a backport of libuv commit 5d2434bf
330 * written by Ben Noordhuis, adjusted for names and inline.
331 */
332
333#ifndef WIN32
334
335typedef pthread_key_t nauv_key_t;
336
337inline int nauv_key_create(nauv_key_t* key) {
338 return -pthread_key_create(key, NULL);
339}
340
341inline void nauv_key_delete(nauv_key_t* key) {
342 if (pthread_key_delete(*key))
343 abort();
344}
345
346inline void* nauv_key_get(nauv_key_t* key) {
347 return pthread_getspecific(*key);
348}
349
350inline void nauv_key_set(nauv_key_t* key, void* value) {
351 if (pthread_setspecific(*key, value))
352 abort();
353}
354
355#else
356
357typedef struct {
358 DWORD tls_index;
359} nauv_key_t;
360
361inline int nauv_key_create(nauv_key_t* key) {
362 key->tls_index = TlsAlloc();
363 if (key->tls_index == TLS_OUT_OF_INDEXES)
364 return UV_ENOMEM;
365 return 0;
366}
367
368inline void nauv_key_delete(nauv_key_t* key) {
369 if (TlsFree(key->tls_index) == FALSE)
370 abort();
371 key->tls_index = TLS_OUT_OF_INDEXES;
372}
373
374inline void* nauv_key_get(nauv_key_t* key) {
375 void* value = TlsGetValue(key->tls_index);
376 if (value == NULL)
377 if (GetLastError() != ERROR_SUCCESS)
378 abort();
379 return value;
380}
381
382inline void nauv_key_set(nauv_key_t* key, void* value) {
383 if (TlsSetValue(key->tls_index, value) == FALSE)
384 abort();
385}
386
387#endif
388#endif
389
390#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
391template<typename T>
392v8::Local<T> New(v8::Handle<T>);
393#endif
394
395#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
396 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
397 typedef v8::WeakCallbackType WeakCallbackType;
398#else
399struct WeakCallbackType {
400 enum E {kParameter, kInternalFields};
401 E type;
402 WeakCallbackType(E other) : type(other) {} // NOLINT(runtime/explicit)
403 inline bool operator==(E other) { return other == this->type; }
404 inline bool operator!=(E other) { return !operator==(other); }
405};
406#endif
407
408template<typename P> class WeakCallbackInfo;
409
410#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
411# include "nan_persistent_12_inl.h" // NOLINT(build/include)
412#else
413# include "nan_persistent_pre_12_inl.h" // NOLINT(build/include)
414#endif
415
416namespace imp {
417 static const size_t kMaxLength = 0x3fffffff;
418 // v8::String::REPLACE_INVALID_UTF8 was introduced
419 // in node.js v0.10.29 and v0.8.27.
420#if NODE_MAJOR_VERSION > 0 || \
421 NODE_MINOR_VERSION > 10 || \
422 NODE_MINOR_VERSION == 10 && NODE_PATCH_VERSION >= 29 || \
423 NODE_MINOR_VERSION == 8 && NODE_PATCH_VERSION >= 27
424 static const unsigned kReplaceInvalidUtf8 = v8::String::REPLACE_INVALID_UTF8;
425#else
426 static const unsigned kReplaceInvalidUtf8 = 0;
427#endif
428} // end of namespace imp
429
430//=== HandleScope ==============================================================
431
432class HandleScope {
433 v8::HandleScope scope;
434
435 public:
436#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
437 inline HandleScope() : scope(v8::Isolate::GetCurrent()) {}
438 inline static int NumberOfHandles() {
439 return v8::HandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
440 }
441#else
442 inline HandleScope() : scope() {}
443 inline static int NumberOfHandles() {
444 return v8::HandleScope::NumberOfHandles();
445 }
446#endif
447
448 private:
449 // Make it hard to create heap-allocated or illegal handle scopes by
450 // disallowing certain operations.
451 HandleScope(const HandleScope &);
452 void operator=(const HandleScope &);
453 void *operator new(size_t size);
454 void operator delete(void *, size_t) {
455 abort();
456 }
457};
458
459class EscapableHandleScope {
460 public:
461#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
462 inline EscapableHandleScope() : scope(v8::Isolate::GetCurrent()) {}
463
464 inline static int NumberOfHandles() {
465 return v8::EscapableHandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
466 }
467
468 template<typename T>
469 inline v8::Local<T> Escape(v8::Local<T> value) {
470 return scope.Escape(value);
471 }
472
473 private:
474 v8::EscapableHandleScope scope;
475#else
476 inline EscapableHandleScope() : scope() {}
477
478 inline static int NumberOfHandles() {
479 return v8::HandleScope::NumberOfHandles();
480 }
481
482 template<typename T>
483 inline v8::Local<T> Escape(v8::Local<T> value) {
484 return scope.Close(value);
485 }
486
487 private:
488 v8::HandleScope scope;
489#endif
490
491 private:
492 // Make it hard to create heap-allocated or illegal handle scopes by
493 // disallowing certain operations.
494 EscapableHandleScope(const EscapableHandleScope &);
495 void operator=(const EscapableHandleScope &);
496 void *operator new(size_t size);
497 void operator delete(void *, size_t) {
498 abort();
499 }
500};
501
502//=== TryCatch =================================================================
503
504class TryCatch {
505 v8::TryCatch try_catch_;
506 friend void FatalException(const TryCatch&);
507
508 public:
509#if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
510 TryCatch() : try_catch_(v8::Isolate::GetCurrent()) {}
511#endif
512
513 inline bool HasCaught() const { return try_catch_.HasCaught(); }
514
515 inline bool CanContinue() const { return try_catch_.CanContinue(); }
516
517 inline v8::Local<v8::Value> ReThrow() {
518#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
519 return New(try_catch_.ReThrow());
520#else
521 return try_catch_.ReThrow();
522#endif
523 }
524
525 inline v8::Local<v8::Value> Exception() const {
526 return try_catch_.Exception();
527 }
528
529#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
530 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
531 inline v8::MaybeLocal<v8::Value> StackTrace() const {
532 v8::Isolate *isolate = v8::Isolate::GetCurrent();
533 v8::EscapableHandleScope scope(isolate);
534 return scope.Escape(try_catch_.StackTrace(isolate->GetCurrentContext())
535 .FromMaybe(v8::Local<v8::Value>()));
536 }
537#else
538 inline MaybeLocal<v8::Value> StackTrace() const {
539 return try_catch_.StackTrace();
540 }
541#endif
542
543 inline v8::Local<v8::Message> Message() const {
544 return try_catch_.Message();
545 }
546
547 inline void Reset() { try_catch_.Reset(); }
548
549 inline void SetVerbose(bool value) { try_catch_.SetVerbose(value); }
550
551 inline void SetCaptureMessage(bool value) {
552 try_catch_.SetCaptureMessage(value);
553 }
554};
555
556v8::Local<v8::Value> MakeCallback(v8::Local<v8::Object> target,
557 v8::Local<v8::Function> func,
558 int argc,
559 v8::Local<v8::Value>* argv);
560v8::Local<v8::Value> MakeCallback(v8::Local<v8::Object> target,
561 v8::Local<v8::String> symbol,
562 int argc,
563 v8::Local<v8::Value>* argv);
564v8::Local<v8::Value> MakeCallback(v8::Local<v8::Object> target,
565 const char* method,
566 int argc,
567 v8::Local<v8::Value>* argv);
568
569// === AsyncResource ===========================================================
570
571class AsyncResource {
572 public:
573 AsyncResource(
574 v8::Local<v8::String> name
575 , v8::Local<v8::Object> resource = New<v8::Object>()) {
576#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
577 v8::Isolate* isolate = v8::Isolate::GetCurrent();
578
579 if (resource.IsEmpty()) {
580 resource = New<v8::Object>();
581 }
582
583 context = node::EmitAsyncInit(isolate, resource, name);
584#endif
585 }
586
587 AsyncResource(
588 const char* name
589 , v8::Local<v8::Object> resource = New<v8::Object>()) {
590#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
591 v8::Isolate* isolate = v8::Isolate::GetCurrent();
592
593 if (resource.IsEmpty()) {
594 resource = New<v8::Object>();
595 }
596
597 v8::Local<v8::String> name_string =
598 New<v8::String>(name).ToLocalChecked();
599 context = node::EmitAsyncInit(isolate, resource, name_string);
600#endif
601 }
602
603 ~AsyncResource() {
604#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
605 v8::Isolate* isolate = v8::Isolate::GetCurrent();
606 node::EmitAsyncDestroy(isolate, context);
607#endif
608 }
609
610 inline MaybeLocal<v8::Value> runInAsyncScope(
611 v8::Local<v8::Object> target
612 , v8::Local<v8::Function> func
613 , int argc
614 , v8::Local<v8::Value>* argv) {
615#if NODE_MODULE_VERSION < NODE_9_0_MODULE_VERSION
616 return MakeCallback(target, func, argc, argv);
617#else
618 return node::MakeCallback(
619 v8::Isolate::GetCurrent(), target, func, argc, argv, context);
620#endif
621 }
622
623 inline MaybeLocal<v8::Value> runInAsyncScope(
624 v8::Local<v8::Object> target
625 , v8::Local<v8::String> symbol
626 , int argc
627 , v8::Local<v8::Value>* argv) {
628#if NODE_MODULE_VERSION < NODE_9_0_MODULE_VERSION
629 return MakeCallback(target, symbol, argc, argv);
630#else
631 return node::MakeCallback(
632 v8::Isolate::GetCurrent(), target, symbol, argc, argv, context);
633#endif
634 }
635
636 inline MaybeLocal<v8::Value> runInAsyncScope(
637 v8::Local<v8::Object> target
638 , const char* method
639 , int argc
640 , v8::Local<v8::Value>* argv) {
641#if NODE_MODULE_VERSION < NODE_9_0_MODULE_VERSION
642 return MakeCallback(target, method, argc, argv);
643#else
644 return node::MakeCallback(
645 v8::Isolate::GetCurrent(), target, method, argc, argv, context);
646#endif
647 }
648
649 private:
650 NAN_DISALLOW_ASSIGN_COPY_MOVE(AsyncResource)
651#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
652 node::async_context context;
653#endif
654};
655
656inline uv_loop_t* GetCurrentEventLoop() {
657#if NODE_MAJOR_VERSION >= 10 || \
658 NODE_MAJOR_VERSION == 9 && NODE_MINOR_VERSION >= 3 || \
659 NODE_MAJOR_VERSION == 8 && NODE_MINOR_VERSION >= 10
660 return node::GetCurrentEventLoop(v8::Isolate::GetCurrent());
661#else
662 return uv_default_loop();
663#endif
664}
665
666//============ =================================================================
667
668/* node 0.12 */
669#if NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION
670 inline
671 void SetCounterFunction(v8::CounterLookupCallback cb) {
672 v8::Isolate::GetCurrent()->SetCounterFunction(cb);
673 }
674
675 inline
676 void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
677 v8::Isolate::GetCurrent()->SetCreateHistogramFunction(cb);
678 }
679
680 inline
681 void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
682 v8::Isolate::GetCurrent()->SetAddHistogramSampleFunction(cb);
683 }
684
685#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
686 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
687 inline bool IdleNotification(int idle_time_in_ms) {
688 return v8::Isolate::GetCurrent()->IdleNotificationDeadline(
689 idle_time_in_ms * 0.001);
690 }
691# else
692 inline bool IdleNotification(int idle_time_in_ms) {
693 return v8::Isolate::GetCurrent()->IdleNotification(idle_time_in_ms);
694 }
695#endif
696
697 inline void LowMemoryNotification() {
698 v8::Isolate::GetCurrent()->LowMemoryNotification();
699 }
700
701 inline void ContextDisposedNotification() {
702 v8::Isolate::GetCurrent()->ContextDisposedNotification();
703 }
704#else
705 inline
706 void SetCounterFunction(v8::CounterLookupCallback cb) {
707 v8::V8::SetCounterFunction(cb);
708 }
709
710 inline
711 void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
712 v8::V8::SetCreateHistogramFunction(cb);
713 }
714
715 inline
716 void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
717 v8::V8::SetAddHistogramSampleFunction(cb);
718 }
719
720 inline bool IdleNotification(int idle_time_in_ms) {
721 return v8::V8::IdleNotification(idle_time_in_ms);
722 }
723
724 inline void LowMemoryNotification() {
725 v8::V8::LowMemoryNotification();
726 }
727
728 inline void ContextDisposedNotification() {
729 v8::V8::ContextDisposedNotification();
730 }
731#endif
732
733#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION) // Node 0.12
734 inline v8::Local<v8::Primitive> Undefined() {
735# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
736 EscapableHandleScope scope;
737 return scope.Escape(New(v8::Undefined(v8::Isolate::GetCurrent())));
738# else
739 return v8::Undefined(v8::Isolate::GetCurrent());
740# endif
741 }
742
743 inline v8::Local<v8::Primitive> Null() {
744# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
745 EscapableHandleScope scope;
746 return scope.Escape(New(v8::Null(v8::Isolate::GetCurrent())));
747# else
748 return v8::Null(v8::Isolate::GetCurrent());
749# endif
750 }
751
752 inline v8::Local<v8::Boolean> True() {
753# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
754 EscapableHandleScope scope;
755 return scope.Escape(New(v8::True(v8::Isolate::GetCurrent())));
756# else
757 return v8::True(v8::Isolate::GetCurrent());
758# endif
759 }
760
761 inline v8::Local<v8::Boolean> False() {
762# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
763 EscapableHandleScope scope;
764 return scope.Escape(New(v8::False(v8::Isolate::GetCurrent())));
765# else
766 return v8::False(v8::Isolate::GetCurrent());
767# endif
768 }
769
770 inline v8::Local<v8::String> EmptyString() {
771 return v8::String::Empty(v8::Isolate::GetCurrent());
772 }
773
774 inline int AdjustExternalMemory(int bc) {
775 return static_cast<int>(
776 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
777 }
778
779 inline void SetTemplate(
780 v8::Local<v8::Template> templ
781 , const char *name
782 , v8::Local<v8::Data> value) {
783 templ->Set(v8::Isolate::GetCurrent(), name, value);
784 }
785
786 inline void SetTemplate(
787 v8::Local<v8::Template> templ
788 , v8::Local<v8::String> name
789 , v8::Local<v8::Data> value
790 , v8::PropertyAttribute attributes) {
791 templ->Set(name, value, attributes);
792 }
793
794 inline v8::Local<v8::Context> GetCurrentContext() {
795 return v8::Isolate::GetCurrent()->GetCurrentContext();
796 }
797
798 inline void* GetInternalFieldPointer(
799 v8::Local<v8::Object> object
800 , int index) {
801 return object->GetAlignedPointerFromInternalField(index);
802 }
803
804 inline void SetInternalFieldPointer(
805 v8::Local<v8::Object> object
806 , int index
807 , void* value) {
808 object->SetAlignedPointerInInternalField(index, value);
809 }
810
811# define NAN_GC_CALLBACK(name) \
812 void name(v8::Isolate *isolate, v8::GCType type, v8::GCCallbackFlags flags)
813
814#if NODE_MODULE_VERSION <= NODE_4_0_MODULE_VERSION
815 typedef v8::Isolate::GCEpilogueCallback GCEpilogueCallback;
816 typedef v8::Isolate::GCPrologueCallback GCPrologueCallback;
817#else
818 typedef v8::Isolate::GCCallback GCEpilogueCallback;
819 typedef v8::Isolate::GCCallback GCPrologueCallback;
820#endif
821
822 inline void AddGCEpilogueCallback(
823 GCEpilogueCallback callback
824 , v8::GCType gc_type_filter = v8::kGCTypeAll) {
825 v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);
826 }
827
828 inline void RemoveGCEpilogueCallback(
829 GCEpilogueCallback callback) {
830 v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);
831 }
832
833 inline void AddGCPrologueCallback(
834 GCPrologueCallback callback
835 , v8::GCType gc_type_filter = v8::kGCTypeAll) {
836 v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);
837 }
838
839 inline void RemoveGCPrologueCallback(
840 GCPrologueCallback callback) {
841 v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);
842 }
843
844 inline void GetHeapStatistics(
845 v8::HeapStatistics *heap_statistics) {
846 v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);
847 }
848
849# define X(NAME) \
850 inline v8::Local<v8::Value> NAME(const char *msg) { \
851 EscapableHandleScope scope; \
852 return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked())); \
853 } \
854 \
855 inline \
856 v8::Local<v8::Value> NAME(v8::Local<v8::String> msg) { \
857 return v8::Exception::NAME(msg); \
858 } \
859 \
860 inline void Throw ## NAME(const char *msg) { \
861 HandleScope scope; \
862 v8::Isolate::GetCurrent()->ThrowException( \
863 v8::Exception::NAME(New(msg).ToLocalChecked())); \
864 } \
865 \
866 inline void Throw ## NAME(v8::Local<v8::String> msg) { \
867 HandleScope scope; \
868 v8::Isolate::GetCurrent()->ThrowException( \
869 v8::Exception::NAME(msg)); \
870 }
871
872 X(Error)
873 X(RangeError)
874 X(ReferenceError)
875 X(SyntaxError)
876 X(TypeError)
877
878# undef X
879
880 inline void ThrowError(v8::Local<v8::Value> error) {
881 v8::Isolate::GetCurrent()->ThrowException(error);
882 }
883
884 inline MaybeLocal<v8::Object> NewBuffer(
885 char *data
886 , size_t length
887#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
888 , node::Buffer::FreeCallback callback
889#else
890 , node::smalloc::FreeCallback callback
891#endif
892 , void *hint
893 ) {
894 // arbitrary buffer lengths requires
895 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
896 assert(length <= imp::kMaxLength && "too large buffer");
897#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
898 return node::Buffer::New(
899 v8::Isolate::GetCurrent(), data, length, callback, hint);
900#else
901 return node::Buffer::New(v8::Isolate::GetCurrent(), data, length, callback,
902 hint);
903#endif
904 }
905
906 inline MaybeLocal<v8::Object> CopyBuffer(
907 const char *data
908 , uint32_t size
909 ) {
910 // arbitrary buffer lengths requires
911 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
912 assert(size <= imp::kMaxLength && "too large buffer");
913#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
914 return node::Buffer::Copy(
915 v8::Isolate::GetCurrent(), data, size);
916#else
917 return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
918#endif
919 }
920
921 inline MaybeLocal<v8::Object> NewBuffer(uint32_t size) {
922 // arbitrary buffer lengths requires
923 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
924 assert(size <= imp::kMaxLength && "too large buffer");
925#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
926 return node::Buffer::New(
927 v8::Isolate::GetCurrent(), size);
928#else
929 return node::Buffer::New(v8::Isolate::GetCurrent(), size);
930#endif
931 }
932
933 inline MaybeLocal<v8::Object> NewBuffer(
934 char* data
935 , uint32_t size
936 ) {
937 // arbitrary buffer lengths requires
938 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
939 assert(size <= imp::kMaxLength && "too large buffer");
940#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
941 return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
942#else
943 return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
944#endif
945 }
946
947#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
948 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
949 inline MaybeLocal<v8::String>
950 NewOneByteString(const uint8_t * value, int length = -1) {
951 return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), value,
952 v8::NewStringType::kNormal, length);
953 }
954
955 inline MaybeLocal<BoundScript> CompileScript(
956 v8::Local<v8::String> s
957 , const v8::ScriptOrigin& origin
958 ) {
959 v8::Isolate *isolate = v8::Isolate::GetCurrent();
960 v8::EscapableHandleScope scope(isolate);
961 v8::ScriptCompiler::Source source(s, origin);
962 return scope.Escape(
963 v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &source)
964 .FromMaybe(v8::Local<BoundScript>()));
965 }
966
967 inline MaybeLocal<BoundScript> CompileScript(
968 v8::Local<v8::String> s
969 ) {
970 v8::Isolate *isolate = v8::Isolate::GetCurrent();
971 v8::EscapableHandleScope scope(isolate);
972 v8::ScriptCompiler::Source source(s);
973 return scope.Escape(
974 v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &source)
975 .FromMaybe(v8::Local<BoundScript>()));
976 }
977
978 inline MaybeLocal<v8::Value> RunScript(
979 v8::Local<UnboundScript> script
980 ) {
981 v8::Isolate *isolate = v8::Isolate::GetCurrent();
982 v8::EscapableHandleScope scope(isolate);
983 return scope.Escape(script->BindToCurrentContext()
984 ->Run(isolate->GetCurrentContext())
985 .FromMaybe(v8::Local<v8::Value>()));
986 }
987
988 inline MaybeLocal<v8::Value> RunScript(
989 v8::Local<BoundScript> script
990 ) {
991 v8::Isolate *isolate = v8::Isolate::GetCurrent();
992 v8::EscapableHandleScope scope(isolate);
993 return scope.Escape(script->Run(isolate->GetCurrentContext())
994 .FromMaybe(v8::Local<v8::Value>()));
995 }
996#else
997 inline MaybeLocal<v8::String>
998 NewOneByteString(const uint8_t * value, int length = -1) {
999 return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), value,
1000 v8::String::kNormalString, length);
1001 }
1002
1003 inline MaybeLocal<BoundScript> CompileScript(
1004 v8::Local<v8::String> s
1005 , const v8::ScriptOrigin& origin
1006 ) {
1007 v8::ScriptCompiler::Source source(s, origin);
1008 return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
1009 }
1010
1011 inline MaybeLocal<BoundScript> CompileScript(
1012 v8::Local<v8::String> s
1013 ) {
1014 v8::ScriptCompiler::Source source(s);
1015 return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
1016 }
1017
1018 inline MaybeLocal<v8::Value> RunScript(
1019 v8::Local<UnboundScript> script
1020 ) {
1021 EscapableHandleScope scope;
1022 return scope.Escape(script->BindToCurrentContext()->Run());
1023 }
1024
1025 inline MaybeLocal<v8::Value> RunScript(
1026 v8::Local<BoundScript> script
1027 ) {
1028 return script->Run();
1029 }
1030#endif
1031
1032 NAN_DEPRECATED inline v8::Local<v8::Value> MakeCallback(
1033 v8::Local<v8::Object> target
1034 , v8::Local<v8::Function> func
1035 , int argc
1036 , v8::Local<v8::Value>* argv) {
1037#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1038 EscapableHandleScope scope;
1039 return scope.Escape(New(node::MakeCallback(
1040 v8::Isolate::GetCurrent(), target, func, argc, argv)));
1041#else
1042# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1043 AsyncResource res("nan:makeCallback");
1044 return res.runInAsyncScope(target, func, argc, argv)
1045 .FromMaybe(v8::Local<v8::Value>());
1046# else
1047 return node::MakeCallback(
1048 v8::Isolate::GetCurrent(), target, func, argc, argv);
1049# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1050#endif // NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1051 }
1052
1053 NAN_DEPRECATED inline v8::Local<v8::Value> MakeCallback(
1054 v8::Local<v8::Object> target
1055 , v8::Local<v8::String> symbol
1056 , int argc
1057 , v8::Local<v8::Value>* argv) {
1058#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1059 EscapableHandleScope scope;
1060 return scope.Escape(New(node::MakeCallback(
1061 v8::Isolate::GetCurrent(), target, symbol, argc, argv)));
1062#else
1063# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1064 AsyncResource res("nan:makeCallback");
1065 return res.runInAsyncScope(target, symbol, argc, argv)
1066 .FromMaybe(v8::Local<v8::Value>());
1067# else
1068 return node::MakeCallback(
1069 v8::Isolate::GetCurrent(), target, symbol, argc, argv);
1070# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1071#endif // NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1072 }
1073
1074 NAN_DEPRECATED inline v8::Local<v8::Value> MakeCallback(
1075 v8::Local<v8::Object> target
1076 , const char* method
1077 , int argc
1078 , v8::Local<v8::Value>* argv) {
1079#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1080 EscapableHandleScope scope;
1081 return scope.Escape(New(node::MakeCallback(
1082 v8::Isolate::GetCurrent(), target, method, argc, argv)));
1083#else
1084# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1085 AsyncResource res("nan:makeCallback");
1086 return res.runInAsyncScope(target, method, argc, argv)
1087 .FromMaybe(v8::Local<v8::Value>());
1088# else
1089 return node::MakeCallback(
1090 v8::Isolate::GetCurrent(), target, method, argc, argv);
1091# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1092#endif // NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1093 }
1094
1095 inline void FatalException(const TryCatch& try_catch) {
1096 node::FatalException(v8::Isolate::GetCurrent(), try_catch.try_catch_);
1097 }
1098
1099 inline v8::Local<v8::Value> ErrnoException(
1100 int errorno
1101 , const char* syscall = NULL
1102 , const char* message = NULL
1103 , const char* path = NULL) {
1104 return node::ErrnoException(v8::Isolate::GetCurrent(), errorno, syscall,
1105 message, path);
1106 }
1107
1108 NAN_DEPRECATED inline v8::Local<v8::Value> NanErrnoException(
1109 int errorno
1110 , const char* syscall = NULL
1111 , const char* message = NULL
1112 , const char* path = NULL) {
1113 return ErrnoException(errorno, syscall, message, path);
1114 }
1115
1116 template<typename T>
1117 inline void SetIsolateData(
1118 v8::Isolate *isolate
1119 , T *data
1120 ) {
1121 isolate->SetData(0, data);
1122 }
1123
1124 template<typename T>
1125 inline T *GetIsolateData(
1126 v8::Isolate *isolate
1127 ) {
1128 return static_cast<T*>(isolate->GetData(0));
1129 }
1130
1131class Utf8String {
1132 public:
1133 inline explicit Utf8String(v8::Local<v8::Value> from) :
1134 length_(0), str_(str_st_) {
1135 HandleScope scope;
1136 if (!from.IsEmpty()) {
1137#if NODE_MAJOR_VERSION >= 10
1138 v8::Local<v8::Context> context = GetCurrentContext();
1139 v8::Local<v8::String> string =
1140 from->ToString(context).FromMaybe(v8::Local<v8::String>());
1141#else
1142 v8::Local<v8::String> string = from->ToString();
1143#endif
1144 if (!string.IsEmpty()) {
1145 size_t len = 3 * string->Length() + 1;
1146 assert(len <= INT_MAX);
1147 if (len > sizeof (str_st_)) {
1148 str_ = static_cast<char*>(malloc(len));
1149 assert(str_ != 0);
1150 }
1151 const int flags =
1152 v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
1153#if NODE_MAJOR_VERSION >= 11
1154 length_ = string->WriteUtf8(v8::Isolate::GetCurrent(), str_,
1155 static_cast<int>(len), 0, flags);
1156#else
1157 // See https://github.com/nodejs/nan/issues/832.
1158 // Disable the warning as there is no way around it.
1159#ifdef _MSC_VER
1160#pragma warning(push)
1161#pragma warning(disable : 4996)
1162#endif
1163#ifdef __GNUC__
1164#pragma GCC diagnostic push
1165#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1166#endif
1167 length_ = string->WriteUtf8(str_, static_cast<int>(len), 0, flags);
1168#ifdef __GNUC__
1169#pragma GCC diagnostic pop
1170#endif
1171#ifdef _MSC_VER
1172#pragma warning(pop)
1173#endif
1174#endif // NODE_MAJOR_VERSION < 11
1175 str_[length_] = '\0';
1176 }
1177 }
1178 }
1179
1180 inline int length() const {
1181 return length_;
1182 }
1183
1184 inline char* operator*() { return str_; }
1185 inline const char* operator*() const { return str_; }
1186
1187 inline ~Utf8String() {
1188 if (str_ != str_st_) {
1189 free(str_);
1190 }
1191 }
1192
1193 private:
1194 NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
1195
1196 int length_;
1197 char *str_;
1198 char str_st_[1024];
1199};
1200
1201#else // Node 0.8 and 0.10
1202 inline v8::Local<v8::Primitive> Undefined() {
1203 EscapableHandleScope scope;
1204 return scope.Escape(New(v8::Undefined()));
1205 }
1206
1207 inline v8::Local<v8::Primitive> Null() {
1208 EscapableHandleScope scope;
1209 return scope.Escape(New(v8::Null()));
1210 }
1211
1212 inline v8::Local<v8::Boolean> True() {
1213 EscapableHandleScope scope;
1214 return scope.Escape(New(v8::True()));
1215 }
1216
1217 inline v8::Local<v8::Boolean> False() {
1218 EscapableHandleScope scope;
1219 return scope.Escape(New(v8::False()));
1220 }
1221
1222 inline v8::Local<v8::String> EmptyString() {
1223 return v8::String::Empty();
1224 }
1225
1226 inline int AdjustExternalMemory(int bc) {
1227 return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
1228 }
1229
1230 inline void SetTemplate(
1231 v8::Local<v8::Template> templ
1232 , const char *name
1233 , v8::Local<v8::Data> value) {
1234 templ->Set(name, value);
1235 }
1236
1237 inline void SetTemplate(
1238 v8::Local<v8::Template> templ
1239 , v8::Local<v8::String> name
1240 , v8::Local<v8::Data> value
1241 , v8::PropertyAttribute attributes) {
1242 templ->Set(name, value, attributes);
1243 }
1244
1245 inline v8::Local<v8::Context> GetCurrentContext() {
1246 return v8::Context::GetCurrent();
1247 }
1248
1249 inline void* GetInternalFieldPointer(
1250 v8::Local<v8::Object> object
1251 , int index) {
1252 return object->GetPointerFromInternalField(index);
1253 }
1254
1255 inline void SetInternalFieldPointer(
1256 v8::Local<v8::Object> object
1257 , int index
1258 , void* value) {
1259 object->SetPointerInInternalField(index, value);
1260 }
1261
1262# define NAN_GC_CALLBACK(name) \
1263 void name(v8::GCType type, v8::GCCallbackFlags flags)
1264
1265 inline void AddGCEpilogueCallback(
1266 v8::GCEpilogueCallback callback
1267 , v8::GCType gc_type_filter = v8::kGCTypeAll) {
1268 v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);
1269 }
1270 inline void RemoveGCEpilogueCallback(
1271 v8::GCEpilogueCallback callback) {
1272 v8::V8::RemoveGCEpilogueCallback(callback);
1273 }
1274 inline void AddGCPrologueCallback(
1275 v8::GCPrologueCallback callback
1276 , v8::GCType gc_type_filter = v8::kGCTypeAll) {
1277 v8::V8::AddGCPrologueCallback(callback, gc_type_filter);
1278 }
1279 inline void RemoveGCPrologueCallback(
1280 v8::GCPrologueCallback callback) {
1281 v8::V8::RemoveGCPrologueCallback(callback);
1282 }
1283 inline void GetHeapStatistics(
1284 v8::HeapStatistics *heap_statistics) {
1285 v8::V8::GetHeapStatistics(heap_statistics);
1286 }
1287
1288# define X(NAME) \
1289 inline v8::Local<v8::Value> NAME(const char *msg) { \
1290 EscapableHandleScope scope; \
1291 return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked())); \
1292 } \
1293 \
1294 inline \
1295 v8::Local<v8::Value> NAME(v8::Local<v8::String> msg) { \
1296 return v8::Exception::NAME(msg); \
1297 } \
1298 \
1299 inline void Throw ## NAME(const char *msg) { \
1300 HandleScope scope; \
1301 v8::ThrowException(v8::Exception::NAME(New(msg).ToLocalChecked())); \
1302 } \
1303 \
1304 inline \
1305 void Throw ## NAME(v8::Local<v8::String> errmsg) { \
1306 HandleScope scope; \
1307 v8::ThrowException(v8::Exception::NAME(errmsg)); \
1308 }
1309
1310 X(Error)
1311 X(RangeError)
1312 X(ReferenceError)
1313 X(SyntaxError)
1314 X(TypeError)
1315
1316# undef X
1317
1318 inline void ThrowError(v8::Local<v8::Value> error) {
1319 v8::ThrowException(error);
1320 }
1321
1322 inline MaybeLocal<v8::Object> NewBuffer(
1323 char *data
1324 , size_t length
1325 , node::Buffer::free_callback callback
1326 , void *hint
1327 ) {
1328 EscapableHandleScope scope;
1329 // arbitrary buffer lengths requires
1330 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1331 assert(length <= imp::kMaxLength && "too large buffer");
1332 return scope.Escape(
1333 New(node::Buffer::New(data, length, callback, hint)->handle_));
1334 }
1335
1336 inline MaybeLocal<v8::Object> CopyBuffer(
1337 const char *data
1338 , uint32_t size
1339 ) {
1340 EscapableHandleScope scope;
1341 // arbitrary buffer lengths requires
1342 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1343 assert(size <= imp::kMaxLength && "too large buffer");
1344#if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
1345 return scope.Escape(New(node::Buffer::New(data, size)->handle_));
1346#else
1347 return scope.Escape(
1348 New(node::Buffer::New(const_cast<char *>(data), size)->handle_));
1349#endif
1350 }
1351
1352 inline MaybeLocal<v8::Object> NewBuffer(uint32_t size) {
1353 // arbitrary buffer lengths requires
1354 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1355 EscapableHandleScope scope;
1356 assert(size <= imp::kMaxLength && "too large buffer");
1357 return scope.Escape(New(node::Buffer::New(size)->handle_));
1358 }
1359
1360 inline void FreeData(char *data, void *hint) {
1361 (void) hint; // unused
1362 delete[] data;
1363 }
1364
1365 inline MaybeLocal<v8::Object> NewBuffer(
1366 char* data
1367 , uint32_t size
1368 ) {
1369 EscapableHandleScope scope;
1370 // arbitrary buffer lengths requires
1371 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1372 assert(size <= imp::kMaxLength && "too large buffer");
1373 return scope.Escape(
1374 New(node::Buffer::New(data, size, FreeData, NULL)->handle_));
1375 }
1376
1377namespace imp {
1378inline void
1379widenString(std::vector<uint16_t> *ws, const uint8_t *s, int l) {
1380 size_t len = static_cast<size_t>(l);
1381 if (l < 0) {
1382 len = strlen(reinterpret_cast<const char*>(s));
1383 }
1384 assert(len <= INT_MAX && "string too long");
1385 ws->resize(len);
1386 std::copy(s, s + len, ws->begin()); // NOLINT(build/include_what_you_use)
1387}
1388} // end of namespace imp
1389
1390 inline MaybeLocal<v8::String>
1391 NewOneByteString(const uint8_t * value, int length = -1) {
1392 std::vector<uint16_t> wideString; // NOLINT(build/include_what_you_use)
1393 imp::widenString(&wideString, value, length);
1394 return v8::String::New(wideString.data(),
1395 static_cast<int>(wideString.size()));
1396 }
1397
1398 inline MaybeLocal<BoundScript> CompileScript(
1399 v8::Local<v8::String> s
1400 , const v8::ScriptOrigin& origin
1401 ) {
1402 return v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin));
1403 }
1404
1405 inline MaybeLocal<BoundScript> CompileScript(
1406 v8::Local<v8::String> s
1407 ) {
1408 return v8::Script::Compile(s);
1409 }
1410
1411 inline
1412 MaybeLocal<v8::Value> RunScript(v8::Local<v8::Script> script) {
1413 return script->Run();
1414 }
1415
1416 inline v8::Local<v8::Value> MakeCallback(
1417 v8::Local<v8::Object> target
1418 , v8::Local<v8::Function> func
1419 , int argc
1420 , v8::Local<v8::Value>* argv) {
1421 v8::HandleScope scope;
1422 return scope.Close(New(node::MakeCallback(target, func, argc, argv)));
1423 }
1424
1425 inline v8::Local<v8::Value> MakeCallback(
1426 v8::Local<v8::Object> target
1427 , v8::Local<v8::String> symbol
1428 , int argc
1429 , v8::Local<v8::Value>* argv) {
1430 v8::HandleScope scope;
1431 return scope.Close(New(node::MakeCallback(target, symbol, argc, argv)));
1432 }
1433
1434 inline v8::Local<v8::Value> MakeCallback(
1435 v8::Local<v8::Object> target
1436 , const char* method
1437 , int argc
1438 , v8::Local<v8::Value>* argv) {
1439 v8::HandleScope scope;
1440 return scope.Close(New(node::MakeCallback(target, method, argc, argv)));
1441 }
1442
1443 inline void FatalException(const TryCatch& try_catch) {
1444 node::FatalException(const_cast<v8::TryCatch &>(try_catch.try_catch_));
1445 }
1446
1447 inline v8::Local<v8::Value> ErrnoException(
1448 int errorno
1449 , const char* syscall = NULL
1450 , const char* message = NULL
1451 , const char* path = NULL) {
1452 return node::ErrnoException(errorno, syscall, message, path);
1453 }
1454
1455 NAN_DEPRECATED inline v8::Local<v8::Value> NanErrnoException(
1456 int errorno
1457 , const char* syscall = NULL
1458 , const char* message = NULL
1459 , const char* path = NULL) {
1460 return ErrnoException(errorno, syscall, message, path);
1461 }
1462
1463
1464 template<typename T>
1465 inline void SetIsolateData(
1466 v8::Isolate *isolate
1467 , T *data
1468 ) {
1469 isolate->SetData(data);
1470 }
1471
1472 template<typename T>
1473 inline T *GetIsolateData(
1474 v8::Isolate *isolate
1475 ) {
1476 return static_cast<T*>(isolate->GetData());
1477 }
1478
1479class Utf8String {
1480 public:
1481 inline explicit Utf8String(v8::Local<v8::Value> from) :
1482 length_(0), str_(str_st_) {
1483 v8::HandleScope scope;
1484 if (!from.IsEmpty()) {
1485 v8::Local<v8::String> string = from->ToString();
1486 if (!string.IsEmpty()) {
1487 size_t len = 3 * string->Length() + 1;
1488 assert(len <= INT_MAX);
1489 if (len > sizeof (str_st_)) {
1490 str_ = static_cast<char*>(malloc(len));
1491 assert(str_ != 0);
1492 }
1493 const int flags =
1494 v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
1495 length_ = string->WriteUtf8(str_, static_cast<int>(len), 0, flags);
1496 str_[length_] = '\0';
1497 }
1498 }
1499 }
1500
1501 inline int length() const {
1502 return length_;
1503 }
1504
1505 inline char* operator*() { return str_; }
1506 inline const char* operator*() const { return str_; }
1507
1508 inline ~Utf8String() {
1509 if (str_ != str_st_) {
1510 free(str_);
1511 }
1512 }
1513
1514 private:
1515 NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
1516
1517 int length_;
1518 char *str_;
1519 char str_st_[1024];
1520};
1521
1522#endif // NODE_MODULE_VERSION
1523
1524typedef void (*FreeCallback)(char *data, void *hint);
1525
1526typedef const FunctionCallbackInfo<v8::Value>& NAN_METHOD_ARGS_TYPE;
1527typedef void NAN_METHOD_RETURN_TYPE;
1528
1529typedef const PropertyCallbackInfo<v8::Value>& NAN_GETTER_ARGS_TYPE;
1530typedef void NAN_GETTER_RETURN_TYPE;
1531
1532typedef const PropertyCallbackInfo<void>& NAN_SETTER_ARGS_TYPE;
1533typedef void NAN_SETTER_RETURN_TYPE;
1534
1535typedef const PropertyCallbackInfo<v8::Value>&
1536 NAN_PROPERTY_GETTER_ARGS_TYPE;
1537typedef void NAN_PROPERTY_GETTER_RETURN_TYPE;
1538
1539typedef const PropertyCallbackInfo<v8::Value>&
1540 NAN_PROPERTY_SETTER_ARGS_TYPE;
1541typedef void NAN_PROPERTY_SETTER_RETURN_TYPE;
1542
1543typedef const PropertyCallbackInfo<v8::Array>&
1544 NAN_PROPERTY_ENUMERATOR_ARGS_TYPE;
1545typedef void NAN_PROPERTY_ENUMERATOR_RETURN_TYPE;
1546
1547typedef const PropertyCallbackInfo<v8::Boolean>&
1548 NAN_PROPERTY_DELETER_ARGS_TYPE;
1549typedef void NAN_PROPERTY_DELETER_RETURN_TYPE;
1550
1551typedef const PropertyCallbackInfo<v8::Integer>&
1552 NAN_PROPERTY_QUERY_ARGS_TYPE;
1553typedef void NAN_PROPERTY_QUERY_RETURN_TYPE;
1554
1555typedef const PropertyCallbackInfo<v8::Value>& NAN_INDEX_GETTER_ARGS_TYPE;
1556typedef void NAN_INDEX_GETTER_RETURN_TYPE;
1557
1558typedef const PropertyCallbackInfo<v8::Value>& NAN_INDEX_SETTER_ARGS_TYPE;
1559typedef void NAN_INDEX_SETTER_RETURN_TYPE;
1560
1561typedef const PropertyCallbackInfo<v8::Array>&
1562 NAN_INDEX_ENUMERATOR_ARGS_TYPE;
1563typedef void NAN_INDEX_ENUMERATOR_RETURN_TYPE;
1564
1565typedef const PropertyCallbackInfo<v8::Boolean>&
1566 NAN_INDEX_DELETER_ARGS_TYPE;
1567typedef void NAN_INDEX_DELETER_RETURN_TYPE;
1568
1569typedef const PropertyCallbackInfo<v8::Integer>&
1570 NAN_INDEX_QUERY_ARGS_TYPE;
1571typedef void NAN_INDEX_QUERY_RETURN_TYPE;
1572
1573#define NAN_METHOD(name) \
1574 Nan::NAN_METHOD_RETURN_TYPE name(Nan::NAN_METHOD_ARGS_TYPE info)
1575#define NAN_GETTER(name) \
1576 Nan::NAN_GETTER_RETURN_TYPE name( \
1577 v8::Local<v8::String> property \
1578 , Nan::NAN_GETTER_ARGS_TYPE info)
1579#define NAN_SETTER(name) \
1580 Nan::NAN_SETTER_RETURN_TYPE name( \
1581 v8::Local<v8::String> property \
1582 , v8::Local<v8::Value> value \
1583 , Nan::NAN_SETTER_ARGS_TYPE info)
1584#define NAN_PROPERTY_GETTER(name) \
1585 Nan::NAN_PROPERTY_GETTER_RETURN_TYPE name( \
1586 v8::Local<v8::String> property \
1587 , Nan::NAN_PROPERTY_GETTER_ARGS_TYPE info)
1588#define NAN_PROPERTY_SETTER(name) \
1589 Nan::NAN_PROPERTY_SETTER_RETURN_TYPE name( \
1590 v8::Local<v8::String> property \
1591 , v8::Local<v8::Value> value \
1592 , Nan::NAN_PROPERTY_SETTER_ARGS_TYPE info)
1593#define NAN_PROPERTY_ENUMERATOR(name) \
1594 Nan::NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name( \
1595 Nan::NAN_PROPERTY_ENUMERATOR_ARGS_TYPE info)
1596#define NAN_PROPERTY_DELETER(name) \
1597 Nan::NAN_PROPERTY_DELETER_RETURN_TYPE name( \
1598 v8::Local<v8::String> property \
1599 , Nan::NAN_PROPERTY_DELETER_ARGS_TYPE info)
1600#define NAN_PROPERTY_QUERY(name) \
1601 Nan::NAN_PROPERTY_QUERY_RETURN_TYPE name( \
1602 v8::Local<v8::String> property \
1603 , Nan::NAN_PROPERTY_QUERY_ARGS_TYPE info)
1604# define NAN_INDEX_GETTER(name) \
1605 Nan::NAN_INDEX_GETTER_RETURN_TYPE name( \
1606 uint32_t index \
1607 , Nan::NAN_INDEX_GETTER_ARGS_TYPE info)
1608#define NAN_INDEX_SETTER(name) \
1609 Nan::NAN_INDEX_SETTER_RETURN_TYPE name( \
1610 uint32_t index \
1611 , v8::Local<v8::Value> value \
1612 , Nan::NAN_INDEX_SETTER_ARGS_TYPE info)
1613#define NAN_INDEX_ENUMERATOR(name) \
1614 Nan::NAN_INDEX_ENUMERATOR_RETURN_TYPE \
1615 name(Nan::NAN_INDEX_ENUMERATOR_ARGS_TYPE info)
1616#define NAN_INDEX_DELETER(name) \
1617 Nan::NAN_INDEX_DELETER_RETURN_TYPE name( \
1618 uint32_t index \
1619 , Nan::NAN_INDEX_DELETER_ARGS_TYPE info)
1620#define NAN_INDEX_QUERY(name) \
1621 Nan::NAN_INDEX_QUERY_RETURN_TYPE name( \
1622 uint32_t index \
1623 , Nan::NAN_INDEX_QUERY_ARGS_TYPE info)
1624
1625class Callback {
1626 public:
1627 Callback() {}
1628
1629 explicit Callback(const v8::Local<v8::Function> &fn) : handle_(fn) {}
1630
1631 ~Callback() {
1632 handle_.Reset();
1633 }
1634
1635 bool operator==(const Callback &other) const {
1636 return handle_ == other.handle_;
1637 }
1638
1639 bool operator!=(const Callback &other) const {
1640 return !operator==(other);
1641 }
1642
1643 inline
1644 v8::Local<v8::Function> operator*() const { return GetFunction(); }
1645
1646 NAN_DEPRECATED inline v8::Local<v8::Value> operator()(
1647 v8::Local<v8::Object> target
1648 , int argc = 0
1649 , v8::Local<v8::Value> argv[] = 0) const {
1650#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1651 v8::Isolate *isolate = v8::Isolate::GetCurrent();
1652# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1653 AsyncResource async("nan:Callback:operator()");
1654 return Call_(isolate, target, argc, argv, &async)
1655 .FromMaybe(v8::Local<v8::Value>());
1656# else
1657 return Call_(isolate, target, argc, argv);
1658# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1659#else
1660 return Call_(target, argc, argv);
1661#endif // NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1662 }
1663
1664 NAN_DEPRECATED inline v8::Local<v8::Value> operator()(
1665 int argc = 0
1666 , v8::Local<v8::Value> argv[] = 0) const {
1667#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1668 v8::Isolate *isolate = v8::Isolate::GetCurrent();
1669 v8::EscapableHandleScope scope(isolate);
1670# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1671 AsyncResource async("nan:Callback:operator()");
1672 return scope.Escape(Call_(isolate, isolate->GetCurrentContext()->Global(),
1673 argc, argv, &async)
1674 .FromMaybe(v8::Local<v8::Value>()));
1675# else
1676 return scope.Escape(
1677 Call_(isolate, isolate->GetCurrentContext()->Global(), argc, argv));
1678# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1679#else
1680 v8::HandleScope scope;
1681 return scope.Close(Call_(v8::Context::GetCurrent()->Global(), argc, argv));
1682#endif // NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1683 }
1684
1685 inline MaybeLocal<v8::Value> operator()(
1686 AsyncResource* resource
1687 , int argc = 0
1688 , v8::Local<v8::Value> argv[] = 0) const {
1689 return this->Call(argc, argv, resource);
1690 }
1691
1692 inline MaybeLocal<v8::Value> operator()(
1693 AsyncResource* resource
1694 , v8::Local<v8::Object> target
1695 , int argc = 0
1696 , v8::Local<v8::Value> argv[] = 0) const {
1697 return this->Call(target, argc, argv, resource);
1698 }
1699
1700 // TODO(kkoopa): remove
1701 inline void SetFunction(const v8::Local<v8::Function> &fn) {
1702 Reset(fn);
1703 }
1704
1705 inline void Reset(const v8::Local<v8::Function> &fn) {
1706 handle_.Reset(fn);
1707 }
1708
1709 inline void Reset() {
1710 handle_.Reset();
1711 }
1712
1713 inline v8::Local<v8::Function> GetFunction() const {
1714 return New(handle_);
1715 }
1716
1717 inline bool IsEmpty() const {
1718 return handle_.IsEmpty();
1719 }
1720
1721 // Deprecated: For async callbacks Use the versions that accept an
1722 // AsyncResource. If this callback does not correspond to an async resource,
1723 // that is, it is a synchronous function call on a non-empty JS stack, you
1724 // should Nan::Call instead.
1725 NAN_DEPRECATED inline v8::Local<v8::Value>
1726 Call(v8::Local<v8::Object> target
1727 , int argc
1728 , v8::Local<v8::Value> argv[]) const {
1729#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1730 v8::Isolate *isolate = v8::Isolate::GetCurrent();
1731# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1732 AsyncResource async("nan:Callback:Call");
1733 return Call_(isolate, target, argc, argv, &async)
1734 .FromMaybe(v8::Local<v8::Value>());
1735# else
1736 return Call_(isolate, target, argc, argv);
1737# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1738#else
1739 return Call_(target, argc, argv);
1740#endif
1741 }
1742
1743 // Deprecated: For async callbacks Use the versions that accept an
1744 // AsyncResource. If this callback does not correspond to an async resource,
1745 // that is, it is a synchronous function call on a non-empty JS stack, you
1746 // should Nan::Call instead.
1747 NAN_DEPRECATED inline v8::Local<v8::Value>
1748 Call(int argc, v8::Local<v8::Value> argv[]) const {
1749#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1750 v8::Isolate *isolate = v8::Isolate::GetCurrent();
1751 v8::EscapableHandleScope scope(isolate);
1752# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1753 AsyncResource async("nan:Callback:Call");
1754 return scope.Escape(Call_(isolate, isolate->GetCurrentContext()->Global(),
1755 argc, argv, &async)
1756 .FromMaybe(v8::Local<v8::Value>()));
1757# else
1758 return scope.Escape(
1759 Call_(isolate, isolate->GetCurrentContext()->Global(), argc, argv));
1760# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1761#else
1762 v8::HandleScope scope;
1763 return scope.Close(Call_(v8::Context::GetCurrent()->Global(), argc, argv));
1764#endif
1765 }
1766
1767 inline MaybeLocal<v8::Value>
1768 Call(v8::Local<v8::Object> target
1769 , int argc
1770 , v8::Local<v8::Value> argv[]
1771 , AsyncResource* resource) const {
1772#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1773 v8::Isolate* isolate = v8::Isolate::GetCurrent();
1774 return Call_(isolate, target, argc, argv, resource);
1775#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1776 v8::Isolate *isolate = v8::Isolate::GetCurrent();
1777 return Call_(isolate, target, argc, argv);
1778#else
1779 return Call_(target, argc, argv);
1780#endif
1781 }
1782
1783 inline MaybeLocal<v8::Value>
1784 Call(int argc, v8::Local<v8::Value> argv[], AsyncResource* resource) const {
1785#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1786 v8::Isolate* isolate = v8::Isolate::GetCurrent();
1787 return Call(isolate->GetCurrentContext()->Global(), argc, argv, resource);
1788#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1789 v8::Isolate *isolate = v8::Isolate::GetCurrent();
1790 v8::EscapableHandleScope scope(isolate);
1791 return scope.Escape(
1792 Call_(isolate, isolate->GetCurrentContext()->Global(), argc, argv));
1793#else
1794 v8::HandleScope scope;
1795 return scope.Close(Call_(v8::Context::GetCurrent()->Global(), argc, argv));
1796#endif
1797 }
1798
1799 private:
1800 NAN_DISALLOW_ASSIGN_COPY_MOVE(Callback)
1801 Persistent<v8::Function> handle_;
1802
1803#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
1804 MaybeLocal<v8::Value> Call_(v8::Isolate *isolate
1805 , v8::Local<v8::Object> target
1806 , int argc
1807 , v8::Local<v8::Value> argv[]
1808 , AsyncResource* resource) const {
1809 EscapableHandleScope scope;
1810 v8::Local<v8::Function> func = New(handle_);
1811 auto maybe = resource->runInAsyncScope(target, func, argc, argv);
1812 v8::Local<v8::Value> local;
1813 if (!maybe.ToLocal(&local)) return MaybeLocal<v8::Value>();
1814 return scope.Escape(local);
1815 }
1816#elif NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1817 v8::Local<v8::Value> Call_(v8::Isolate *isolate
1818 , v8::Local<v8::Object> target
1819 , int argc
1820 , v8::Local<v8::Value> argv[]) const {
1821 EscapableHandleScope scope;
1822
1823 v8::Local<v8::Function> callback = New(handle_);
1824# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1825 return scope.Escape(New(node::MakeCallback(
1826 isolate
1827 , target
1828 , callback
1829 , argc
1830 , argv
1831 )));
1832# else
1833 return scope.Escape(node::MakeCallback(
1834 isolate
1835 , target
1836 , callback
1837 , argc
1838 , argv
1839 ));
1840# endif
1841 }
1842#else
1843 v8::Local<v8::Value> Call_(v8::Local<v8::Object> target
1844 , int argc
1845 , v8::Local<v8::Value> argv[]) const {
1846 EscapableHandleScope scope;
1847
1848 v8::Local<v8::Function> callback = New(handle_);
1849 return scope.Escape(New(node::MakeCallback(
1850 target
1851 , callback
1852 , argc
1853 , argv
1854 )));
1855 }
1856#endif
1857};
1858
1859inline MaybeLocal<v8::Value> Call(
1860 const Nan::Callback& callback
1861 , v8::Local<v8::Object> recv
1862 , int argc
1863 , v8::Local<v8::Value> argv[]) {
1864 return Call(*callback, recv, argc, argv);
1865}
1866
1867inline MaybeLocal<v8::Value> Call(
1868 const Nan::Callback& callback
1869 , int argc
1870 , v8::Local<v8::Value> argv[]) {
1871#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
1872 v8::Isolate* isolate = v8::Isolate::GetCurrent();
1873 v8::EscapableHandleScope scope(isolate);
1874 return scope.Escape(
1875 Call(*callback, isolate->GetCurrentContext()->Global(), argc, argv)
1876 .FromMaybe(v8::Local<v8::Value>()));
1877#else
1878 EscapableHandleScope scope;
1879 return scope.Escape(
1880 Call(*callback, v8::Context::GetCurrent()->Global(), argc, argv)
1881 .FromMaybe(v8::Local<v8::Value>()));
1882#endif
1883}
1884
1885inline MaybeLocal<v8::Value> Call(
1886 v8::Local<v8::String> symbol
1887 , v8::Local<v8::Object> recv
1888 , int argc
1889 , v8::Local<v8::Value> argv[]) {
1890 EscapableHandleScope scope;
1891 v8::Local<v8::Value> fn_v =
1892 Get(recv, symbol).FromMaybe(v8::Local<v8::Value>());
1893 if (fn_v.IsEmpty() || !fn_v->IsFunction()) return v8::Local<v8::Value>();
1894 v8::Local<v8::Function> fn = fn_v.As<v8::Function>();
1895 return scope.Escape(
1896 Call(fn, recv, argc, argv).FromMaybe(v8::Local<v8::Value>()));
1897}
1898
1899inline MaybeLocal<v8::Value> Call(
1900 const char* method
1901 , v8::Local<v8::Object> recv
1902 , int argc
1903 , v8::Local<v8::Value> argv[]) {
1904 EscapableHandleScope scope;
1905 v8::Local<v8::String> method_string =
1906 New<v8::String>(method).ToLocalChecked();
1907 return scope.Escape(
1908 Call(method_string, recv, argc, argv).FromMaybe(v8::Local<v8::Value>()));
1909}
1910
1911/* abstract */ class AsyncWorker {
1912 public:
1913 explicit AsyncWorker(Callback *callback_,
1914 const char* resource_name = "nan:AsyncWorker")
1915 : callback(callback_), errmsg_(NULL) {
1916 request.data = this;
1917
1918 HandleScope scope;
1919 v8::Local<v8::Object> obj = New<v8::Object>();
1920 persistentHandle.Reset(obj);
1921 async_resource = new AsyncResource(resource_name, obj);
1922 }
1923
1924 virtual ~AsyncWorker() {
1925 HandleScope scope;
1926
1927 if (!persistentHandle.IsEmpty())
1928 persistentHandle.Reset();
1929 delete callback;
1930 delete[] errmsg_;
1931 delete async_resource;
1932 }
1933
1934 virtual void WorkComplete() {
1935 HandleScope scope;
1936
1937 if (errmsg_ == NULL)
1938 HandleOKCallback();
1939 else
1940 HandleErrorCallback();
1941 delete callback;
1942 callback = NULL;
1943 }
1944
1945 inline void SaveToPersistent(
1946 const char *key, const v8::Local<v8::Value> &value) {
1947 HandleScope scope;
1948 Set(New(persistentHandle), New(key).ToLocalChecked(), value).FromJust();
1949 }
1950
1951 inline void SaveToPersistent(
1952 const v8::Local<v8::String> &key, const v8::Local<v8::Value> &value) {
1953 HandleScope scope;
1954 Set(New(persistentHandle), key, value).FromJust();
1955 }
1956
1957 inline void SaveToPersistent(
1958 uint32_t index, const v8::Local<v8::Value> &value) {
1959 HandleScope scope;
1960 Set(New(persistentHandle), index, value).FromJust();
1961 }
1962
1963 inline v8::Local<v8::Value> GetFromPersistent(const char *key) const {
1964 EscapableHandleScope scope;
1965 return scope.Escape(
1966 Get(New(persistentHandle), New(key).ToLocalChecked())
1967 .FromMaybe(v8::Local<v8::Value>()));
1968 }
1969
1970 inline v8::Local<v8::Value>
1971 GetFromPersistent(const v8::Local<v8::String> &key) const {
1972 EscapableHandleScope scope;
1973 return scope.Escape(
1974 Get(New(persistentHandle), key)
1975 .FromMaybe(v8::Local<v8::Value>()));
1976 }
1977
1978 inline v8::Local<v8::Value> GetFromPersistent(uint32_t index) const {
1979 EscapableHandleScope scope;
1980 return scope.Escape(
1981 Get(New(persistentHandle), index)
1982 .FromMaybe(v8::Local<v8::Value>()));
1983 }
1984
1985 virtual void Execute() = 0;
1986
1987 uv_work_t request;
1988
1989 virtual void Destroy() {
1990 delete this;
1991 }
1992
1993 protected:
1994 Persistent<v8::Object> persistentHandle;
1995 Callback *callback;
1996 AsyncResource *async_resource;
1997
1998 virtual void HandleOKCallback() {
1999 HandleScope scope;
2000
2001 callback->Call(0, NULL, async_resource);
2002 }
2003
2004 virtual void HandleErrorCallback() {
2005 HandleScope scope;
2006
2007 v8::Local<v8::Value> argv[] = {
2008 v8::Exception::Error(New<v8::String>(ErrorMessage()).ToLocalChecked())
2009 };
2010 callback->Call(1, argv, async_resource);
2011 }
2012
2013 void SetErrorMessage(const char *msg) {
2014 delete[] errmsg_;
2015
2016 size_t size = strlen(msg) + 1;
2017 errmsg_ = new char[size];
2018 memcpy(errmsg_, msg, size);
2019 }
2020
2021 const char* ErrorMessage() const {
2022 return errmsg_;
2023 }
2024
2025 private:
2026 NAN_DISALLOW_ASSIGN_COPY_MOVE(AsyncWorker)
2027 char *errmsg_;
2028};
2029
2030/* abstract */ class AsyncBareProgressWorkerBase : public AsyncWorker {
2031 public:
2032 explicit AsyncBareProgressWorkerBase(
2033 Callback *callback_,
2034 const char* resource_name = "nan:AsyncBareProgressWorkerBase")
2035 : AsyncWorker(callback_, resource_name) {
2036 uv_async_init(
2037 GetCurrentEventLoop()
2038 , &async
2039 , AsyncProgress_
2040 );
2041 async.data = this;
2042 }
2043
2044 virtual ~AsyncBareProgressWorkerBase() {
2045 }
2046
2047 virtual void WorkProgress() = 0;
2048
2049 virtual void Destroy() {
2050 uv_close(reinterpret_cast<uv_handle_t*>(&async), AsyncClose_);
2051 }
2052
2053 private:
2054 inline static NAUV_WORK_CB(AsyncProgress_) {
2055 AsyncBareProgressWorkerBase *worker =
2056 static_cast<AsyncBareProgressWorkerBase*>(async->data);
2057 worker->WorkProgress();
2058 }
2059
2060 inline static void AsyncClose_(uv_handle_t* handle) {
2061 AsyncBareProgressWorkerBase *worker =
2062 static_cast<AsyncBareProgressWorkerBase*>(handle->data);
2063 delete worker;
2064 }
2065
2066 protected:
2067 uv_async_t async;
2068};
2069
2070template<class T>
2071/* abstract */
2072class AsyncBareProgressWorker : public AsyncBareProgressWorkerBase {
2073 public:
2074 explicit AsyncBareProgressWorker(
2075 Callback *callback_,
2076 const char* resource_name = "nan:AsyncBareProgressWorker")
2077 : AsyncBareProgressWorkerBase(callback_, resource_name) {
2078 uv_mutex_init(&async_lock);
2079 }
2080
2081 virtual ~AsyncBareProgressWorker() {
2082 uv_mutex_destroy(&async_lock);
2083 }
2084
2085 class ExecutionProgress {
2086 friend class AsyncBareProgressWorker;
2087 public:
2088 void Signal() const {
2089 uv_mutex_lock(&that_->async_lock);
2090 uv_async_send(&that_->async);
2091 uv_mutex_unlock(&that_->async_lock);
2092 }
2093
2094 void Send(const T* data, size_t count) const {
2095 that_->SendProgress_(data, count);
2096 }
2097
2098 private:
2099 explicit ExecutionProgress(AsyncBareProgressWorker *that) : that_(that) {}
2100 NAN_DISALLOW_ASSIGN_COPY_MOVE(ExecutionProgress)
2101 AsyncBareProgressWorker* const that_;
2102 };
2103
2104 virtual void Execute(const ExecutionProgress& progress) = 0;
2105 virtual void HandleProgressCallback(const T *data, size_t size) = 0;
2106
2107 protected:
2108 uv_mutex_t async_lock;
2109
2110 private:
2111 void Execute() /*final override*/ {
2112 ExecutionProgress progress(this);
2113 Execute(progress);
2114 }
2115
2116 virtual void SendProgress_(const T *data, size_t count) = 0;
2117};
2118
2119template<class T>
2120/* abstract */
2121class AsyncProgressWorkerBase : public AsyncBareProgressWorker<T> {
2122 public:
2123 explicit AsyncProgressWorkerBase(
2124 Callback *callback_,
2125 const char* resource_name = "nan:AsyncProgressWorkerBase")
2126 : AsyncBareProgressWorker<T>(callback_, resource_name), asyncdata_(NULL),
2127 asyncsize_(0) {
2128 }
2129
2130 virtual ~AsyncProgressWorkerBase() {
2131 delete[] asyncdata_;
2132 }
2133
2134 void WorkProgress() {
2135 uv_mutex_lock(&this->async_lock);
2136 T *data = asyncdata_;
2137 size_t size = asyncsize_;
2138 asyncdata_ = NULL;
2139 asyncsize_ = 0;
2140 uv_mutex_unlock(&this->async_lock);
2141
2142 // Don't send progress events after we've already completed.
2143 if (this->callback) {
2144 this->HandleProgressCallback(data, size);
2145 }
2146 delete[] data;
2147 }
2148
2149 private:
2150 void SendProgress_(const T *data, size_t count) {
2151 T *new_data = new T[count];
2152 std::copy(data, data + count, new_data);
2153
2154 uv_mutex_lock(&this->async_lock);
2155 T *old_data = asyncdata_;
2156 asyncdata_ = new_data;
2157 asyncsize_ = count;
2158 uv_async_send(&this->async);
2159 uv_mutex_unlock(&this->async_lock);
2160
2161 delete[] old_data;
2162 }
2163
2164 T *asyncdata_;
2165 size_t asyncsize_;
2166};
2167
2168// This ensures compatibility to the previous un-templated AsyncProgressWorker
2169// class definition.
2170typedef AsyncProgressWorkerBase<char> AsyncProgressWorker;
2171
2172template<class T>
2173/* abstract */
2174class AsyncBareProgressQueueWorker : public AsyncBareProgressWorkerBase {
2175 public:
2176 explicit AsyncBareProgressQueueWorker(
2177 Callback *callback_,
2178 const char* resource_name = "nan:AsyncBareProgressQueueWorker")
2179 : AsyncBareProgressWorkerBase(callback_, resource_name) {
2180 }
2181
2182 virtual ~AsyncBareProgressQueueWorker() {
2183 }
2184
2185 class ExecutionProgress {
2186 friend class AsyncBareProgressQueueWorker;
2187 public:
2188 void Send(const T* data, size_t count) const {
2189 that_->SendProgress_(data, count);
2190 }
2191
2192 private:
2193 explicit ExecutionProgress(AsyncBareProgressQueueWorker *that)
2194 : that_(that) {}
2195 NAN_DISALLOW_ASSIGN_COPY_MOVE(ExecutionProgress)
2196 AsyncBareProgressQueueWorker* const that_;
2197 };
2198
2199 virtual void Execute(const ExecutionProgress& progress) = 0;
2200 virtual void HandleProgressCallback(const T *data, size_t size) = 0;
2201
2202 private:
2203 void Execute() /*final override*/ {
2204 ExecutionProgress progress(this);
2205 Execute(progress);
2206 }
2207
2208 virtual void SendProgress_(const T *data, size_t count) = 0;
2209};
2210
2211template<class T>
2212/* abstract */
2213class AsyncProgressQueueWorker : public AsyncBareProgressQueueWorker<T> {
2214 public:
2215 explicit AsyncProgressQueueWorker(
2216 Callback *callback_,
2217 const char* resource_name = "nan:AsyncProgressQueueWorker")
2218 : AsyncBareProgressQueueWorker<T>(callback_) {
2219 uv_mutex_init(&async_lock);
2220 }
2221
2222 virtual ~AsyncProgressQueueWorker() {
2223 uv_mutex_lock(&async_lock);
2224
2225 while (!asyncdata_.empty()) {
2226 std::pair<T*, size_t> &datapair = asyncdata_.front();
2227 T *data = datapair.first;
2228
2229 asyncdata_.pop();
2230
2231 delete[] data;
2232 }
2233
2234 uv_mutex_unlock(&async_lock);
2235 uv_mutex_destroy(&async_lock);
2236 }
2237
2238 void WorkComplete() {
2239 WorkProgress();
2240 AsyncWorker::WorkComplete();
2241 }
2242
2243 void WorkProgress() {
2244 uv_mutex_lock(&async_lock);
2245
2246 while (!asyncdata_.empty()) {
2247 std::pair<T*, size_t> &datapair = asyncdata_.front();
2248
2249 T *data = datapair.first;
2250 size_t size = datapair.second;
2251
2252 asyncdata_.pop();
2253 uv_mutex_unlock(&async_lock);
2254
2255 // Don't send progress events after we've already completed.
2256 if (this->callback) {
2257 this->HandleProgressCallback(data, size);
2258 }
2259
2260 delete[] data;
2261
2262 uv_mutex_lock(&async_lock);
2263 }
2264
2265 uv_mutex_unlock(&async_lock);
2266 }
2267
2268 private:
2269 void SendProgress_(const T *data, size_t count) {
2270 T *new_data = new T[count];
2271 std::copy(data, data + count, new_data);
2272
2273 uv_mutex_lock(&async_lock);
2274 asyncdata_.push(std::pair<T*, size_t>(new_data, count));
2275 uv_mutex_unlock(&async_lock);
2276
2277 uv_async_send(&this->async);
2278 }
2279
2280 uv_mutex_t async_lock;
2281 std::queue<std::pair<T*, size_t> > asyncdata_;
2282};
2283
2284inline void AsyncExecute (uv_work_t* req) {
2285 AsyncWorker *worker = static_cast<AsyncWorker*>(req->data);
2286 worker->Execute();
2287}
2288
2289/* uv_after_work_cb has 1 argument before node-v0.9.4 and
2290 * 2 arguments since node-v0.9.4
2291 * https://github.com/libuv/libuv/commit/92fb84b751e18f032c02609467f44bfe927b80c5
2292 */
2293inline void AsyncExecuteComplete(uv_work_t *req) {
2294 AsyncWorker* worker = static_cast<AsyncWorker*>(req->data);
2295 worker->WorkComplete();
2296 worker->Destroy();
2297}
2298inline void AsyncExecuteComplete (uv_work_t* req, int status) {
2299 AsyncExecuteComplete(req);
2300}
2301
2302inline void AsyncQueueWorker (AsyncWorker* worker) {
2303 uv_queue_work(
2304 GetCurrentEventLoop()
2305 , &worker->request
2306 , AsyncExecute
2307 , AsyncExecuteComplete
2308 );
2309}
2310
2311namespace imp {
2312
2313inline
2314ExternalOneByteStringResource const*
2315GetExternalResource(v8::Local<v8::String> str) {
2316#if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION
2317 return str->GetExternalAsciiStringResource();
2318#else
2319 return str->GetExternalOneByteStringResource();
2320#endif
2321}
2322
2323inline
2324bool
2325IsExternal(v8::Local<v8::String> str) {
2326#if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION
2327 return str->IsExternalAscii();
2328#else
2329 return str->IsExternalOneByte();
2330#endif
2331}
2332
2333} // end of namespace imp
2334
2335enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
2336
2337#if NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION
2338# include "nan_string_bytes.h" // NOLINT(build/include)
2339#endif
2340
2341inline v8::Local<v8::Value> Encode(
2342 const void *buf, size_t len, enum Encoding encoding = BINARY) {
2343#if (NODE_MODULE_VERSION >= ATOM_0_21_MODULE_VERSION)
2344 v8::Isolate* isolate = v8::Isolate::GetCurrent();
2345 node::encoding node_enc = static_cast<node::encoding>(encoding);
2346
2347 if (encoding == UCS2) {
2348 return node::Encode(
2349 isolate
2350 , reinterpret_cast<const uint16_t *>(buf)
2351 , len / 2);
2352 } else {
2353 return node::Encode(
2354 isolate
2355 , reinterpret_cast<const char *>(buf)
2356 , len
2357 , node_enc);
2358 }
2359#elif (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
2360 return node::Encode(
2361 v8::Isolate::GetCurrent()
2362 , buf, len
2363 , static_cast<node::encoding>(encoding));
2364#else
2365# if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
2366 return node::Encode(buf, len, static_cast<node::encoding>(encoding));
2367# else
2368 return imp::Encode(reinterpret_cast<const char*>(buf), len, encoding);
2369# endif
2370#endif
2371}
2372
2373inline ssize_t DecodeBytes(
2374 v8::Local<v8::Value> val, enum Encoding encoding = BINARY) {
2375#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
2376 return node::DecodeBytes(
2377 v8::Isolate::GetCurrent()
2378 , val
2379 , static_cast<node::encoding>(encoding));
2380#else
2381# if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)
2382 if (encoding == BUFFER) {
2383 return node::DecodeBytes(val, node::BINARY);
2384 }
2385# endif
2386 return node::DecodeBytes(val, static_cast<node::encoding>(encoding));
2387#endif
2388}
2389
2390inline ssize_t DecodeWrite(
2391 char *buf
2392 , size_t len
2393 , v8::Local<v8::Value> val
2394 , enum Encoding encoding = BINARY) {
2395#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
2396 return node::DecodeWrite(
2397 v8::Isolate::GetCurrent()
2398 , buf
2399 , len
2400 , val
2401 , static_cast<node::encoding>(encoding));
2402#else
2403# if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)
2404 if (encoding == BUFFER) {
2405 return node::DecodeWrite(buf, len, val, node::BINARY);
2406 }
2407# endif
2408 return node::DecodeWrite(
2409 buf
2410 , len
2411 , val
2412 , static_cast<node::encoding>(encoding));
2413#endif
2414}
2415
2416inline void SetPrototypeTemplate(
2417 v8::Local<v8::FunctionTemplate> templ
2418 , const char *name
2419 , v8::Local<v8::Data> value
2420) {
2421 HandleScope scope;
2422 SetTemplate(templ->PrototypeTemplate(), name, value);
2423}
2424
2425inline void SetPrototypeTemplate(
2426 v8::Local<v8::FunctionTemplate> templ
2427 , v8::Local<v8::String> name
2428 , v8::Local<v8::Data> value
2429 , v8::PropertyAttribute attributes
2430) {
2431 HandleScope scope;
2432 SetTemplate(templ->PrototypeTemplate(), name, value, attributes);
2433}
2434
2435inline void SetInstanceTemplate(
2436 v8::Local<v8::FunctionTemplate> templ
2437 , const char *name
2438 , v8::Local<v8::Data> value
2439) {
2440 HandleScope scope;
2441 SetTemplate(templ->InstanceTemplate(), name, value);
2442}
2443
2444inline void SetInstanceTemplate(
2445 v8::Local<v8::FunctionTemplate> templ
2446 , v8::Local<v8::String> name
2447 , v8::Local<v8::Data> value
2448 , v8::PropertyAttribute attributes
2449) {
2450 HandleScope scope;
2451 SetTemplate(templ->InstanceTemplate(), name, value, attributes);
2452}
2453
2454namespace imp {
2455
2456// Note(@agnat): Helper to distinguish different receiver types. The first
2457// version deals with receivers derived from v8::Template. The second version
2458// handles everything else. The final argument only serves as discriminator and
2459// is unused.
2460template <typename T>
2461inline
2462void
2463SetMethodAux(T recv,
2464 v8::Local<v8::String> name,
2465 v8::Local<v8::FunctionTemplate> tpl,
2466 v8::Template *) {
2467 recv->Set(name, tpl);
2468}
2469
2470template <typename T>
2471inline
2472void
2473SetMethodAux(T recv,
2474 v8::Local<v8::String> name,
2475 v8::Local<v8::FunctionTemplate> tpl,
2476 ...) {
2477 Set(recv, name, GetFunction(tpl).ToLocalChecked());
2478}
2479
2480} // end of namespace imp
2481
2482template <typename T, template <typename> class HandleType>
2483inline void SetMethod(
2484 HandleType<T> recv
2485 , const char *name
2486 , FunctionCallback callback
2487 , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2488 HandleScope scope;
2489 v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(callback, data);
2490 v8::Local<v8::String> fn_name = New(name).ToLocalChecked();
2491 t->SetClassName(fn_name);
2492 // Note(@agnat): Pass an empty T* as discriminator. See note on
2493 // SetMethodAux(...) above
2494 imp::SetMethodAux(recv, fn_name, t, static_cast<T*>(0));
2495}
2496
2497inline void SetPrototypeMethod(
2498 v8::Local<v8::FunctionTemplate> recv
2499 , const char* name
2500 , FunctionCallback callback
2501 , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2502 HandleScope scope;
2503 v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(
2504 callback
2505 , data
2506 , New<v8::Signature>(recv));
2507 v8::Local<v8::String> fn_name = New(name).ToLocalChecked();
2508 recv->PrototypeTemplate()->Set(fn_name, t);
2509 t->SetClassName(fn_name);
2510}
2511
2512//=== Accessors and Such =======================================================
2513
2514NAN_DEPRECATED inline void SetAccessor(
2515 v8::Local<v8::ObjectTemplate> tpl
2516 , v8::Local<v8::String> name
2517 , GetterCallback getter
2518 , SetterCallback setter
2519 , v8::Local<v8::Value> data
2520 , v8::AccessControl settings
2521 , v8::PropertyAttribute attribute
2522 , imp::Sig signature) {
2523 HandleScope scope;
2524
2525 imp::NativeGetter getter_ =
2526 imp::GetterCallbackWrapper;
2527 imp::NativeSetter setter_ =
2528 setter ? imp::SetterCallbackWrapper : 0;
2529
2530 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2531 otpl->SetInternalFieldCount(imp::kAccessorFieldCount);
2532 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2533
2534 obj->SetInternalField(
2535 imp::kGetterIndex
2536 , New<v8::External>(reinterpret_cast<void *>(getter)));
2537
2538 if (setter != 0) {
2539 obj->SetInternalField(
2540 imp::kSetterIndex
2541 , New<v8::External>(reinterpret_cast<void *>(setter)));
2542 }
2543
2544 if (!data.IsEmpty()) {
2545 obj->SetInternalField(imp::kDataIndex, data);
2546 }
2547
2548 tpl->SetAccessor(
2549 name
2550 , getter_
2551 , setter_
2552 , obj
2553#if !defined(V8_MAJOR_VERSION) || V8_MAJOR_VERSION < 12
2554 , settings
2555#endif
2556 , attribute
2557#if (NODE_MODULE_VERSION < NODE_16_0_MODULE_VERSION)
2558 , signature
2559#endif
2560 );
2561}
2562
2563inline void SetAccessor(
2564 v8::Local<v8::ObjectTemplate> tpl
2565 , v8::Local<v8::String> name
2566 , GetterCallback getter
2567 , SetterCallback setter = 0
2568 , v8::Local<v8::Value> data = v8::Local<v8::Value>()
2569 , v8::AccessControl settings = v8::DEFAULT
2570 , v8::PropertyAttribute attribute = v8::None) {
2571 HandleScope scope;
2572
2573 imp::NativeGetter getter_ =
2574 imp::GetterCallbackWrapper;
2575 imp::NativeSetter setter_ =
2576 setter ? imp::SetterCallbackWrapper : 0;
2577
2578 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2579 otpl->SetInternalFieldCount(imp::kAccessorFieldCount);
2580 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2581
2582 obj->SetInternalField(
2583 imp::kGetterIndex
2584 , New<v8::External>(reinterpret_cast<void *>(getter)));
2585
2586 if (setter != 0) {
2587 obj->SetInternalField(
2588 imp::kSetterIndex
2589 , New<v8::External>(reinterpret_cast<void *>(setter)));
2590 }
2591
2592 if (!data.IsEmpty()) {
2593 obj->SetInternalField(imp::kDataIndex, data);
2594 }
2595
2596 tpl->SetAccessor(
2597 name
2598 , getter_
2599 , setter_
2600 , obj
2601#if !defined(V8_MAJOR_VERSION) || V8_MAJOR_VERSION < 12
2602 , settings
2603#endif
2604 , attribute
2605 );
2606}
2607
2608inline bool SetAccessor(
2609 v8::Local<v8::Object> obj
2610 , v8::Local<v8::String> name
2611 , GetterCallback getter
2612 , SetterCallback setter = 0
2613 , v8::Local<v8::Value> data = v8::Local<v8::Value>()
2614 , v8::AccessControl settings = v8::DEFAULT
2615 , v8::PropertyAttribute attribute = v8::None) {
2616 HandleScope scope;
2617
2618 imp::NativeGetter getter_ =
2619 imp::GetterCallbackWrapper;
2620 imp::NativeSetter setter_ =
2621 setter ? imp::SetterCallbackWrapper : 0;
2622
2623 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2624 otpl->SetInternalFieldCount(imp::kAccessorFieldCount);
2625 v8::Local<v8::Object> dataobj = NewInstance(otpl).ToLocalChecked();
2626
2627 dataobj->SetInternalField(
2628 imp::kGetterIndex
2629 , New<v8::External>(reinterpret_cast<void *>(getter)));
2630
2631 if (!data.IsEmpty()) {
2632 dataobj->SetInternalField(imp::kDataIndex, data);
2633 }
2634
2635 if (setter) {
2636 dataobj->SetInternalField(
2637 imp::kSetterIndex
2638 , New<v8::External>(reinterpret_cast<void *>(setter)));
2639 }
2640
2641#if (NODE_MODULE_VERSION >= NODE_6_0_MODULE_VERSION)
2642 return obj->SetAccessor(
2643 GetCurrentContext()
2644 , name
2645 , getter_
2646 , setter_
2647 , dataobj
2648 , settings
2649 , attribute).FromMaybe(false);
2650#else
2651 return obj->SetAccessor(
2652 name
2653 , getter_
2654 , setter_
2655 , dataobj
2656 , settings
2657 , attribute);
2658#endif
2659}
2660
2661inline void SetNamedPropertyHandler(
2662 v8::Local<v8::ObjectTemplate> tpl
2663 , PropertyGetterCallback getter
2664 , PropertySetterCallback setter = 0
2665 , PropertyQueryCallback query = 0
2666 , PropertyDeleterCallback deleter = 0
2667 , PropertyEnumeratorCallback enumerator = 0
2668 , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2669 HandleScope scope;
2670
2671 imp::NativePropertyGetter getter_ =
2672 imp::PropertyGetterCallbackWrapper;
2673 imp::NativePropertySetter setter_ =
2674 setter ? imp::PropertySetterCallbackWrapper : 0;
2675 imp::NativePropertyQuery query_ =
2676 query ? imp::PropertyQueryCallbackWrapper : 0;
2677 imp::NativePropertyDeleter *deleter_ =
2678 deleter ? imp::PropertyDeleterCallbackWrapper : 0;
2679 imp::NativePropertyEnumerator enumerator_ =
2680 enumerator ? imp::PropertyEnumeratorCallbackWrapper : 0;
2681
2682 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2683 otpl->SetInternalFieldCount(imp::kPropertyFieldCount);
2684 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2685 obj->SetInternalField(
2686 imp::kPropertyGetterIndex
2687 , New<v8::External>(reinterpret_cast<void *>(getter)));
2688
2689 if (setter) {
2690 obj->SetInternalField(
2691 imp::kPropertySetterIndex
2692 , New<v8::External>(reinterpret_cast<void *>(setter)));
2693 }
2694
2695 if (query) {
2696 obj->SetInternalField(
2697 imp::kPropertyQueryIndex
2698 , New<v8::External>(reinterpret_cast<void *>(query)));
2699 }
2700
2701 if (deleter) {
2702 obj->SetInternalField(
2703 imp::kPropertyDeleterIndex
2704 , New<v8::External>(reinterpret_cast<void *>(deleter)));
2705 }
2706
2707 if (enumerator) {
2708 obj->SetInternalField(
2709 imp::kPropertyEnumeratorIndex
2710 , New<v8::External>(reinterpret_cast<void *>(enumerator)));
2711 }
2712
2713 if (!data.IsEmpty()) {
2714 obj->SetInternalField(imp::kDataIndex, data);
2715 }
2716
2717#if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
2718 tpl->SetHandler(v8::NamedPropertyHandlerConfiguration(
2719 getter_, setter_, query_, deleter_, enumerator_, obj));
2720#else
2721 tpl->SetNamedPropertyHandler(
2722 getter_
2723 , setter_
2724 , query_
2725 , deleter_
2726 , enumerator_
2727 , obj);
2728#endif
2729}
2730
2731inline void SetIndexedPropertyHandler(
2732 v8::Local<v8::ObjectTemplate> tpl
2733 , IndexGetterCallback getter
2734 , IndexSetterCallback setter = 0
2735 , IndexQueryCallback query = 0
2736 , IndexDeleterCallback deleter = 0
2737 , IndexEnumeratorCallback enumerator = 0
2738 , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2739 HandleScope scope;
2740
2741 imp::NativeIndexGetter getter_ =
2742 imp::IndexGetterCallbackWrapper;
2743 imp::NativeIndexSetter setter_ =
2744 setter ? imp::IndexSetterCallbackWrapper : 0;
2745 imp::NativeIndexQuery query_ =
2746 query ? imp::IndexQueryCallbackWrapper : 0;
2747 imp::NativeIndexDeleter deleter_ =
2748 deleter ? imp::IndexDeleterCallbackWrapper : 0;
2749 imp::NativeIndexEnumerator enumerator_ =
2750 enumerator ? imp::IndexEnumeratorCallbackWrapper : 0;
2751
2752 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2753 otpl->SetInternalFieldCount(imp::kIndexPropertyFieldCount);
2754 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2755 obj->SetInternalField(
2756 imp::kIndexPropertyGetterIndex
2757 , New<v8::External>(reinterpret_cast<void *>(getter)));
2758
2759 if (setter) {
2760 obj->SetInternalField(
2761 imp::kIndexPropertySetterIndex
2762 , New<v8::External>(reinterpret_cast<void *>(setter)));
2763 }
2764
2765 if (query) {
2766 obj->SetInternalField(
2767 imp::kIndexPropertyQueryIndex
2768 , New<v8::External>(reinterpret_cast<void *>(query)));
2769 }
2770
2771 if (deleter) {
2772 obj->SetInternalField(
2773 imp::kIndexPropertyDeleterIndex
2774 , New<v8::External>(reinterpret_cast<void *>(deleter)));
2775 }
2776
2777 if (enumerator) {
2778 obj->SetInternalField(
2779 imp::kIndexPropertyEnumeratorIndex
2780 , New<v8::External>(reinterpret_cast<void *>(enumerator)));
2781 }
2782
2783 if (!data.IsEmpty()) {
2784 obj->SetInternalField(imp::kDataIndex, data);
2785 }
2786
2787#if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
2788 tpl->SetHandler(v8::IndexedPropertyHandlerConfiguration(
2789 getter_, setter_, query_, deleter_, enumerator_, obj));
2790#else
2791 tpl->SetIndexedPropertyHandler(
2792 getter_
2793 , setter_
2794 , query_
2795 , deleter_
2796 , enumerator_
2797 , obj);
2798#endif
2799}
2800
2801inline void SetCallHandler(
2802 v8::Local<v8::FunctionTemplate> tpl
2803 , FunctionCallback callback
2804 , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2805 HandleScope scope;
2806
2807 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2808 otpl->SetInternalFieldCount(imp::kFunctionFieldCount);
2809 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2810
2811 obj->SetInternalField(
2812 imp::kFunctionIndex
2813 , New<v8::External>(reinterpret_cast<void *>(callback)));
2814
2815 if (!data.IsEmpty()) {
2816 obj->SetInternalField(imp::kDataIndex, data);
2817 }
2818
2819 tpl->SetCallHandler(imp::FunctionCallbackWrapper, obj);
2820}
2821
2822
2823inline void SetCallAsFunctionHandler(
2824 v8::Local<v8::ObjectTemplate> tpl,
2825 FunctionCallback callback,
2826 v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2827 HandleScope scope;
2828
2829 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2830 otpl->SetInternalFieldCount(imp::kFunctionFieldCount);
2831 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2832
2833 obj->SetInternalField(
2834 imp::kFunctionIndex
2835 , New<v8::External>(reinterpret_cast<void *>(callback)));
2836
2837 if (!data.IsEmpty()) {
2838 obj->SetInternalField(imp::kDataIndex, data);
2839 }
2840
2841 tpl->SetCallAsFunctionHandler(imp::FunctionCallbackWrapper, obj);
2842}
2843
2844//=== Weak Persistent Handling =================================================
2845
2846#include "nan_weak.h" // NOLINT(build/include)
2847
2848//=== ObjectWrap ===============================================================
2849
2850#include "nan_object_wrap.h" // NOLINT(build/include)
2851
2852//=== HiddenValue/Private ======================================================
2853
2854#include "nan_private.h" // NOLINT(build/include)
2855
2856//=== Export ==================================================================
2857
2858inline
2859void
2860Export(ADDON_REGISTER_FUNCTION_ARGS_TYPE target, const char *name,
2861 FunctionCallback f) {
2862 HandleScope scope;
2863
2864 Set(target, New<v8::String>(name).ToLocalChecked(),
2865 GetFunction(New<v8::FunctionTemplate>(f)).ToLocalChecked());
2866}
2867
2868//=== Tap Reverse Binding =====================================================
2869
2870struct Tap {
2871 explicit Tap(v8::Local<v8::Value> t) : t_() {
2872 HandleScope scope;
2873
2874 t_.Reset(To<v8::Object>(t).ToLocalChecked());
2875 }
2876
2877 ~Tap() { t_.Reset(); } // not sure if necessary
2878
2879 inline void plan(int i) {
2880 HandleScope scope;
2881 v8::Local<v8::Value> arg = New(i);
2882 Call("plan", New(t_), 1, &arg);
2883 }
2884
2885 inline void ok(bool isOk, const char *msg = NULL) {
2886 HandleScope scope;
2887 v8::Local<v8::Value> args[2];
2888 args[0] = New(isOk);
2889 if (msg) args[1] = New(msg).ToLocalChecked();
2890 Call("ok", New(t_), msg ? 2 : 1, args);
2891 }
2892
2893 inline void pass(const char * msg = NULL) {
2894 HandleScope scope;
2895 v8::Local<v8::Value> hmsg;
2896 if (msg) hmsg = New(msg).ToLocalChecked();
2897 Call("pass", New(t_), msg ? 1 : 0, &hmsg);
2898 }
2899
2900 inline void end() {
2901 HandleScope scope;
2902 Call("end", New(t_), 0, NULL);
2903 }
2904
2905 private:
2906 Persistent<v8::Object> t_;
2907};
2908
2909#define NAN_STRINGIZE2(x) #x
2910#define NAN_STRINGIZE(x) NAN_STRINGIZE2(x)
2911#define NAN_TEST_EXPRESSION(expression) \
2912 ( expression ), __FILE__ ":" NAN_STRINGIZE(__LINE__) ": " #expression
2913
2914#define NAN_EXPORT(target, function) Export(target, #function, function)
2915
2916#undef TYPE_CHECK
2917
2918//=== Generic Maybefication ===================================================
2919
2920namespace imp {
2921
2922template <typename T> struct Maybefier;
2923
2924template <typename T> struct Maybefier<v8::Local<T> > {
2925 inline static MaybeLocal<T> convert(v8::Local<T> v) {
2926 return v;
2927 }
2928};
2929
2930template <typename T> struct Maybefier<MaybeLocal<T> > {
2931 inline static MaybeLocal<T> convert(MaybeLocal<T> v) {
2932 return v;
2933 }
2934};
2935
2936} // end of namespace imp
2937
2938template <typename T, template <typename> class MaybeMaybe>
2939inline MaybeLocal<T>
2940MakeMaybe(MaybeMaybe<T> v) {
2941 return imp::Maybefier<MaybeMaybe<T> >::convert(v);
2942}
2943
2944//=== TypedArrayContents =======================================================
2945
2946#include "nan_typedarray_contents.h" // NOLINT(build/include)
2947
2948//=== JSON =====================================================================
2949
2950#include "nan_json.h" // NOLINT(build/include)
2951
2952//=== ScriptOrigin =============================================================
2953
2954#include "nan_scriptorigin.h" // NOLINT(build/include)
2955
2956} // end of namespace Nan
2957
2958#endif // NAN_H_