1 /*********************************************************************
2 * NAN - Native Abstractions for Node.js
4 * Copyright (c) 2017 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>
13 * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
15 * Version 2.5.1: current Node 7.4.0, Node 12: 0.12.18, Node 10: 0.10.48, iojs: 3.3.1
17 * See https://github.com/nodejs/nan for the latest update to this file
18 **********************************************************************************/
23 #include <node_version.h>
25 #define NODE_0_10_MODULE_VERSION 11
26 #define NODE_0_12_MODULE_VERSION 14
27 #define ATOM_0_21_MODULE_VERSION 41
28 #define IOJS_1_0_MODULE_VERSION 42
29 #define IOJS_1_1_MODULE_VERSION 43
30 #define IOJS_2_0_MODULE_VERSION 44
31 #define IOJS_3_0_MODULE_VERSION 45
32 #define NODE_4_0_MODULE_VERSION 46
33 #define NODE_5_0_MODULE_VERSION 47
34 #define NODE_6_0_MODULE_VERSION 48
37 # define NAN_HAS_CPLUSPLUS_11 (_MSC_VER >= 1800)
39 # define NAN_HAS_CPLUSPLUS_11 (__cplusplus >= 201103L)
42 #if NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION && !NAN_HAS_CPLUSPLUS_11
43 # error This version of node/NAN/v8 requires a C++11 compiler
48 #include <node_buffer.h>
49 #include <node_object_wrap.h>
55 # pragma warning( push )
56 # pragma warning( disable : 4530 )
59 # pragma warning( pop )
66 #ifdef UV_VERSION_MAJOR
67 # ifndef UV_VERSION_PATCH
68 # define UV_VERSION_PATCH 0
70 # define NAUV_UVVERSION ((UV_VERSION_MAJOR << 16) | \
71 (UV_VERSION_MINOR << 8) | \
74 # define NAUV_UVVERSION 0x000b00
77 #if NAUV_UVVERSION < 0x000b0b
87 #define NAN_INLINE inline // TODO(bnoordhuis) Remove in v3.0.0.
89 #if defined(__GNUC__) && \
90 !(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
91 # define NAN_DEPRECATED __attribute__((deprecated))
92 #elif defined(_MSC_VER) && \
93 !(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
94 # define NAN_DEPRECATED __declspec(deprecated)
96 # define NAN_DEPRECATED
99 #if NAN_HAS_CPLUSPLUS_11
100 # define NAN_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete;
101 # define NAN_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete;
102 # define NAN_DISALLOW_MOVE(CLASS) \
103 CLASS(CLASS&&) = delete; /* NOLINT(build/c++11) */ \
104 void operator=(CLASS&&) = delete;
106 # define NAN_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&);
107 # define NAN_DISALLOW_COPY(CLASS) CLASS(const CLASS&);
108 # define NAN_DISALLOW_MOVE(CLASS)
111 #define NAN_DISALLOW_ASSIGN_COPY(CLASS) \
112 NAN_DISALLOW_ASSIGN(CLASS) \
113 NAN_DISALLOW_COPY(CLASS)
115 #define NAN_DISALLOW_ASSIGN_MOVE(CLASS) \
116 NAN_DISALLOW_ASSIGN(CLASS) \
117 NAN_DISALLOW_MOVE(CLASS)
119 #define NAN_DISALLOW_COPY_MOVE(CLASS) \
120 NAN_DISALLOW_COPY(CLASS) \
121 NAN_DISALLOW_MOVE(CLASS)
123 #define NAN_DISALLOW_ASSIGN_COPY_MOVE(CLASS) \
124 NAN_DISALLOW_ASSIGN(CLASS) \
125 NAN_DISALLOW_COPY(CLASS) \
126 NAN_DISALLOW_MOVE(CLASS)
128 #define TYPE_CHECK(T, S) \
130 *(static_cast<T *volatile *>(0)) = static_cast<S*>(0); \
133 //=== RegistrationFunction =====================================================
135 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
136 typedef v8::Handle<v8::Object> ADDON_REGISTER_FUNCTION_ARGS_TYPE;
138 typedef v8::Local<v8::Object> ADDON_REGISTER_FUNCTION_ARGS_TYPE;
141 #define NAN_MODULE_INIT(name) \
142 void name(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target)
144 //=== CallbackInfo =============================================================
146 #include "nan_callbacks.h" // NOLINT(build/include)
148 //==============================================================================
150 #if (NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION)
151 typedef v8::Script UnboundScript;
152 typedef v8::Script BoundScript;
154 typedef v8::UnboundScript UnboundScript;
155 typedef v8::Script BoundScript;
158 #if (NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION)
159 typedef v8::String::ExternalAsciiStringResource
160 ExternalOneByteStringResource;
162 typedef v8::String::ExternalOneByteStringResource
163 ExternalOneByteStringResource;
166 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
168 class NonCopyablePersistentTraits :
169 public v8::NonCopyablePersistentTraits<T> {};
171 class CopyablePersistentTraits :
172 public v8::CopyablePersistentTraits<T> {};
175 class PersistentBase :
176 public v8::PersistentBase<T> {};
178 template<typename T, typename M = v8::NonCopyablePersistentTraits<T> >
181 template<typename T> class NonCopyablePersistentTraits;
182 template<typename T> class PersistentBase;
183 template<typename T, typename P> class WeakCallbackData;
184 template<typename T, typename M = NonCopyablePersistentTraits<T> >
186 #endif // NODE_MODULE_VERSION
188 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
189 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
190 # include "nan_maybe_43_inl.h" // NOLINT(build/include)
192 # include "nan_maybe_pre_43_inl.h" // NOLINT(build/include)
195 #include "nan_converters.h" // NOLINT(build/include)
196 #include "nan_new.h" // NOLINT(build/include)
198 #if NAUV_UVVERSION < 0x000b17
199 #define NAUV_WORK_CB(func) \
200 void func(uv_async_t *async, int)
202 #define NAUV_WORK_CB(func) \
203 void func(uv_async_t *async)
206 #if NAUV_UVVERSION >= 0x000b0b
208 typedef uv_key_t nauv_key_t;
210 inline int nauv_key_create(nauv_key_t *key) {
211 return uv_key_create(key);
214 inline void nauv_key_delete(nauv_key_t *key) {
218 inline void* nauv_key_get(nauv_key_t *key) {
219 return uv_key_get(key);
222 inline void nauv_key_set(nauv_key_t *key, void *value) {
223 uv_key_set(key, value);
228 /* Implement thread local storage for older versions of libuv.
229 * This is essentially a backport of libuv commit 5d2434bf
230 * written by Ben Noordhuis, adjusted for names and inline.
235 typedef pthread_key_t nauv_key_t;
237 inline int nauv_key_create(nauv_key_t* key) {
238 return -pthread_key_create(key, NULL);
241 inline void nauv_key_delete(nauv_key_t* key) {
242 if (pthread_key_delete(*key))
246 inline void* nauv_key_get(nauv_key_t* key) {
247 return pthread_getspecific(*key);
250 inline void nauv_key_set(nauv_key_t* key, void* value) {
251 if (pthread_setspecific(*key, value))
261 inline int nauv_key_create(nauv_key_t* key) {
262 key->tls_index = TlsAlloc();
263 if (key->tls_index == TLS_OUT_OF_INDEXES)
268 inline void nauv_key_delete(nauv_key_t* key) {
269 if (TlsFree(key->tls_index) == FALSE)
271 key->tls_index = TLS_OUT_OF_INDEXES;
274 inline void* nauv_key_get(nauv_key_t* key) {
275 void* value = TlsGetValue(key->tls_index);
277 if (GetLastError() != ERROR_SUCCESS)
282 inline void nauv_key_set(nauv_key_t* key, void* value) {
283 if (TlsSetValue(key->tls_index, value) == FALSE)
290 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
292 v8::Local<T> New(v8::Handle<T>);
295 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
296 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
297 typedef v8::WeakCallbackType WeakCallbackType;
299 struct WeakCallbackType {
300 enum E {kParameter, kInternalFields};
302 WeakCallbackType(E other) : type(other) {} // NOLINT(runtime/explicit)
303 inline bool operator==(E other) { return other == this->type; }
304 inline bool operator!=(E other) { return !operator==(other); }
308 template<typename P> class WeakCallbackInfo;
310 #if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
311 # include "nan_persistent_12_inl.h" // NOLINT(build/include)
313 # include "nan_persistent_pre_12_inl.h" // NOLINT(build/include)
317 static const size_t kMaxLength = 0x3fffffff;
318 // v8::String::REPLACE_INVALID_UTF8 was introduced
319 // in node.js v0.10.29 and v0.8.27.
320 #if NODE_MAJOR_VERSION > 0 || \
321 NODE_MINOR_VERSION > 10 || \
322 NODE_MINOR_VERSION == 10 && NODE_PATCH_VERSION >= 29 || \
323 NODE_MINOR_VERSION == 8 && NODE_PATCH_VERSION >= 27
324 static const unsigned kReplaceInvalidUtf8 = v8::String::REPLACE_INVALID_UTF8;
326 static const unsigned kReplaceInvalidUtf8 = 0;
328 } // end of namespace imp
330 //=== HandleScope ==============================================================
333 v8::HandleScope scope;
336 #if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
337 inline HandleScope() : scope(v8::Isolate::GetCurrent()) {}
338 inline static int NumberOfHandles() {
339 return v8::HandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
342 inline HandleScope() : scope() {}
343 inline static int NumberOfHandles() {
344 return v8::HandleScope::NumberOfHandles();
349 // Make it hard to create heap-allocated or illegal handle scopes by
350 // disallowing certain operations.
351 HandleScope(const HandleScope &);
352 void operator=(const HandleScope &);
353 void *operator new(size_t size);
354 void operator delete(void *, size_t) {
359 class EscapableHandleScope {
361 #if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
362 inline EscapableHandleScope() : scope(v8::Isolate::GetCurrent()) {}
364 inline static int NumberOfHandles() {
365 return v8::EscapableHandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
369 inline v8::Local<T> Escape(v8::Local<T> value) {
370 return scope.Escape(value);
374 v8::EscapableHandleScope scope;
376 inline EscapableHandleScope() : scope() {}
378 inline static int NumberOfHandles() {
379 return v8::HandleScope::NumberOfHandles();
383 inline v8::Local<T> Escape(v8::Local<T> value) {
384 return scope.Close(value);
388 v8::HandleScope scope;
392 // Make it hard to create heap-allocated or illegal handle scopes by
393 // disallowing certain operations.
394 EscapableHandleScope(const EscapableHandleScope &);
395 void operator=(const EscapableHandleScope &);
396 void *operator new(size_t size);
397 void operator delete(void *, size_t) {
402 //=== TryCatch =================================================================
405 v8::TryCatch try_catch_;
406 friend void FatalException(const TryCatch&);
409 #if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
410 TryCatch() : try_catch_(v8::Isolate::GetCurrent()) {}
413 inline bool HasCaught() const { return try_catch_.HasCaught(); }
415 inline bool CanContinue() const { return try_catch_.CanContinue(); }
417 inline v8::Local<v8::Value> ReThrow() {
418 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
419 return New(try_catch_.ReThrow());
421 return try_catch_.ReThrow();
425 inline v8::Local<v8::Value> Exception() const {
426 return try_catch_.Exception();
429 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
430 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
431 inline v8::MaybeLocal<v8::Value> StackTrace() const {
432 v8::Isolate *isolate = v8::Isolate::GetCurrent();
433 v8::EscapableHandleScope scope(isolate);
434 return scope.Escape(try_catch_.StackTrace(isolate->GetCurrentContext())
435 .FromMaybe(v8::Local<v8::Value>()));
438 inline MaybeLocal<v8::Value> StackTrace() const {
439 return try_catch_.StackTrace();
443 inline v8::Local<v8::Message> Message() const {
444 return try_catch_.Message();
447 inline void Reset() { try_catch_.Reset(); }
449 inline void SetVerbose(bool value) { try_catch_.SetVerbose(value); }
451 inline void SetCaptureMessage(bool value) {
452 try_catch_.SetCaptureMessage(value);
456 //============ =================================================================
459 #if NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION
461 void SetCounterFunction(v8::CounterLookupCallback cb) {
462 v8::Isolate::GetCurrent()->SetCounterFunction(cb);
466 void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
467 v8::Isolate::GetCurrent()->SetCreateHistogramFunction(cb);
471 void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
472 v8::Isolate::GetCurrent()->SetAddHistogramSampleFunction(cb);
475 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
476 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
477 inline bool IdleNotification(int idle_time_in_ms) {
478 return v8::Isolate::GetCurrent()->IdleNotificationDeadline(
479 idle_time_in_ms * 0.001);
482 inline bool IdleNotification(int idle_time_in_ms) {
483 return v8::Isolate::GetCurrent()->IdleNotification(idle_time_in_ms);
487 inline void LowMemoryNotification() {
488 v8::Isolate::GetCurrent()->LowMemoryNotification();
491 inline void ContextDisposedNotification() {
492 v8::Isolate::GetCurrent()->ContextDisposedNotification();
496 void SetCounterFunction(v8::CounterLookupCallback cb) {
497 v8::V8::SetCounterFunction(cb);
501 void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
502 v8::V8::SetCreateHistogramFunction(cb);
506 void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
507 v8::V8::SetAddHistogramSampleFunction(cb);
510 inline bool IdleNotification(int idle_time_in_ms) {
511 return v8::V8::IdleNotification(idle_time_in_ms);
514 inline void LowMemoryNotification() {
515 v8::V8::LowMemoryNotification();
518 inline void ContextDisposedNotification() {
519 v8::V8::ContextDisposedNotification();
523 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION) // Node 0.12
524 inline v8::Local<v8::Primitive> Undefined() {
525 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
526 EscapableHandleScope scope;
527 return scope.Escape(New(v8::Undefined(v8::Isolate::GetCurrent())));
529 return v8::Undefined(v8::Isolate::GetCurrent());
533 inline v8::Local<v8::Primitive> Null() {
534 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
535 EscapableHandleScope scope;
536 return scope.Escape(New(v8::Null(v8::Isolate::GetCurrent())));
538 return v8::Null(v8::Isolate::GetCurrent());
542 inline v8::Local<v8::Boolean> True() {
543 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
544 EscapableHandleScope scope;
545 return scope.Escape(New(v8::True(v8::Isolate::GetCurrent())));
547 return v8::True(v8::Isolate::GetCurrent());
551 inline v8::Local<v8::Boolean> False() {
552 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
553 EscapableHandleScope scope;
554 return scope.Escape(New(v8::False(v8::Isolate::GetCurrent())));
556 return v8::False(v8::Isolate::GetCurrent());
560 inline v8::Local<v8::String> EmptyString() {
561 return v8::String::Empty(v8::Isolate::GetCurrent());
564 inline int AdjustExternalMemory(int bc) {
565 return static_cast<int>(
566 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
569 inline void SetTemplate(
570 v8::Local<v8::Template> templ
572 , v8::Local<v8::Data> value) {
573 templ->Set(v8::Isolate::GetCurrent(), name, value);
576 inline void SetTemplate(
577 v8::Local<v8::Template> templ
578 , v8::Local<v8::String> name
579 , v8::Local<v8::Data> value
580 , v8::PropertyAttribute attributes) {
581 templ->Set(name, value, attributes);
584 inline v8::Local<v8::Context> GetCurrentContext() {
585 return v8::Isolate::GetCurrent()->GetCurrentContext();
588 inline void* GetInternalFieldPointer(
589 v8::Local<v8::Object> object
591 return object->GetAlignedPointerFromInternalField(index);
594 inline void SetInternalFieldPointer(
595 v8::Local<v8::Object> object
598 object->SetAlignedPointerInInternalField(index, value);
601 # define NAN_GC_CALLBACK(name) \
602 void name(v8::Isolate *isolate, v8::GCType type, v8::GCCallbackFlags flags)
604 #if NODE_MODULE_VERSION <= NODE_4_0_MODULE_VERSION
605 typedef v8::Isolate::GCEpilogueCallback GCEpilogueCallback;
606 typedef v8::Isolate::GCPrologueCallback GCPrologueCallback;
608 typedef v8::Isolate::GCCallback GCEpilogueCallback;
609 typedef v8::Isolate::GCCallback GCPrologueCallback;
612 inline void AddGCEpilogueCallback(
613 GCEpilogueCallback callback
614 , v8::GCType gc_type_filter = v8::kGCTypeAll) {
615 v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);
618 inline void RemoveGCEpilogueCallback(
619 GCEpilogueCallback callback) {
620 v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);
623 inline void AddGCPrologueCallback(
624 GCPrologueCallback callback
625 , v8::GCType gc_type_filter = v8::kGCTypeAll) {
626 v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);
629 inline void RemoveGCPrologueCallback(
630 GCPrologueCallback callback) {
631 v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);
634 inline void GetHeapStatistics(
635 v8::HeapStatistics *heap_statistics) {
636 v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);
640 inline v8::Local<v8::Value> NAME(const char *msg) { \
641 EscapableHandleScope scope; \
642 return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked())); \
646 v8::Local<v8::Value> NAME(v8::Local<v8::String> msg) { \
647 return v8::Exception::NAME(msg); \
650 inline void Throw ## NAME(const char *msg) { \
652 v8::Isolate::GetCurrent()->ThrowException( \
653 v8::Exception::NAME(New(msg).ToLocalChecked())); \
656 inline void Throw ## NAME(v8::Local<v8::String> msg) { \
658 v8::Isolate::GetCurrent()->ThrowException( \
659 v8::Exception::NAME(msg)); \
670 inline void ThrowError(v8::Local<v8::Value> error) {
671 v8::Isolate::GetCurrent()->ThrowException(error);
674 inline MaybeLocal<v8::Object> NewBuffer(
677 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
678 , node::Buffer::FreeCallback callback
680 , node::smalloc::FreeCallback callback
684 // arbitrary buffer lengths requires
685 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
686 assert(length <= imp::kMaxLength && "too large buffer");
687 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
688 return node::Buffer::New(
689 v8::Isolate::GetCurrent(), data, length, callback, hint);
691 return node::Buffer::New(v8::Isolate::GetCurrent(), data, length, callback,
696 inline MaybeLocal<v8::Object> CopyBuffer(
700 // arbitrary buffer lengths requires
701 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
702 assert(size <= imp::kMaxLength && "too large buffer");
703 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
704 return node::Buffer::Copy(
705 v8::Isolate::GetCurrent(), data, size);
707 return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
711 inline MaybeLocal<v8::Object> NewBuffer(uint32_t size) {
712 // arbitrary buffer lengths requires
713 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
714 assert(size <= imp::kMaxLength && "too large buffer");
715 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
716 return node::Buffer::New(
717 v8::Isolate::GetCurrent(), size);
719 return node::Buffer::New(v8::Isolate::GetCurrent(), size);
723 inline MaybeLocal<v8::Object> NewBuffer(
727 // arbitrary buffer lengths requires
728 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
729 assert(size <= imp::kMaxLength && "too large buffer");
730 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
731 return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
733 return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
737 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
738 (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
739 inline MaybeLocal<v8::String>
740 NewOneByteString(const uint8_t * value, int length = -1) {
741 return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), value,
742 v8::NewStringType::kNormal, length);
745 inline MaybeLocal<BoundScript> CompileScript(
746 v8::Local<v8::String> s
747 , const v8::ScriptOrigin& origin
749 v8::Isolate *isolate = v8::Isolate::GetCurrent();
750 v8::EscapableHandleScope scope(isolate);
751 v8::ScriptCompiler::Source source(s, origin);
753 v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &source)
754 .FromMaybe(v8::Local<BoundScript>()));
757 inline MaybeLocal<BoundScript> CompileScript(
758 v8::Local<v8::String> s
760 v8::Isolate *isolate = v8::Isolate::GetCurrent();
761 v8::EscapableHandleScope scope(isolate);
762 v8::ScriptCompiler::Source source(s);
764 v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &source)
765 .FromMaybe(v8::Local<BoundScript>()));
768 inline MaybeLocal<v8::Value> RunScript(
769 v8::Local<UnboundScript> script
771 v8::Isolate *isolate = v8::Isolate::GetCurrent();
772 v8::EscapableHandleScope scope(isolate);
773 return scope.Escape(script->BindToCurrentContext()
774 ->Run(isolate->GetCurrentContext())
775 .FromMaybe(v8::Local<v8::Value>()));
778 inline MaybeLocal<v8::Value> RunScript(
779 v8::Local<BoundScript> script
781 v8::Isolate *isolate = v8::Isolate::GetCurrent();
782 v8::EscapableHandleScope scope(isolate);
783 return scope.Escape(script->Run(isolate->GetCurrentContext())
784 .FromMaybe(v8::Local<v8::Value>()));
787 inline MaybeLocal<v8::String>
788 NewOneByteString(const uint8_t * value, int length = -1) {
789 return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), value,
790 v8::String::kNormalString, length);
793 inline MaybeLocal<BoundScript> CompileScript(
794 v8::Local<v8::String> s
795 , const v8::ScriptOrigin& origin
797 v8::ScriptCompiler::Source source(s, origin);
798 return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
801 inline MaybeLocal<BoundScript> CompileScript(
802 v8::Local<v8::String> s
804 v8::ScriptCompiler::Source source(s);
805 return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
808 inline MaybeLocal<v8::Value> RunScript(
809 v8::Local<UnboundScript> script
811 EscapableHandleScope scope;
812 return scope.Escape(script->BindToCurrentContext()->Run());
815 inline MaybeLocal<v8::Value> RunScript(
816 v8::Local<BoundScript> script
818 return script->Run();
822 inline v8::Local<v8::Value> MakeCallback(
823 v8::Local<v8::Object> target
824 , v8::Local<v8::Function> func
826 , v8::Local<v8::Value>* argv) {
827 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
828 EscapableHandleScope scope;
829 return scope.Escape(New(node::MakeCallback(
830 v8::Isolate::GetCurrent(), target, func, argc, argv)));
832 return node::MakeCallback(
833 v8::Isolate::GetCurrent(), target, func, argc, argv);
837 inline v8::Local<v8::Value> MakeCallback(
838 v8::Local<v8::Object> target
839 , v8::Local<v8::String> symbol
841 , v8::Local<v8::Value>* argv) {
842 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
843 EscapableHandleScope scope;
844 return scope.Escape(New(node::MakeCallback(
845 v8::Isolate::GetCurrent(), target, symbol, argc, argv)));
847 return node::MakeCallback(
848 v8::Isolate::GetCurrent(), target, symbol, argc, argv);
852 inline v8::Local<v8::Value> MakeCallback(
853 v8::Local<v8::Object> target
856 , v8::Local<v8::Value>* argv) {
857 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
858 EscapableHandleScope scope;
859 return scope.Escape(New(node::MakeCallback(
860 v8::Isolate::GetCurrent(), target, method, argc, argv)));
862 return node::MakeCallback(
863 v8::Isolate::GetCurrent(), target, method, argc, argv);
867 inline void FatalException(const TryCatch& try_catch) {
868 node::FatalException(v8::Isolate::GetCurrent(), try_catch.try_catch_);
871 inline v8::Local<v8::Value> ErrnoException(
873 , const char* syscall = NULL
874 , const char* message = NULL
875 , const char* path = NULL) {
876 return node::ErrnoException(v8::Isolate::GetCurrent(), errorno, syscall,
880 NAN_DEPRECATED inline v8::Local<v8::Value> NanErrnoException(
882 , const char* syscall = NULL
883 , const char* message = NULL
884 , const char* path = NULL) {
885 return ErrnoException(errorno, syscall, message, path);
889 inline void SetIsolateData(
893 isolate->SetData(0, data);
897 inline T *GetIsolateData(
900 return static_cast<T*>(isolate->GetData(0));
905 inline explicit Utf8String(v8::Local<v8::Value> from) :
906 length_(0), str_(str_st_) {
908 if (!from.IsEmpty()) {
909 v8::Local<v8::String> string = from->ToString();
910 if (!string.IsEmpty()) {
911 size_t len = 3 * string->Length() + 1;
912 assert(len <= INT_MAX);
913 if (len > sizeof (str_st_)) {
914 str_ = static_cast<char*>(malloc(len));
918 v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
919 length_ = string->WriteUtf8(str_, static_cast<int>(len), 0, flags);
920 str_[length_] = '\0';
925 inline int length() const {
929 inline char* operator*() { return str_; }
930 inline const char* operator*() const { return str_; }
932 inline ~Utf8String() {
933 if (str_ != str_st_) {
939 NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
946 #else // Node 0.8 and 0.10
947 inline v8::Local<v8::Primitive> Undefined() {
948 EscapableHandleScope scope;
949 return scope.Escape(New(v8::Undefined()));
952 inline v8::Local<v8::Primitive> Null() {
953 EscapableHandleScope scope;
954 return scope.Escape(New(v8::Null()));
957 inline v8::Local<v8::Boolean> True() {
958 EscapableHandleScope scope;
959 return scope.Escape(New(v8::True()));
962 inline v8::Local<v8::Boolean> False() {
963 EscapableHandleScope scope;
964 return scope.Escape(New(v8::False()));
967 inline v8::Local<v8::String> EmptyString() {
968 return v8::String::Empty();
971 inline int AdjustExternalMemory(int bc) {
972 return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
975 inline void SetTemplate(
976 v8::Local<v8::Template> templ
978 , v8::Local<v8::Data> value) {
979 templ->Set(name, value);
982 inline void SetTemplate(
983 v8::Local<v8::Template> templ
984 , v8::Local<v8::String> name
985 , v8::Local<v8::Data> value
986 , v8::PropertyAttribute attributes) {
987 templ->Set(name, value, attributes);
990 inline v8::Local<v8::Context> GetCurrentContext() {
991 return v8::Context::GetCurrent();
994 inline void* GetInternalFieldPointer(
995 v8::Local<v8::Object> object
997 return object->GetPointerFromInternalField(index);
1000 inline void SetInternalFieldPointer(
1001 v8::Local<v8::Object> object
1004 object->SetPointerInInternalField(index, value);
1007 # define NAN_GC_CALLBACK(name) \
1008 void name(v8::GCType type, v8::GCCallbackFlags flags)
1010 inline void AddGCEpilogueCallback(
1011 v8::GCEpilogueCallback callback
1012 , v8::GCType gc_type_filter = v8::kGCTypeAll) {
1013 v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);
1015 inline void RemoveGCEpilogueCallback(
1016 v8::GCEpilogueCallback callback) {
1017 v8::V8::RemoveGCEpilogueCallback(callback);
1019 inline void AddGCPrologueCallback(
1020 v8::GCPrologueCallback callback
1021 , v8::GCType gc_type_filter = v8::kGCTypeAll) {
1022 v8::V8::AddGCPrologueCallback(callback, gc_type_filter);
1024 inline void RemoveGCPrologueCallback(
1025 v8::GCPrologueCallback callback) {
1026 v8::V8::RemoveGCPrologueCallback(callback);
1028 inline void GetHeapStatistics(
1029 v8::HeapStatistics *heap_statistics) {
1030 v8::V8::GetHeapStatistics(heap_statistics);
1034 inline v8::Local<v8::Value> NAME(const char *msg) { \
1035 EscapableHandleScope scope; \
1036 return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked())); \
1040 v8::Local<v8::Value> NAME(v8::Local<v8::String> msg) { \
1041 return v8::Exception::NAME(msg); \
1044 inline void Throw ## NAME(const char *msg) { \
1045 HandleScope scope; \
1046 v8::ThrowException(v8::Exception::NAME(New(msg).ToLocalChecked())); \
1050 void Throw ## NAME(v8::Local<v8::String> errmsg) { \
1051 HandleScope scope; \
1052 v8::ThrowException(v8::Exception::NAME(errmsg)); \
1063 inline void ThrowError(v8::Local<v8::Value> error) {
1064 v8::ThrowException(error);
1067 inline MaybeLocal<v8::Object> NewBuffer(
1070 , node::Buffer::free_callback callback
1073 EscapableHandleScope scope;
1074 // arbitrary buffer lengths requires
1075 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1076 assert(length <= imp::kMaxLength && "too large buffer");
1077 return scope.Escape(
1078 New(node::Buffer::New(data, length, callback, hint)->handle_));
1081 inline MaybeLocal<v8::Object> CopyBuffer(
1085 EscapableHandleScope scope;
1086 // arbitrary buffer lengths requires
1087 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1088 assert(size <= imp::kMaxLength && "too large buffer");
1089 #if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
1090 return scope.Escape(New(node::Buffer::New(data, size)->handle_));
1092 return scope.Escape(
1093 New(node::Buffer::New(const_cast<char *>(data), size)->handle_));
1097 inline MaybeLocal<v8::Object> NewBuffer(uint32_t size) {
1098 // arbitrary buffer lengths requires
1099 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1100 EscapableHandleScope scope;
1101 assert(size <= imp::kMaxLength && "too large buffer");
1102 return scope.Escape(New(node::Buffer::New(size)->handle_));
1105 inline void FreeData(char *data, void *hint) {
1106 (void) hint; // unused
1110 inline MaybeLocal<v8::Object> NewBuffer(
1114 EscapableHandleScope scope;
1115 // arbitrary buffer lengths requires
1116 // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1117 assert(size <= imp::kMaxLength && "too large buffer");
1118 return scope.Escape(
1119 New(node::Buffer::New(data, size, FreeData, NULL)->handle_));
1124 widenString(std::vector<uint16_t> *ws, const uint8_t *s, int l) {
1125 size_t len = static_cast<size_t>(l);
1127 len = strlen(reinterpret_cast<const char*>(s));
1129 assert(len <= INT_MAX && "string too long");
1131 std::copy(s, s + len, ws->begin()); // NOLINT(build/include_what_you_use)
1133 } // end of namespace imp
1135 inline MaybeLocal<v8::String>
1136 NewOneByteString(const uint8_t * value, int length = -1) {
1137 std::vector<uint16_t> wideString; // NOLINT(build/include_what_you_use)
1138 imp::widenString(&wideString, value, length);
1139 return v8::String::New(wideString.data(),
1140 static_cast<int>(wideString.size()));
1143 inline MaybeLocal<BoundScript> CompileScript(
1144 v8::Local<v8::String> s
1145 , const v8::ScriptOrigin& origin
1147 return v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin));
1150 inline MaybeLocal<BoundScript> CompileScript(
1151 v8::Local<v8::String> s
1153 return v8::Script::Compile(s);
1157 MaybeLocal<v8::Value> RunScript(v8::Local<v8::Script> script) {
1158 return script->Run();
1161 inline v8::Local<v8::Value> MakeCallback(
1162 v8::Local<v8::Object> target
1163 , v8::Local<v8::Function> func
1165 , v8::Local<v8::Value>* argv) {
1166 v8::HandleScope scope;
1167 return scope.Close(New(node::MakeCallback(target, func, argc, argv)));
1170 inline v8::Local<v8::Value> MakeCallback(
1171 v8::Local<v8::Object> target
1172 , v8::Local<v8::String> symbol
1174 , v8::Local<v8::Value>* argv) {
1175 v8::HandleScope scope;
1176 return scope.Close(New(node::MakeCallback(target, symbol, argc, argv)));
1179 inline v8::Local<v8::Value> MakeCallback(
1180 v8::Local<v8::Object> target
1181 , const char* method
1183 , v8::Local<v8::Value>* argv) {
1184 v8::HandleScope scope;
1185 return scope.Close(New(node::MakeCallback(target, method, argc, argv)));
1188 inline void FatalException(const TryCatch& try_catch) {
1189 node::FatalException(const_cast<v8::TryCatch &>(try_catch.try_catch_));
1192 inline v8::Local<v8::Value> ErrnoException(
1194 , const char* syscall = NULL
1195 , const char* message = NULL
1196 , const char* path = NULL) {
1197 return node::ErrnoException(errorno, syscall, message, path);
1200 NAN_DEPRECATED inline v8::Local<v8::Value> NanErrnoException(
1202 , const char* syscall = NULL
1203 , const char* message = NULL
1204 , const char* path = NULL) {
1205 return ErrnoException(errorno, syscall, message, path);
1209 template<typename T>
1210 inline void SetIsolateData(
1211 v8::Isolate *isolate
1214 isolate->SetData(data);
1217 template<typename T>
1218 inline T *GetIsolateData(
1219 v8::Isolate *isolate
1221 return static_cast<T*>(isolate->GetData());
1226 inline explicit Utf8String(v8::Local<v8::Value> from) :
1227 length_(0), str_(str_st_) {
1228 v8::HandleScope scope;
1229 if (!from.IsEmpty()) {
1230 v8::Local<v8::String> string = from->ToString();
1231 if (!string.IsEmpty()) {
1232 size_t len = 3 * string->Length() + 1;
1233 assert(len <= INT_MAX);
1234 if (len > sizeof (str_st_)) {
1235 str_ = static_cast<char*>(malloc(len));
1239 v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
1240 length_ = string->WriteUtf8(str_, static_cast<int>(len), 0, flags);
1241 str_[length_] = '\0';
1246 inline int length() const {
1250 inline char* operator*() { return str_; }
1251 inline const char* operator*() const { return str_; }
1253 inline ~Utf8String() {
1254 if (str_ != str_st_) {
1260 NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
1267 #endif // NODE_MODULE_VERSION
1269 typedef void (*FreeCallback)(char *data, void *hint);
1271 typedef const FunctionCallbackInfo<v8::Value>& NAN_METHOD_ARGS_TYPE;
1272 typedef void NAN_METHOD_RETURN_TYPE;
1274 typedef const PropertyCallbackInfo<v8::Value>& NAN_GETTER_ARGS_TYPE;
1275 typedef void NAN_GETTER_RETURN_TYPE;
1277 typedef const PropertyCallbackInfo<void>& NAN_SETTER_ARGS_TYPE;
1278 typedef void NAN_SETTER_RETURN_TYPE;
1280 typedef const PropertyCallbackInfo<v8::Value>&
1281 NAN_PROPERTY_GETTER_ARGS_TYPE;
1282 typedef void NAN_PROPERTY_GETTER_RETURN_TYPE;
1284 typedef const PropertyCallbackInfo<v8::Value>&
1285 NAN_PROPERTY_SETTER_ARGS_TYPE;
1286 typedef void NAN_PROPERTY_SETTER_RETURN_TYPE;
1288 typedef const PropertyCallbackInfo<v8::Array>&
1289 NAN_PROPERTY_ENUMERATOR_ARGS_TYPE;
1290 typedef void NAN_PROPERTY_ENUMERATOR_RETURN_TYPE;
1292 typedef const PropertyCallbackInfo<v8::Boolean>&
1293 NAN_PROPERTY_DELETER_ARGS_TYPE;
1294 typedef void NAN_PROPERTY_DELETER_RETURN_TYPE;
1296 typedef const PropertyCallbackInfo<v8::Integer>&
1297 NAN_PROPERTY_QUERY_ARGS_TYPE;
1298 typedef void NAN_PROPERTY_QUERY_RETURN_TYPE;
1300 typedef const PropertyCallbackInfo<v8::Value>& NAN_INDEX_GETTER_ARGS_TYPE;
1301 typedef void NAN_INDEX_GETTER_RETURN_TYPE;
1303 typedef const PropertyCallbackInfo<v8::Value>& NAN_INDEX_SETTER_ARGS_TYPE;
1304 typedef void NAN_INDEX_SETTER_RETURN_TYPE;
1306 typedef const PropertyCallbackInfo<v8::Array>&
1307 NAN_INDEX_ENUMERATOR_ARGS_TYPE;
1308 typedef void NAN_INDEX_ENUMERATOR_RETURN_TYPE;
1310 typedef const PropertyCallbackInfo<v8::Boolean>&
1311 NAN_INDEX_DELETER_ARGS_TYPE;
1312 typedef void NAN_INDEX_DELETER_RETURN_TYPE;
1314 typedef const PropertyCallbackInfo<v8::Integer>&
1315 NAN_INDEX_QUERY_ARGS_TYPE;
1316 typedef void NAN_INDEX_QUERY_RETURN_TYPE;
1318 #define NAN_METHOD(name) \
1319 Nan::NAN_METHOD_RETURN_TYPE name(Nan::NAN_METHOD_ARGS_TYPE info)
1320 #define NAN_GETTER(name) \
1321 Nan::NAN_GETTER_RETURN_TYPE name( \
1322 v8::Local<v8::String> property \
1323 , Nan::NAN_GETTER_ARGS_TYPE info)
1324 #define NAN_SETTER(name) \
1325 Nan::NAN_SETTER_RETURN_TYPE name( \
1326 v8::Local<v8::String> property \
1327 , v8::Local<v8::Value> value \
1328 , Nan::NAN_SETTER_ARGS_TYPE info)
1329 #define NAN_PROPERTY_GETTER(name) \
1330 Nan::NAN_PROPERTY_GETTER_RETURN_TYPE name( \
1331 v8::Local<v8::String> property \
1332 , Nan::NAN_PROPERTY_GETTER_ARGS_TYPE info)
1333 #define NAN_PROPERTY_SETTER(name) \
1334 Nan::NAN_PROPERTY_SETTER_RETURN_TYPE name( \
1335 v8::Local<v8::String> property \
1336 , v8::Local<v8::Value> value \
1337 , Nan::NAN_PROPERTY_SETTER_ARGS_TYPE info)
1338 #define NAN_PROPERTY_ENUMERATOR(name) \
1339 Nan::NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name( \
1340 Nan::NAN_PROPERTY_ENUMERATOR_ARGS_TYPE info)
1341 #define NAN_PROPERTY_DELETER(name) \
1342 Nan::NAN_PROPERTY_DELETER_RETURN_TYPE name( \
1343 v8::Local<v8::String> property \
1344 , Nan::NAN_PROPERTY_DELETER_ARGS_TYPE info)
1345 #define NAN_PROPERTY_QUERY(name) \
1346 Nan::NAN_PROPERTY_QUERY_RETURN_TYPE name( \
1347 v8::Local<v8::String> property \
1348 , Nan::NAN_PROPERTY_QUERY_ARGS_TYPE info)
1349 # define NAN_INDEX_GETTER(name) \
1350 Nan::NAN_INDEX_GETTER_RETURN_TYPE name( \
1352 , Nan::NAN_INDEX_GETTER_ARGS_TYPE info)
1353 #define NAN_INDEX_SETTER(name) \
1354 Nan::NAN_INDEX_SETTER_RETURN_TYPE name( \
1356 , v8::Local<v8::Value> value \
1357 , Nan::NAN_INDEX_SETTER_ARGS_TYPE info)
1358 #define NAN_INDEX_ENUMERATOR(name) \
1359 Nan::NAN_INDEX_ENUMERATOR_RETURN_TYPE \
1360 name(Nan::NAN_INDEX_ENUMERATOR_ARGS_TYPE info)
1361 #define NAN_INDEX_DELETER(name) \
1362 Nan::NAN_INDEX_DELETER_RETURN_TYPE name( \
1364 , Nan::NAN_INDEX_DELETER_ARGS_TYPE info)
1365 #define NAN_INDEX_QUERY(name) \
1366 Nan::NAN_INDEX_QUERY_RETURN_TYPE name( \
1368 , Nan::NAN_INDEX_QUERY_ARGS_TYPE info)
1374 explicit Callback(const v8::Local<v8::Function> &fn) : handle_(fn) {}
1380 bool operator==(const Callback &other) const {
1381 return handle_ == other.handle_;
1384 bool operator!=(const Callback &other) const {
1385 return !operator==(other);
1389 v8::Local<v8::Function> operator*() const { return GetFunction(); }
1391 inline v8::Local<v8::Value> operator()(
1392 v8::Local<v8::Object> target
1394 , v8::Local<v8::Value> argv[] = 0) const {
1395 return this->Call(target, argc, argv);
1398 inline v8::Local<v8::Value> operator()(
1400 , v8::Local<v8::Value> argv[] = 0) const {
1401 return this->Call(argc, argv);
1404 // TODO(kkoopa): remove
1405 inline void SetFunction(const v8::Local<v8::Function> &fn) {
1409 inline void Reset(const v8::Local<v8::Function> &fn) {
1413 inline void Reset() {
1417 inline v8::Local<v8::Function> GetFunction() const {
1418 return New(handle_);
1421 inline bool IsEmpty() const {
1422 return handle_.IsEmpty();
1425 inline v8::Local<v8::Value>
1426 Call(v8::Local<v8::Object> target
1428 , v8::Local<v8::Value> argv[]) const {
1429 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1430 v8::Isolate *isolate = v8::Isolate::GetCurrent();
1431 return Call_(isolate, target, argc, argv);
1433 return Call_(target, argc, argv);
1437 inline v8::Local<v8::Value>
1438 Call(int argc, v8::Local<v8::Value> argv[]) const {
1439 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1440 v8::Isolate *isolate = v8::Isolate::GetCurrent();
1441 v8::EscapableHandleScope scope(isolate);
1442 return scope.Escape(
1443 Call_(isolate, isolate->GetCurrentContext()->Global(), argc, argv));
1445 v8::HandleScope scope;
1446 return scope.Close(Call_(v8::Context::GetCurrent()->Global(), argc, argv));
1451 NAN_DISALLOW_ASSIGN_COPY_MOVE(Callback)
1452 Persistent<v8::Function> handle_;
1454 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1455 v8::Local<v8::Value> Call_(v8::Isolate *isolate
1456 , v8::Local<v8::Object> target
1458 , v8::Local<v8::Value> argv[]) const {
1459 EscapableHandleScope scope;
1461 v8::Local<v8::Function> callback = New(handle_);
1462 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1463 return scope.Escape(New(node::MakeCallback(
1471 return scope.Escape(node::MakeCallback(
1481 v8::Local<v8::Value> Call_(v8::Local<v8::Object> target
1483 , v8::Local<v8::Value> argv[]) const {
1484 EscapableHandleScope scope;
1486 v8::Local<v8::Function> callback = New(handle_);
1487 return scope.Escape(New(node::MakeCallback(
1497 /* abstract */ class AsyncWorker {
1499 explicit AsyncWorker(Callback *callback_)
1500 : callback(callback_), errmsg_(NULL) {
1501 request.data = this;
1504 v8::Local<v8::Object> obj = New<v8::Object>();
1505 persistentHandle.Reset(obj);
1508 virtual ~AsyncWorker() {
1511 if (!persistentHandle.IsEmpty())
1512 persistentHandle.Reset();
1517 virtual void WorkComplete() {
1520 if (errmsg_ == NULL)
1523 HandleErrorCallback();
1528 inline void SaveToPersistent(
1529 const char *key, const v8::Local<v8::Value> &value) {
1531 New(persistentHandle)->Set(New(key).ToLocalChecked(), value);
1534 inline void SaveToPersistent(
1535 const v8::Local<v8::String> &key, const v8::Local<v8::Value> &value) {
1537 New(persistentHandle)->Set(key, value);
1540 inline void SaveToPersistent(
1541 uint32_t index, const v8::Local<v8::Value> &value) {
1543 New(persistentHandle)->Set(index, value);
1546 inline v8::Local<v8::Value> GetFromPersistent(const char *key) const {
1547 EscapableHandleScope scope;
1548 return scope.Escape(
1549 New(persistentHandle)->Get(New(key).ToLocalChecked()));
1552 inline v8::Local<v8::Value>
1553 GetFromPersistent(const v8::Local<v8::String> &key) const {
1554 EscapableHandleScope scope;
1555 return scope.Escape(New(persistentHandle)->Get(key));
1558 inline v8::Local<v8::Value> GetFromPersistent(uint32_t index) const {
1559 EscapableHandleScope scope;
1560 return scope.Escape(New(persistentHandle)->Get(index));
1563 virtual void Execute() = 0;
1567 virtual void Destroy() {
1572 Persistent<v8::Object> persistentHandle;
1575 virtual void HandleOKCallback() {
1578 callback->Call(0, NULL);
1581 virtual void HandleErrorCallback() {
1584 v8::Local<v8::Value> argv[] = {
1585 v8::Exception::Error(New<v8::String>(ErrorMessage()).ToLocalChecked())
1587 callback->Call(1, argv);
1590 void SetErrorMessage(const char *msg) {
1593 size_t size = strlen(msg) + 1;
1594 errmsg_ = new char[size];
1595 memcpy(errmsg_, msg, size);
1598 const char* ErrorMessage() const {
1603 NAN_DISALLOW_ASSIGN_COPY_MOVE(AsyncWorker)
1609 /* abstract */ class AsyncProgressWorkerBase : public AsyncWorker {
1611 explicit AsyncProgressWorkerBase(Callback *callback_)
1612 : AsyncWorker(callback_), asyncdata_(NULL), asyncsize_(0) {
1613 async = new uv_async_t;
1621 uv_mutex_init(&async_lock);
1624 virtual ~AsyncProgressWorkerBase() {
1625 uv_mutex_destroy(&async_lock);
1627 delete[] asyncdata_;
1630 void WorkProgress() {
1631 uv_mutex_lock(&async_lock);
1632 T *data = asyncdata_;
1633 size_t size = asyncsize_;
1635 uv_mutex_unlock(&async_lock);
1637 // Don't send progress events after we've already completed.
1639 HandleProgressCallback(data, size);
1644 class ExecutionProgress {
1645 friend class AsyncProgressWorkerBase;
1647 void Signal() const {
1648 uv_async_send(that_->async);
1651 void Send(const T* data, size_t size) const {
1652 that_->SendProgress_(data, size);
1656 explicit ExecutionProgress(AsyncProgressWorkerBase *that) : that_(that) {}
1657 NAN_DISALLOW_ASSIGN_COPY_MOVE(ExecutionProgress)
1658 AsyncProgressWorkerBase* const that_;
1661 virtual void Execute(const ExecutionProgress& progress) = 0;
1662 virtual void HandleProgressCallback(const T *data, size_t size) = 0;
1664 virtual void Destroy() {
1665 uv_close(reinterpret_cast<uv_handle_t*>(async), AsyncClose_);
1669 void Execute() /*final override*/ {
1670 ExecutionProgress progress(this);
1674 void SendProgress_(const T *data, size_t size) {
1675 T *new_data = new T[size];
1678 std::copy(data, data + size, it);
1681 uv_mutex_lock(&async_lock);
1682 T *old_data = asyncdata_;
1683 asyncdata_ = new_data;
1685 uv_mutex_unlock(&async_lock);
1688 uv_async_send(async);
1691 inline static NAUV_WORK_CB(AsyncProgress_) {
1692 AsyncProgressWorkerBase *worker =
1693 static_cast<AsyncProgressWorkerBase*>(async->data);
1694 worker->WorkProgress();
1697 inline static void AsyncClose_(uv_handle_t* handle) {
1698 AsyncProgressWorkerBase *worker =
1699 static_cast<AsyncProgressWorkerBase*>(handle->data);
1700 delete reinterpret_cast<uv_async_t*>(handle);
1705 uv_mutex_t async_lock;
1710 // This ensures compatibility to the previous un-templated AsyncProgressWorker
1711 // class definition.
1712 typedef AsyncProgressWorkerBase<char> AsyncProgressWorker;
1714 inline void AsyncExecute (uv_work_t* req) {
1715 AsyncWorker *worker = static_cast<AsyncWorker*>(req->data);
1719 inline void AsyncExecuteComplete (uv_work_t* req) {
1720 AsyncWorker* worker = static_cast<AsyncWorker*>(req->data);
1721 worker->WorkComplete();
1725 inline void AsyncQueueWorker (AsyncWorker* worker) {
1730 , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
1737 ExternalOneByteStringResource const*
1738 GetExternalResource(v8::Local<v8::String> str) {
1739 #if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION
1740 return str->GetExternalAsciiStringResource();
1742 return str->GetExternalOneByteStringResource();
1748 IsExternal(v8::Local<v8::String> str) {
1749 #if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION
1750 return str->IsExternalAscii();
1752 return str->IsExternalOneByte();
1756 } // end of namespace imp
1758 enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
1760 #if NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION
1761 # include "nan_string_bytes.h" // NOLINT(build/include)
1764 inline v8::Local<v8::Value> Encode(
1765 const void *buf, size_t len, enum Encoding encoding = BINARY) {
1766 #if (NODE_MODULE_VERSION >= ATOM_0_21_MODULE_VERSION)
1767 v8::Isolate* isolate = v8::Isolate::GetCurrent();
1768 node::encoding node_enc = static_cast<node::encoding>(encoding);
1770 if (encoding == UCS2) {
1771 return node::Encode(
1773 , reinterpret_cast<const uint16_t *>(buf)
1776 return node::Encode(
1778 , reinterpret_cast<const char *>(buf)
1782 #elif (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1783 return node::Encode(
1784 v8::Isolate::GetCurrent()
1786 , static_cast<node::encoding>(encoding));
1788 # if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
1789 return node::Encode(buf, len, static_cast<node::encoding>(encoding));
1791 return imp::Encode(reinterpret_cast<const char*>(buf), len, encoding);
1796 inline ssize_t DecodeBytes(
1797 v8::Local<v8::Value> val, enum Encoding encoding = BINARY) {
1798 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1799 return node::DecodeBytes(
1800 v8::Isolate::GetCurrent()
1802 , static_cast<node::encoding>(encoding));
1804 # if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)
1805 if (encoding == BUFFER) {
1806 return node::DecodeBytes(val, node::BINARY);
1809 return node::DecodeBytes(val, static_cast<node::encoding>(encoding));
1813 inline ssize_t DecodeWrite(
1816 , v8::Local<v8::Value> val
1817 , enum Encoding encoding = BINARY) {
1818 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1819 return node::DecodeWrite(
1820 v8::Isolate::GetCurrent()
1824 , static_cast<node::encoding>(encoding));
1826 # if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)
1827 if (encoding == BUFFER) {
1828 return node::DecodeWrite(buf, len, val, node::BINARY);
1831 return node::DecodeWrite(
1835 , static_cast<node::encoding>(encoding));
1839 inline void SetPrototypeTemplate(
1840 v8::Local<v8::FunctionTemplate> templ
1842 , v8::Local<v8::Data> value
1845 SetTemplate(templ->PrototypeTemplate(), name, value);
1848 inline void SetPrototypeTemplate(
1849 v8::Local<v8::FunctionTemplate> templ
1850 , v8::Local<v8::String> name
1851 , v8::Local<v8::Data> value
1852 , v8::PropertyAttribute attributes
1855 SetTemplate(templ->PrototypeTemplate(), name, value, attributes);
1858 inline void SetInstanceTemplate(
1859 v8::Local<v8::FunctionTemplate> templ
1861 , v8::Local<v8::Data> value
1864 SetTemplate(templ->InstanceTemplate(), name, value);
1867 inline void SetInstanceTemplate(
1868 v8::Local<v8::FunctionTemplate> templ
1869 , v8::Local<v8::String> name
1870 , v8::Local<v8::Data> value
1871 , v8::PropertyAttribute attributes
1874 SetTemplate(templ->InstanceTemplate(), name, value, attributes);
1879 // Note(@agnat): Helper to distinguish different receiver types. The first
1880 // version deals with receivers derived from v8::Template. The second version
1881 // handles everything else. The final argument only serves as discriminator and
1883 template <typename T>
1886 SetMethodAux(T recv,
1887 v8::Local<v8::String> name,
1888 v8::Local<v8::FunctionTemplate> tpl,
1890 recv->Set(name, tpl);
1893 template <typename T>
1896 SetMethodAux(T recv,
1897 v8::Local<v8::String> name,
1898 v8::Local<v8::FunctionTemplate> tpl,
1900 recv->Set(name, GetFunction(tpl).ToLocalChecked());
1903 } // end of namespace imp
1905 template <typename T, template <typename> class HandleType>
1906 inline void SetMethod(
1909 , FunctionCallback callback) {
1911 v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(callback);
1912 v8::Local<v8::String> fn_name = New(name).ToLocalChecked();
1913 t->SetClassName(fn_name);
1914 // Note(@agnat): Pass an empty T* as discriminator. See note on
1915 // SetMethodAux(...) above
1916 imp::SetMethodAux(recv, fn_name, t, static_cast<T*>(0));
1919 inline void SetPrototypeMethod(
1920 v8::Local<v8::FunctionTemplate> recv
1921 , const char* name, FunctionCallback callback) {
1923 v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(
1925 , v8::Local<v8::Value>()
1926 , New<v8::Signature>(recv));
1927 v8::Local<v8::String> fn_name = New(name).ToLocalChecked();
1928 recv->PrototypeTemplate()->Set(fn_name, t);
1929 t->SetClassName(fn_name);
1932 //=== Accessors and Such =======================================================
1934 inline void SetAccessor(
1935 v8::Local<v8::ObjectTemplate> tpl
1936 , v8::Local<v8::String> name
1937 , GetterCallback getter
1938 , SetterCallback setter = 0
1939 , v8::Local<v8::Value> data = v8::Local<v8::Value>()
1940 , v8::AccessControl settings = v8::DEFAULT
1941 , v8::PropertyAttribute attribute = v8::None
1942 , imp::Sig signature = imp::Sig()) {
1945 imp::NativeGetter getter_ =
1946 imp::GetterCallbackWrapper;
1947 imp::NativeSetter setter_ =
1948 setter ? imp::SetterCallbackWrapper : 0;
1950 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
1951 otpl->SetInternalFieldCount(imp::kAccessorFieldCount);
1952 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
1954 obj->SetInternalField(
1956 , New<v8::External>(reinterpret_cast<void *>(getter)));
1959 obj->SetInternalField(
1961 , New<v8::External>(reinterpret_cast<void *>(setter)));
1964 if (!data.IsEmpty()) {
1965 obj->SetInternalField(imp::kDataIndex, data);
1978 inline bool SetAccessor(
1979 v8::Local<v8::Object> obj
1980 , v8::Local<v8::String> name
1981 , GetterCallback getter
1982 , SetterCallback setter = 0
1983 , v8::Local<v8::Value> data = v8::Local<v8::Value>()
1984 , v8::AccessControl settings = v8::DEFAULT
1985 , v8::PropertyAttribute attribute = v8::None) {
1988 imp::NativeGetter getter_ =
1989 imp::GetterCallbackWrapper;
1990 imp::NativeSetter setter_ =
1991 setter ? imp::SetterCallbackWrapper : 0;
1993 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
1994 otpl->SetInternalFieldCount(imp::kAccessorFieldCount);
1995 v8::Local<v8::Object> dataobj = NewInstance(otpl).ToLocalChecked();
1997 dataobj->SetInternalField(
1999 , New<v8::External>(reinterpret_cast<void *>(getter)));
2001 if (!data.IsEmpty()) {
2002 dataobj->SetInternalField(imp::kDataIndex, data);
2006 dataobj->SetInternalField(
2008 , New<v8::External>(reinterpret_cast<void *>(setter)));
2011 #if (NODE_MODULE_VERSION >= NODE_6_0_MODULE_VERSION)
2012 return obj->SetAccessor(
2019 , attribute).FromMaybe(false);
2021 return obj->SetAccessor(
2031 inline void SetNamedPropertyHandler(
2032 v8::Local<v8::ObjectTemplate> tpl
2033 , PropertyGetterCallback getter
2034 , PropertySetterCallback setter = 0
2035 , PropertyQueryCallback query = 0
2036 , PropertyDeleterCallback deleter = 0
2037 , PropertyEnumeratorCallback enumerator = 0
2038 , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2041 imp::NativePropertyGetter getter_ =
2042 imp::PropertyGetterCallbackWrapper;
2043 imp::NativePropertySetter setter_ =
2044 setter ? imp::PropertySetterCallbackWrapper : 0;
2045 imp::NativePropertyQuery query_ =
2046 query ? imp::PropertyQueryCallbackWrapper : 0;
2047 imp::NativePropertyDeleter *deleter_ =
2048 deleter ? imp::PropertyDeleterCallbackWrapper : 0;
2049 imp::NativePropertyEnumerator enumerator_ =
2050 enumerator ? imp::PropertyEnumeratorCallbackWrapper : 0;
2052 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2053 otpl->SetInternalFieldCount(imp::kPropertyFieldCount);
2054 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2055 obj->SetInternalField(
2056 imp::kPropertyGetterIndex
2057 , New<v8::External>(reinterpret_cast<void *>(getter)));
2060 obj->SetInternalField(
2061 imp::kPropertySetterIndex
2062 , New<v8::External>(reinterpret_cast<void *>(setter)));
2066 obj->SetInternalField(
2067 imp::kPropertyQueryIndex
2068 , New<v8::External>(reinterpret_cast<void *>(query)));
2072 obj->SetInternalField(
2073 imp::kPropertyDeleterIndex
2074 , New<v8::External>(reinterpret_cast<void *>(deleter)));
2078 obj->SetInternalField(
2079 imp::kPropertyEnumeratorIndex
2080 , New<v8::External>(reinterpret_cast<void *>(enumerator)));
2083 if (!data.IsEmpty()) {
2084 obj->SetInternalField(imp::kDataIndex, data);
2087 #if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
2088 tpl->SetHandler(v8::NamedPropertyHandlerConfiguration(
2089 getter_, setter_, query_, deleter_, enumerator_, obj));
2091 tpl->SetNamedPropertyHandler(
2101 inline void SetIndexedPropertyHandler(
2102 v8::Local<v8::ObjectTemplate> tpl
2103 , IndexGetterCallback getter
2104 , IndexSetterCallback setter = 0
2105 , IndexQueryCallback query = 0
2106 , IndexDeleterCallback deleter = 0
2107 , IndexEnumeratorCallback enumerator = 0
2108 , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2111 imp::NativeIndexGetter getter_ =
2112 imp::IndexGetterCallbackWrapper;
2113 imp::NativeIndexSetter setter_ =
2114 setter ? imp::IndexSetterCallbackWrapper : 0;
2115 imp::NativeIndexQuery query_ =
2116 query ? imp::IndexQueryCallbackWrapper : 0;
2117 imp::NativeIndexDeleter deleter_ =
2118 deleter ? imp::IndexDeleterCallbackWrapper : 0;
2119 imp::NativeIndexEnumerator enumerator_ =
2120 enumerator ? imp::IndexEnumeratorCallbackWrapper : 0;
2122 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2123 otpl->SetInternalFieldCount(imp::kIndexPropertyFieldCount);
2124 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2125 obj->SetInternalField(
2126 imp::kIndexPropertyGetterIndex
2127 , New<v8::External>(reinterpret_cast<void *>(getter)));
2130 obj->SetInternalField(
2131 imp::kIndexPropertySetterIndex
2132 , New<v8::External>(reinterpret_cast<void *>(setter)));
2136 obj->SetInternalField(
2137 imp::kIndexPropertyQueryIndex
2138 , New<v8::External>(reinterpret_cast<void *>(query)));
2142 obj->SetInternalField(
2143 imp::kIndexPropertyDeleterIndex
2144 , New<v8::External>(reinterpret_cast<void *>(deleter)));
2148 obj->SetInternalField(
2149 imp::kIndexPropertyEnumeratorIndex
2150 , New<v8::External>(reinterpret_cast<void *>(enumerator)));
2153 if (!data.IsEmpty()) {
2154 obj->SetInternalField(imp::kDataIndex, data);
2157 #if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
2158 tpl->SetHandler(v8::IndexedPropertyHandlerConfiguration(
2159 getter_, setter_, query_, deleter_, enumerator_, obj));
2161 tpl->SetIndexedPropertyHandler(
2171 inline void SetCallHandler(
2172 v8::Local<v8::FunctionTemplate> tpl
2173 , FunctionCallback callback
2174 , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2177 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2178 otpl->SetInternalFieldCount(imp::kFunctionFieldCount);
2179 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2181 obj->SetInternalField(
2183 , New<v8::External>(reinterpret_cast<void *>(callback)));
2185 if (!data.IsEmpty()) {
2186 obj->SetInternalField(imp::kDataIndex, data);
2189 tpl->SetCallHandler(imp::FunctionCallbackWrapper, obj);
2193 inline void SetCallAsFunctionHandler(
2194 v8::Local<v8::ObjectTemplate> tpl,
2195 FunctionCallback callback,
2196 v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
2199 v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
2200 otpl->SetInternalFieldCount(imp::kFunctionFieldCount);
2201 v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
2203 obj->SetInternalField(
2205 , New<v8::External>(reinterpret_cast<void *>(callback)));
2207 if (!data.IsEmpty()) {
2208 obj->SetInternalField(imp::kDataIndex, data);
2211 tpl->SetCallAsFunctionHandler(imp::FunctionCallbackWrapper, obj);
2214 //=== Weak Persistent Handling =================================================
2216 #include "nan_weak.h" // NOLINT(build/include)
2218 //=== ObjectWrap ===============================================================
2220 #include "nan_object_wrap.h" // NOLINT(build/include)
2222 //=== HiddenValue/Private ======================================================
2224 #include "nan_private.h" // NOLINT(build/include)
2226 //=== Export ==================================================================
2230 Export(ADDON_REGISTER_FUNCTION_ARGS_TYPE target, const char *name,
2231 FunctionCallback f) {
2234 Set(target, New<v8::String>(name).ToLocalChecked(),
2235 GetFunction(New<v8::FunctionTemplate>(f)).ToLocalChecked());
2238 //=== Tap Reverse Binding =====================================================
2241 explicit Tap(v8::Local<v8::Value> t) : t_() {
2244 t_.Reset(To<v8::Object>(t).ToLocalChecked());
2247 ~Tap() { t_.Reset(); } // not sure if neccessary
2249 inline void plan(int i) {
2251 v8::Local<v8::Value> arg = New(i);
2252 MakeCallback(New(t_), "plan", 1, &arg);
2255 inline void ok(bool isOk, const char *msg = NULL) {
2257 v8::Local<v8::Value> args[2];
2258 args[0] = New(isOk);
2259 if (msg) args[1] = New(msg).ToLocalChecked();
2260 MakeCallback(New(t_), "ok", msg ? 2 : 1, args);
2263 inline void pass(const char * msg = NULL) {
2265 v8::Local<v8::Value> hmsg;
2266 if (msg) hmsg = New(msg).ToLocalChecked();
2267 MakeCallback(New(t_), "pass", msg ? 1 : 0, &hmsg);
2271 Persistent<v8::Object> t_;
2274 #define NAN_STRINGIZE2(x) #x
2275 #define NAN_STRINGIZE(x) NAN_STRINGIZE2(x)
2276 #define NAN_TEST_EXPRESSION(expression) \
2277 ( expression ), __FILE__ ":" NAN_STRINGIZE(__LINE__) ": " #expression
2279 #define NAN_EXPORT(target, function) Export(target, #function, function)
2283 //=== Generic Maybefication ===================================================
2287 template <typename T> struct Maybefier;
2289 template <typename T> struct Maybefier<v8::Local<T> > {
2290 inline static MaybeLocal<T> convert(v8::Local<T> v) {
2295 template <typename T> struct Maybefier<MaybeLocal<T> > {
2296 inline static MaybeLocal<T> convert(MaybeLocal<T> v) {
2301 } // end of namespace imp
2303 template <typename T, template <typename> class MaybeMaybe>
2304 inline MaybeLocal<T>
2305 MakeMaybe(MaybeMaybe<T> v) {
2306 return imp::Maybefier<MaybeMaybe<T> >::convert(v);
2309 //=== TypedArrayContents =======================================================
2311 #include "nan_typedarray_contents.h" // NOLINT(build/include)
2313 } // end of namespace Nan