nan.h
Go to the documentation of this file.
00001 /*********************************************************************
00002  * NAN - Native Abstractions for Node.js
00003  *
00004  * Copyright (c) 2016 NAN contributors:
00005  *   - Rod Vagg <https://github.com/rvagg>
00006  *   - Benjamin Byholm <https://github.com/kkoopa>
00007  *   - Trevor Norris <https://github.com/trevnorris>
00008  *   - Nathan Rajlich <https://github.com/TooTallNate>
00009  *   - Brett Lawson <https://github.com/brett19>
00010  *   - Ben Noordhuis <https://github.com/bnoordhuis>
00011  *   - David Siegel <https://github.com/agnat>
00012  *
00013  * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
00014  *
00015  * Version 2.4.0: current Node 6.3.0, Node 12: 0.12.15, Node 10: 0.10.46, iojs: 3.3.1
00016  *
00017  * See https://github.com/nodejs/nan for the latest update to this file
00018  **********************************************************************************/
00019 
00020 #ifndef NAN_H_
00021 #define NAN_H_
00022 
00023 #include <node_version.h>
00024 
00025 #define NODE_0_10_MODULE_VERSION 11
00026 #define NODE_0_12_MODULE_VERSION 14
00027 #define ATOM_0_21_MODULE_VERSION 41
00028 #define IOJS_1_0_MODULE_VERSION  42
00029 #define IOJS_1_1_MODULE_VERSION  43
00030 #define IOJS_2_0_MODULE_VERSION  44
00031 #define IOJS_3_0_MODULE_VERSION  45
00032 #define NODE_4_0_MODULE_VERSION  46
00033 #define NODE_5_0_MODULE_VERSION  47
00034 #define NODE_6_0_MODULE_VERSION  48
00035 
00036 #ifdef _MSC_VER
00037 # define NAN_HAS_CPLUSPLUS_11 (_MSC_VER >= 1800)
00038 #else
00039 # define NAN_HAS_CPLUSPLUS_11 (__cplusplus >= 201103L)
00040 #endif
00041 
00042 #if NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION && !NAN_HAS_CPLUSPLUS_11
00043 # error This version of node/NAN/v8 requires a C++11 compiler
00044 #endif
00045 
00046 #include <uv.h>
00047 #include <node.h>
00048 #include <node_buffer.h>
00049 #include <node_object_wrap.h>
00050 #include <algorithm>
00051 #include <cstring>
00052 #include <climits>
00053 #include <cstdlib>
00054 #if defined(_MSC_VER)
00055 # pragma warning( push )
00056 # pragma warning( disable : 4530 )
00057 # include <string>
00058 # include <vector>
00059 # pragma warning( pop )
00060 #else
00061 # include <string>
00062 # include <vector>
00063 #endif
00064 
00065 // uv helpers
00066 #ifdef UV_VERSION_MAJOR
00067 # ifndef UV_VERSION_PATCH
00068 #  define UV_VERSION_PATCH 0
00069 # endif
00070 # define NAUV_UVVERSION ((UV_VERSION_MAJOR << 16) | \
00071                          (UV_VERSION_MINOR <<  8) | \
00072                          (UV_VERSION_PATCH))
00073 #else
00074 # define NAUV_UVVERSION 0x000b00
00075 #endif
00076 
00077 #if NAUV_UVVERSION < 0x000b0b
00078 # ifdef WIN32
00079 #  include <windows.h>
00080 # else
00081 #  include <pthread.h>
00082 # endif
00083 #endif
00084 
00085 namespace Nan {
00086 
00087 #define NAN_INLINE inline  // TODO(bnoordhuis) Remove in v3.0.0.
00088 
00089 #if defined(__GNUC__) && \
00090     !(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
00091 # define NAN_DEPRECATED __attribute__((deprecated))
00092 #elif defined(_MSC_VER) && \
00093     !(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
00094 # define NAN_DEPRECATED __declspec(deprecated)
00095 #else
00096 # define NAN_DEPRECATED
00097 #endif
00098 
00099 #if NAN_HAS_CPLUSPLUS_11
00100 # define NAN_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete;
00101 # define NAN_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete;
00102 # define NAN_DISALLOW_MOVE(CLASS)                                              \
00103     CLASS(CLASS&&) = delete;  /* NOLINT(build/c++11) */                        \
00104     void operator=(CLASS&&) = delete;
00105 #else
00106 # define NAN_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&);
00107 # define NAN_DISALLOW_COPY(CLASS) CLASS(const CLASS&);
00108 # define NAN_DISALLOW_MOVE(CLASS)
00109 #endif
00110 
00111 #define NAN_DISALLOW_ASSIGN_COPY(CLASS)                                        \
00112     NAN_DISALLOW_ASSIGN(CLASS)                                                 \
00113     NAN_DISALLOW_COPY(CLASS)
00114 
00115 #define NAN_DISALLOW_ASSIGN_MOVE(CLASS)                                        \
00116     NAN_DISALLOW_ASSIGN(CLASS)                                                 \
00117     NAN_DISALLOW_MOVE(CLASS)
00118 
00119 #define NAN_DISALLOW_COPY_MOVE(CLASS)                                          \
00120     NAN_DISALLOW_COPY(CLASS)                                                   \
00121     NAN_DISALLOW_MOVE(CLASS)
00122 
00123 #define NAN_DISALLOW_ASSIGN_COPY_MOVE(CLASS)                                   \
00124     NAN_DISALLOW_ASSIGN(CLASS)                                                 \
00125     NAN_DISALLOW_COPY(CLASS)                                                   \
00126     NAN_DISALLOW_MOVE(CLASS)
00127 
00128 #define TYPE_CHECK(T, S)                                                       \
00129     while (false) {                                                            \
00130       *(static_cast<T *volatile *>(0)) = static_cast<S*>(0);                   \
00131     }
00132 
00133 //=== RegistrationFunction =====================================================
00134 
00135 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00136   typedef v8::Handle<v8::Object> ADDON_REGISTER_FUNCTION_ARGS_TYPE;
00137 #else
00138   typedef v8::Local<v8::Object> ADDON_REGISTER_FUNCTION_ARGS_TYPE;
00139 #endif
00140 
00141 #define NAN_MODULE_INIT(name)                                                  \
00142     void name(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target)
00143 
00144 //=== CallbackInfo =============================================================
00145 
00146 #include "nan_callbacks.h"  // NOLINT(build/include)
00147 
00148 //==============================================================================
00149 
00150 #if (NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION)
00151 typedef v8::Script             UnboundScript;
00152 typedef v8::Script             BoundScript;
00153 #else
00154 typedef v8::UnboundScript      UnboundScript;
00155 typedef v8::Script             BoundScript;
00156 #endif
00157 
00158 #if (NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION)
00159 typedef v8::String::ExternalAsciiStringResource
00160     ExternalOneByteStringResource;
00161 #else
00162 typedef v8::String::ExternalOneByteStringResource
00163     ExternalOneByteStringResource;
00164 #endif
00165 
00166 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
00167 template<typename T>
00168 class NonCopyablePersistentTraits :
00169     public v8::NonCopyablePersistentTraits<T> {};
00170 template<typename T>
00171 class CopyablePersistentTraits :
00172     public v8::CopyablePersistentTraits<T> {};
00173 
00174 template<typename T>
00175 class PersistentBase :
00176     public v8::PersistentBase<T> {};
00177 
00178 template<typename T, typename M = v8::NonCopyablePersistentTraits<T> >
00179 class Persistent;
00180 #else
00181 template<typename T> class NonCopyablePersistentTraits;
00182 template<typename T> class PersistentBase;
00183 template<typename T, typename P> class WeakCallbackData;
00184 template<typename T, typename M = NonCopyablePersistentTraits<T> >
00185 class Persistent;
00186 #endif  // NODE_MODULE_VERSION
00187 
00188 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
00189   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00190 # include "nan_maybe_43_inl.h"  // NOLINT(build/include)
00191 #else
00192 # include "nan_maybe_pre_43_inl.h"  // NOLINT(build/include)
00193 #endif
00194 
00195 #include "nan_converters.h"  // NOLINT(build/include)
00196 #include "nan_new.h"  // NOLINT(build/include)
00197 
00198 #if NAUV_UVVERSION < 0x000b17
00199 #define NAUV_WORK_CB(func) \
00200     void func(uv_async_t *async, int)
00201 #else
00202 #define NAUV_WORK_CB(func) \
00203     void func(uv_async_t *async)
00204 #endif
00205 
00206 #if NAUV_UVVERSION >= 0x000b0b
00207 
00208 typedef uv_key_t nauv_key_t;
00209 
00210 inline int nauv_key_create(nauv_key_t *key) {
00211   return uv_key_create(key);
00212 }
00213 
00214 inline void nauv_key_delete(nauv_key_t *key) {
00215   uv_key_delete(key);
00216 }
00217 
00218 inline void* nauv_key_get(nauv_key_t *key) {
00219   return uv_key_get(key);
00220 }
00221 
00222 inline void nauv_key_set(nauv_key_t *key, void *value) {
00223   uv_key_set(key, value);
00224 }
00225 
00226 #else
00227 
00228 /* Implement thread local storage for older versions of libuv.
00229  * This is essentially a backport of libuv commit 5d2434bf
00230  * written by Ben Noordhuis, adjusted for names and inline.
00231  */
00232 
00233 #ifndef WIN32
00234 
00235 typedef pthread_key_t nauv_key_t;
00236 
00237 inline int nauv_key_create(nauv_key_t* key) {
00238   return -pthread_key_create(key, NULL);
00239 }
00240 
00241 inline void nauv_key_delete(nauv_key_t* key) {
00242   if (pthread_key_delete(*key))
00243     abort();
00244 }
00245 
00246 inline void* nauv_key_get(nauv_key_t* key) {
00247   return pthread_getspecific(*key);
00248 }
00249 
00250 inline void nauv_key_set(nauv_key_t* key, void* value) {
00251   if (pthread_setspecific(*key, value))
00252     abort();
00253 }
00254 
00255 #else
00256 
00257 typedef struct {
00258   DWORD tls_index;
00259 } nauv_key_t;
00260 
00261 inline int nauv_key_create(nauv_key_t* key) {
00262   key->tls_index = TlsAlloc();
00263   if (key->tls_index == TLS_OUT_OF_INDEXES)
00264     return UV_ENOMEM;
00265   return 0;
00266 }
00267 
00268 inline void nauv_key_delete(nauv_key_t* key) {
00269   if (TlsFree(key->tls_index) == FALSE)
00270     abort();
00271   key->tls_index = TLS_OUT_OF_INDEXES;
00272 }
00273 
00274 inline void* nauv_key_get(nauv_key_t* key) {
00275   void* value = TlsGetValue(key->tls_index);
00276   if (value == NULL)
00277     if (GetLastError() != ERROR_SUCCESS)
00278       abort();
00279   return value;
00280 }
00281 
00282 inline void nauv_key_set(nauv_key_t* key, void* value) {
00283   if (TlsSetValue(key->tls_index, value) == FALSE)
00284     abort();
00285 }
00286 
00287 #endif
00288 #endif
00289 
00290 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00291 template<typename T>
00292 v8::Local<T> New(v8::Handle<T>);
00293 #endif
00294 
00295 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
00296   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00297   typedef v8::WeakCallbackType WeakCallbackType;
00298 #else
00299 struct WeakCallbackType {
00300   enum E {kParameter, kInternalFields};
00301   E type;
00302   WeakCallbackType(E other) : type(other) {}  // NOLINT(runtime/explicit)
00303   inline bool operator==(E other) { return other == this->type; }
00304   inline bool operator!=(E other) { return !operator==(other); }
00305 };
00306 #endif
00307 
00308 template<typename P> class WeakCallbackInfo;
00309 
00310 #if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
00311 # include "nan_persistent_12_inl.h"  // NOLINT(build/include)
00312 #else
00313 # include "nan_persistent_pre_12_inl.h"  // NOLINT(build/include)
00314 #endif
00315 
00316 namespace imp {
00317   static const size_t kMaxLength = 0x3fffffff;
00318   // v8::String::REPLACE_INVALID_UTF8 was introduced
00319   // in node.js v0.10.29 and v0.8.27.
00320 #if NODE_MAJOR_VERSION > 0 || \
00321     NODE_MINOR_VERSION > 10 || \
00322     NODE_MINOR_VERSION == 10 && NODE_PATCH_VERSION >= 29 || \
00323     NODE_MINOR_VERSION == 8 && NODE_PATCH_VERSION >= 27
00324   static const unsigned kReplaceInvalidUtf8 = v8::String::REPLACE_INVALID_UTF8;
00325 #else
00326   static const unsigned kReplaceInvalidUtf8 = 0;
00327 #endif
00328 }  // end of namespace imp
00329 
00330 //=== HandleScope ==============================================================
00331 
00332 class HandleScope {
00333   v8::HandleScope scope;
00334 
00335  public:
00336 #if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
00337   inline HandleScope() : scope(v8::Isolate::GetCurrent()) {}
00338   inline static int NumberOfHandles() {
00339     return v8::HandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
00340   }
00341 #else
00342   inline HandleScope() : scope() {}
00343   inline static int NumberOfHandles() {
00344     return v8::HandleScope::NumberOfHandles();
00345   }
00346 #endif
00347 
00348  private:
00349   // Make it hard to create heap-allocated or illegal handle scopes by
00350   // disallowing certain operations.
00351   HandleScope(const HandleScope &);
00352   void operator=(const HandleScope &);
00353   void *operator new(size_t size);
00354   void operator delete(void *, size_t);
00355 };
00356 
00357 class EscapableHandleScope {
00358  public:
00359 #if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
00360   inline EscapableHandleScope() : scope(v8::Isolate::GetCurrent()) {}
00361 
00362   inline static int NumberOfHandles() {
00363     return v8::EscapableHandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
00364   }
00365 
00366   template<typename T>
00367   inline v8::Local<T> Escape(v8::Local<T> value) {
00368     return scope.Escape(value);
00369   }
00370 
00371  private:
00372   v8::EscapableHandleScope scope;
00373 #else
00374   inline EscapableHandleScope() : scope() {}
00375 
00376   inline static int NumberOfHandles() {
00377     return v8::HandleScope::NumberOfHandles();
00378   }
00379 
00380   template<typename T>
00381   inline v8::Local<T> Escape(v8::Local<T> value) {
00382     return scope.Close(value);
00383   }
00384 
00385  private:
00386   v8::HandleScope scope;
00387 #endif
00388 
00389  private:
00390   // Make it hard to create heap-allocated or illegal handle scopes by
00391   // disallowing certain operations.
00392   EscapableHandleScope(const EscapableHandleScope &);
00393   void operator=(const EscapableHandleScope &);
00394   void *operator new(size_t size);
00395   void operator delete(void *, size_t);
00396 };
00397 
00398 //=== TryCatch =================================================================
00399 
00400 class TryCatch {
00401   v8::TryCatch try_catch_;
00402   friend void FatalException(const TryCatch&);
00403 
00404  public:
00405 #if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
00406   TryCatch() : try_catch_(v8::Isolate::GetCurrent()) {}
00407 #endif
00408 
00409   inline bool HasCaught() const { return try_catch_.HasCaught(); }
00410 
00411   inline bool CanContinue() const { return try_catch_.CanContinue(); }
00412 
00413   inline v8::Local<v8::Value> ReThrow() {
00414 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00415     return New(try_catch_.ReThrow());
00416 #else
00417     return try_catch_.ReThrow();
00418 #endif
00419   }
00420 
00421   inline v8::Local<v8::Value> Exception() const {
00422     return try_catch_.Exception();
00423   }
00424 
00425 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
00426   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00427   inline v8::MaybeLocal<v8::Value> StackTrace() const {
00428     return try_catch_.StackTrace(GetCurrentContext());
00429   }
00430 #else
00431   inline MaybeLocal<v8::Value> StackTrace() const {
00432     return MaybeLocal<v8::Value>(try_catch_.StackTrace());
00433   }
00434 #endif
00435 
00436   inline v8::Local<v8::Message> Message() const {
00437     return try_catch_.Message();
00438   }
00439 
00440   inline void Reset() { try_catch_.Reset(); }
00441 
00442   inline void SetVerbose(bool value) { try_catch_.SetVerbose(value); }
00443 
00444   inline void SetCaptureMessage(bool value) {
00445     try_catch_.SetCaptureMessage(value);
00446   }
00447 };
00448 
00449 //============ =================================================================
00450 
00451 /* node 0.12  */
00452 #if NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION
00453   inline
00454   void SetCounterFunction(v8::CounterLookupCallback cb) {
00455     v8::Isolate::GetCurrent()->SetCounterFunction(cb);
00456   }
00457 
00458   inline
00459   void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
00460     v8::Isolate::GetCurrent()->SetCreateHistogramFunction(cb);
00461   }
00462 
00463   inline
00464   void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
00465     v8::Isolate::GetCurrent()->SetAddHistogramSampleFunction(cb);
00466   }
00467 
00468 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
00469   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00470   inline bool IdleNotification(int idle_time_in_ms) {
00471     return v8::Isolate::GetCurrent()->IdleNotificationDeadline(
00472         idle_time_in_ms * 0.001);
00473   }
00474 # else
00475   inline bool IdleNotification(int idle_time_in_ms) {
00476     return v8::Isolate::GetCurrent()->IdleNotification(idle_time_in_ms);
00477   }
00478 #endif
00479 
00480   inline void LowMemoryNotification() {
00481     v8::Isolate::GetCurrent()->LowMemoryNotification();
00482   }
00483 
00484   inline void ContextDisposedNotification() {
00485     v8::Isolate::GetCurrent()->ContextDisposedNotification();
00486   }
00487 #else
00488   inline
00489   void SetCounterFunction(v8::CounterLookupCallback cb) {
00490     v8::V8::SetCounterFunction(cb);
00491   }
00492 
00493   inline
00494   void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
00495     v8::V8::SetCreateHistogramFunction(cb);
00496   }
00497 
00498   inline
00499   void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
00500     v8::V8::SetAddHistogramSampleFunction(cb);
00501   }
00502 
00503   inline bool IdleNotification(int idle_time_in_ms) {
00504     return v8::V8::IdleNotification(idle_time_in_ms);
00505   }
00506 
00507   inline void LowMemoryNotification() {
00508     v8::V8::LowMemoryNotification();
00509   }
00510 
00511   inline void ContextDisposedNotification() {
00512     v8::V8::ContextDisposedNotification();
00513   }
00514 #endif
00515 
00516 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)  // Node 0.12
00517   inline v8::Local<v8::Primitive> Undefined() {
00518 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00519     EscapableHandleScope scope;
00520     return scope.Escape(New(v8::Undefined(v8::Isolate::GetCurrent())));
00521 # else
00522     return v8::Undefined(v8::Isolate::GetCurrent());
00523 # endif
00524   }
00525 
00526   inline v8::Local<v8::Primitive> Null() {
00527 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00528     EscapableHandleScope scope;
00529     return scope.Escape(New(v8::Null(v8::Isolate::GetCurrent())));
00530 # else
00531     return v8::Null(v8::Isolate::GetCurrent());
00532 # endif
00533   }
00534 
00535   inline v8::Local<v8::Boolean> True() {
00536 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00537     EscapableHandleScope scope;
00538     return scope.Escape(New(v8::True(v8::Isolate::GetCurrent())));
00539 # else
00540     return v8::True(v8::Isolate::GetCurrent());
00541 # endif
00542   }
00543 
00544   inline v8::Local<v8::Boolean> False() {
00545 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00546     EscapableHandleScope scope;
00547     return scope.Escape(New(v8::False(v8::Isolate::GetCurrent())));
00548 # else
00549     return v8::False(v8::Isolate::GetCurrent());
00550 # endif
00551   }
00552 
00553   inline v8::Local<v8::String> EmptyString() {
00554     return v8::String::Empty(v8::Isolate::GetCurrent());
00555   }
00556 
00557   inline int AdjustExternalMemory(int bc) {
00558     return static_cast<int>(
00559         v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
00560   }
00561 
00562   inline void SetTemplate(
00563       v8::Local<v8::Template> templ
00564     , const char *name
00565     , v8::Local<v8::Data> value) {
00566     templ->Set(v8::Isolate::GetCurrent(), name, value);
00567   }
00568 
00569   inline void SetTemplate(
00570       v8::Local<v8::Template> templ
00571     , v8::Local<v8::String> name
00572     , v8::Local<v8::Data> value
00573     , v8::PropertyAttribute attributes) {
00574     templ->Set(name, value, attributes);
00575   }
00576 
00577   inline v8::Local<v8::Context> GetCurrentContext() {
00578     return v8::Isolate::GetCurrent()->GetCurrentContext();
00579   }
00580 
00581   inline void* GetInternalFieldPointer(
00582       v8::Local<v8::Object> object
00583     , int index) {
00584     return object->GetAlignedPointerFromInternalField(index);
00585   }
00586 
00587   inline void SetInternalFieldPointer(
00588       v8::Local<v8::Object> object
00589     , int index
00590     , void* value) {
00591     object->SetAlignedPointerInInternalField(index, value);
00592   }
00593 
00594 # define NAN_GC_CALLBACK(name)                                                 \
00595     void name(v8::Isolate *isolate, v8::GCType type, v8::GCCallbackFlags flags)
00596 
00597 #if NODE_MODULE_VERSION <= NODE_4_0_MODULE_VERSION
00598   typedef v8::Isolate::GCEpilogueCallback GCEpilogueCallback;
00599   typedef v8::Isolate::GCPrologueCallback GCPrologueCallback;
00600 #else
00601   typedef v8::Isolate::GCCallback GCEpilogueCallback;
00602   typedef v8::Isolate::GCCallback GCPrologueCallback;
00603 #endif
00604 
00605   inline void AddGCEpilogueCallback(
00606       GCEpilogueCallback callback
00607     , v8::GCType gc_type_filter = v8::kGCTypeAll) {
00608     v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);
00609   }
00610 
00611   inline void RemoveGCEpilogueCallback(
00612       GCEpilogueCallback callback) {
00613     v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);
00614   }
00615 
00616   inline void AddGCPrologueCallback(
00617       GCPrologueCallback callback
00618     , v8::GCType gc_type_filter = v8::kGCTypeAll) {
00619     v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);
00620   }
00621 
00622   inline void RemoveGCPrologueCallback(
00623       GCPrologueCallback callback) {
00624     v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);
00625   }
00626 
00627   inline void GetHeapStatistics(
00628       v8::HeapStatistics *heap_statistics) {
00629     v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);
00630   }
00631 
00632 # define X(NAME)                                                               \
00633     inline v8::Local<v8::Value> NAME(const char *msg) {                    \
00634       EscapableHandleScope scope;                                              \
00635       return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked()));     \
00636     }                                                                          \
00637                                                                                \
00638     inline                                                                 \
00639     v8::Local<v8::Value> NAME(v8::Local<v8::String> msg) {                     \
00640       return v8::Exception::NAME(msg);                                         \
00641     }                                                                          \
00642                                                                                \
00643     inline void Throw ## NAME(const char *msg) {                           \
00644       HandleScope scope;                                                       \
00645       v8::Isolate::GetCurrent()->ThrowException(                               \
00646           v8::Exception::NAME(New(msg).ToLocalChecked()));                     \
00647     }                                                                          \
00648                                                                                \
00649     inline void Throw ## NAME(v8::Local<v8::String> msg) {                 \
00650       HandleScope scope;                                                       \
00651       v8::Isolate::GetCurrent()->ThrowException(                               \
00652           v8::Exception::NAME(msg));                                           \
00653     }
00654 
00655   X(Error)
00656   X(RangeError)
00657   X(ReferenceError)
00658   X(SyntaxError)
00659   X(TypeError)
00660 
00661 # undef X
00662 
00663   inline void ThrowError(v8::Local<v8::Value> error) {
00664     v8::Isolate::GetCurrent()->ThrowException(error);
00665   }
00666 
00667   inline MaybeLocal<v8::Object> NewBuffer(
00668       char *data
00669     , size_t length
00670 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
00671     , node::Buffer::FreeCallback callback
00672 #else
00673     , node::smalloc::FreeCallback callback
00674 #endif
00675     , void *hint
00676   ) {
00677     // arbitrary buffer lengths requires
00678     // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
00679     assert(length <= imp::kMaxLength && "too large buffer");
00680 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
00681     return node::Buffer::New(
00682         v8::Isolate::GetCurrent(), data, length, callback, hint);
00683 #else
00684     return MaybeLocal<v8::Object>(node::Buffer::New(
00685         v8::Isolate::GetCurrent(), data, length, callback, hint));
00686 #endif
00687   }
00688 
00689   inline MaybeLocal<v8::Object> CopyBuffer(
00690       const char *data
00691     , uint32_t size
00692   ) {
00693     // arbitrary buffer lengths requires
00694     // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
00695     assert(size <= imp::kMaxLength && "too large buffer");
00696 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
00697     return node::Buffer::Copy(
00698         v8::Isolate::GetCurrent(), data, size);
00699 #else
00700     return MaybeLocal<v8::Object>(node::Buffer::New(
00701         v8::Isolate::GetCurrent(), data, size));
00702 #endif
00703   }
00704 
00705   inline MaybeLocal<v8::Object> NewBuffer(uint32_t size) {
00706     // arbitrary buffer lengths requires
00707     // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
00708     assert(size <= imp::kMaxLength && "too large buffer");
00709 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
00710     return node::Buffer::New(
00711         v8::Isolate::GetCurrent(), size);
00712 #else
00713     return MaybeLocal<v8::Object>(node::Buffer::New(
00714         v8::Isolate::GetCurrent(), size));
00715 #endif
00716   }
00717 
00718   inline MaybeLocal<v8::Object> NewBuffer(
00719       char* data
00720     , uint32_t size
00721   ) {
00722     // arbitrary buffer lengths requires
00723     // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
00724     assert(size <= imp::kMaxLength && "too large buffer");
00725 #if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
00726     return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
00727 #else
00728     return MaybeLocal<v8::Object>(
00729         node::Buffer::Use(v8::Isolate::GetCurrent(), data, size));
00730 #endif
00731   }
00732 
00733 #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
00734   (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
00735   inline MaybeLocal<v8::String>
00736   NewOneByteString(const uint8_t * value, int length = -1) {
00737     return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), value,
00738           v8::NewStringType::kNormal, length);
00739   }
00740 
00741   inline MaybeLocal<BoundScript> CompileScript(
00742       v8::Local<v8::String> s
00743     , const v8::ScriptOrigin& origin
00744   ) {
00745     v8::ScriptCompiler::Source source(s, origin);
00746     return v8::ScriptCompiler::Compile(GetCurrentContext(), &source);
00747   }
00748 
00749   inline MaybeLocal<BoundScript> CompileScript(
00750       v8::Local<v8::String> s
00751   ) {
00752     v8::ScriptCompiler::Source source(s);
00753     return v8::ScriptCompiler::Compile(GetCurrentContext(), &source);
00754   }
00755 
00756   inline MaybeLocal<v8::Value> RunScript(
00757       v8::Local<UnboundScript> script
00758   ) {
00759     return script->BindToCurrentContext()->Run(GetCurrentContext());
00760   }
00761 
00762   inline MaybeLocal<v8::Value> RunScript(
00763       v8::Local<BoundScript> script
00764   ) {
00765     return script->Run(GetCurrentContext());
00766   }
00767 #else
00768   inline MaybeLocal<v8::String>
00769   NewOneByteString(const uint8_t * value, int length = -1) {
00770     return MaybeLocal<v8::String>(
00771         v8::String::NewFromOneByte(
00772             v8::Isolate::GetCurrent()
00773           , value
00774           , v8::String::kNormalString, length));
00775   }
00776 
00777   inline MaybeLocal<BoundScript> CompileScript(
00778       v8::Local<v8::String> s
00779     , const v8::ScriptOrigin& origin
00780   ) {
00781     v8::ScriptCompiler::Source source(s, origin);
00782     return MaybeLocal<BoundScript>(
00783         v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source));
00784   }
00785 
00786   inline MaybeLocal<BoundScript> CompileScript(
00787       v8::Local<v8::String> s
00788   ) {
00789     v8::ScriptCompiler::Source source(s);
00790     return MaybeLocal<BoundScript>(
00791         v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source));
00792   }
00793 
00794   inline MaybeLocal<v8::Value> RunScript(
00795       v8::Local<UnboundScript> script
00796   ) {
00797     return MaybeLocal<v8::Value>(script->BindToCurrentContext()->Run());
00798   }
00799 
00800   inline MaybeLocal<v8::Value> RunScript(
00801       v8::Local<BoundScript> script
00802   ) {
00803     return MaybeLocal<v8::Value>(script->Run());
00804   }
00805 #endif
00806 
00807   inline v8::Local<v8::Value> MakeCallback(
00808       v8::Local<v8::Object> target
00809     , v8::Local<v8::Function> func
00810     , int argc
00811     , v8::Local<v8::Value>* argv) {
00812 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00813     return New(node::MakeCallback(
00814         v8::Isolate::GetCurrent(), target, func, argc, argv));
00815 #else
00816     return node::MakeCallback(
00817         v8::Isolate::GetCurrent(), target, func, argc, argv);
00818 #endif
00819   }
00820 
00821   inline v8::Local<v8::Value> MakeCallback(
00822       v8::Local<v8::Object> target
00823     , v8::Local<v8::String> symbol
00824     , int argc
00825     , v8::Local<v8::Value>* argv) {
00826 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00827     return New(node::MakeCallback(
00828         v8::Isolate::GetCurrent(), target, symbol, argc, argv));
00829 #else
00830     return node::MakeCallback(
00831         v8::Isolate::GetCurrent(), target, symbol, argc, argv);
00832 #endif
00833   }
00834 
00835   inline v8::Local<v8::Value> MakeCallback(
00836       v8::Local<v8::Object> target
00837     , const char* method
00838     , int argc
00839     , v8::Local<v8::Value>* argv) {
00840 #if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
00841     return New(node::MakeCallback(
00842         v8::Isolate::GetCurrent(), target, method, argc, argv));
00843 #else
00844     return node::MakeCallback(
00845         v8::Isolate::GetCurrent(), target, method, argc, argv);
00846 #endif
00847   }
00848 
00849   inline void FatalException(const TryCatch& try_catch) {
00850     node::FatalException(v8::Isolate::GetCurrent(), try_catch.try_catch_);
00851   }
00852 
00853   inline v8::Local<v8::Value> ErrnoException(
00854           int errorno
00855        ,  const char* syscall = NULL
00856        ,  const char* message = NULL
00857        ,  const char* path = NULL) {
00858     return node::ErrnoException(v8::Isolate::GetCurrent(), errorno, syscall,
00859             message, path);
00860   }
00861 
00862   NAN_DEPRECATED inline v8::Local<v8::Value> NanErrnoException(
00863           int errorno
00864        ,  const char* syscall = NULL
00865        ,  const char* message = NULL
00866        ,  const char* path = NULL) {
00867     return ErrnoException(errorno, syscall, message, path);
00868   }
00869 
00870   template<typename T>
00871   inline void SetIsolateData(
00872       v8::Isolate *isolate
00873     , T *data
00874   ) {
00875       isolate->SetData(0, data);
00876   }
00877 
00878   template<typename T>
00879   inline T *GetIsolateData(
00880       v8::Isolate *isolate
00881   ) {
00882       return static_cast<T*>(isolate->GetData(0));
00883   }
00884 
00885 class Utf8String {
00886  public:
00887   inline explicit Utf8String(v8::Local<v8::Value> from) :
00888       length_(0), str_(str_st_) {
00889     if (!from.IsEmpty()) {
00890       v8::Local<v8::String> string = from->ToString();
00891       if (!string.IsEmpty()) {
00892         size_t len = 3 * string->Length() + 1;
00893         assert(len <= INT_MAX);
00894         if (len > sizeof (str_st_)) {
00895           str_ = static_cast<char*>(malloc(len));
00896           assert(str_ != 0);
00897         }
00898         const int flags =
00899             v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
00900         length_ = string->WriteUtf8(str_, static_cast<int>(len), 0, flags);
00901         str_[length_] = '\0';
00902       }
00903     }
00904   }
00905 
00906   inline int length() const {
00907     return length_;
00908   }
00909 
00910   inline char* operator*() { return str_; }
00911   inline const char* operator*() const { return str_; }
00912 
00913   inline ~Utf8String() {
00914     if (str_ != str_st_) {
00915       free(str_);
00916     }
00917   }
00918 
00919  private:
00920   NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
00921 
00922   int length_;
00923   char *str_;
00924   char str_st_[1024];
00925 };
00926 
00927 #else  // Node 0.8 and 0.10
00928   inline v8::Local<v8::Primitive> Undefined() {
00929     EscapableHandleScope scope;
00930     return scope.Escape(New(v8::Undefined()));
00931   }
00932 
00933   inline v8::Local<v8::Primitive> Null() {
00934     EscapableHandleScope scope;
00935     return scope.Escape(New(v8::Null()));
00936   }
00937 
00938   inline v8::Local<v8::Boolean> True() {
00939     EscapableHandleScope scope;
00940     return scope.Escape(New(v8::True()));
00941   }
00942 
00943   inline v8::Local<v8::Boolean> False() {
00944     EscapableHandleScope scope;
00945     return scope.Escape(New(v8::False()));
00946   }
00947 
00948   inline v8::Local<v8::String> EmptyString() {
00949     return v8::String::Empty();
00950   }
00951 
00952   inline int AdjustExternalMemory(int bc) {
00953     return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
00954   }
00955 
00956   inline void SetTemplate(
00957       v8::Local<v8::Template> templ
00958     , const char *name
00959     , v8::Local<v8::Data> value) {
00960     templ->Set(name, value);
00961   }
00962 
00963   inline void SetTemplate(
00964       v8::Local<v8::Template> templ
00965     , v8::Local<v8::String> name
00966     , v8::Local<v8::Data> value
00967     , v8::PropertyAttribute attributes) {
00968     templ->Set(name, value, attributes);
00969   }
00970 
00971   inline v8::Local<v8::Context> GetCurrentContext() {
00972     return v8::Context::GetCurrent();
00973   }
00974 
00975   inline void* GetInternalFieldPointer(
00976       v8::Local<v8::Object> object
00977     , int index) {
00978     return object->GetPointerFromInternalField(index);
00979   }
00980 
00981   inline void SetInternalFieldPointer(
00982       v8::Local<v8::Object> object
00983     , int index
00984     , void* value) {
00985     object->SetPointerInInternalField(index, value);
00986   }
00987 
00988 # define NAN_GC_CALLBACK(name)                                                 \
00989     void name(v8::GCType type, v8::GCCallbackFlags flags)
00990 
00991   inline void AddGCEpilogueCallback(
00992     v8::GCEpilogueCallback callback
00993   , v8::GCType gc_type_filter = v8::kGCTypeAll) {
00994     v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);
00995   }
00996   inline void RemoveGCEpilogueCallback(
00997     v8::GCEpilogueCallback callback) {
00998     v8::V8::RemoveGCEpilogueCallback(callback);
00999   }
01000   inline void AddGCPrologueCallback(
01001     v8::GCPrologueCallback callback
01002   , v8::GCType gc_type_filter = v8::kGCTypeAll) {
01003     v8::V8::AddGCPrologueCallback(callback, gc_type_filter);
01004   }
01005   inline void RemoveGCPrologueCallback(
01006     v8::GCPrologueCallback callback) {
01007     v8::V8::RemoveGCPrologueCallback(callback);
01008   }
01009   inline void GetHeapStatistics(
01010     v8::HeapStatistics *heap_statistics) {
01011     v8::V8::GetHeapStatistics(heap_statistics);
01012   }
01013 
01014 # define X(NAME)                                                               \
01015     inline v8::Local<v8::Value> NAME(const char *msg) {                    \
01016       EscapableHandleScope scope;                                              \
01017       return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked()));     \
01018     }                                                                          \
01019                                                                                \
01020     inline                                                                 \
01021     v8::Local<v8::Value> NAME(v8::Local<v8::String> msg) {                     \
01022       return v8::Exception::NAME(msg);                                         \
01023     }                                                                          \
01024                                                                                \
01025     inline void Throw ## NAME(const char *msg) {                           \
01026       HandleScope scope;                                                       \
01027       v8::ThrowException(v8::Exception::NAME(New(msg).ToLocalChecked()));      \
01028     }                                                                          \
01029                                                                                \
01030     inline                                                                 \
01031     void Throw ## NAME(v8::Local<v8::String> errmsg) {                         \
01032       v8::ThrowException(v8::Exception::NAME(errmsg));                         \
01033     }
01034 
01035   X(Error)
01036   X(RangeError)
01037   X(ReferenceError)
01038   X(SyntaxError)
01039   X(TypeError)
01040 
01041 # undef X
01042 
01043   inline void ThrowError(v8::Local<v8::Value> error) {
01044     v8::ThrowException(error);
01045   }
01046 
01047   inline MaybeLocal<v8::Object> NewBuffer(
01048       char *data
01049     , size_t length
01050     , node::Buffer::free_callback callback
01051     , void *hint
01052   ) {
01053     EscapableHandleScope scope;
01054     // arbitrary buffer lengths requires
01055     // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
01056     assert(length <= imp::kMaxLength && "too large buffer");
01057     return MaybeLocal<v8::Object>(scope.Escape(
01058         New(node::Buffer::New(data, length, callback, hint)->handle_)));
01059   }
01060 
01061   inline MaybeLocal<v8::Object> CopyBuffer(
01062       const char *data
01063     , uint32_t size
01064   ) {
01065     EscapableHandleScope scope;
01066     // arbitrary buffer lengths requires
01067     // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
01068     assert(size <= imp::kMaxLength && "too large buffer");
01069 #if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
01070     return MaybeLocal<v8::Object>(
01071         scope.Escape(New(node::Buffer::New(data, size)->handle_)));
01072 #else
01073     return MaybeLocal<v8::Object>(scope.Escape(
01074         New(node::Buffer::New(const_cast<char*>(data), size)->handle_)));
01075 #endif
01076   }
01077 
01078   inline MaybeLocal<v8::Object> NewBuffer(uint32_t size) {
01079     // arbitrary buffer lengths requires
01080     // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
01081     EscapableHandleScope scope;
01082     assert(size <= imp::kMaxLength && "too large buffer");
01083     return MaybeLocal<v8::Object>(
01084         scope.Escape(New(node::Buffer::New(size)->handle_)));
01085   }
01086 
01087   inline void FreeData(char *data, void *hint) {
01088     (void) hint;  // unused
01089     delete[] data;
01090   }
01091 
01092   inline MaybeLocal<v8::Object> NewBuffer(
01093       char* data
01094     , uint32_t size
01095   ) {
01096     EscapableHandleScope scope;
01097     // arbitrary buffer lengths requires
01098     // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
01099     assert(size <= imp::kMaxLength && "too large buffer");
01100     return MaybeLocal<v8::Object>(scope.Escape(New(
01101         node::Buffer::New(data, size, FreeData, NULL)->handle_)));
01102   }
01103 
01104 namespace imp {
01105 inline void
01106 widenString(std::vector<uint16_t> *ws, const uint8_t *s, int l) {
01107   size_t len = static_cast<size_t>(l);
01108   if (l < 0) {
01109     len = strlen(reinterpret_cast<const char*>(s));
01110   }
01111   assert(len <= INT_MAX && "string too long");
01112   ws->resize(len);
01113   std::copy(s, s + len, ws->begin());  // NOLINT(build/include_what_you_use)
01114 }
01115 }  // end of namespace imp
01116 
01117   inline MaybeLocal<v8::String>
01118   NewOneByteString(const uint8_t * value, int length = -1) {
01119     std::vector<uint16_t> wideString;  // NOLINT(build/include_what_you_use)
01120     imp::widenString(&wideString, value, length);
01121     return imp::Factory<v8::String>::return_t(v8::String::New(
01122         &wideString.front(), static_cast<int>(wideString.size())));
01123   }
01124 
01125   inline MaybeLocal<BoundScript> CompileScript(
01126       v8::Local<v8::String> s
01127     , const v8::ScriptOrigin& origin
01128   ) {
01129     return MaybeLocal<BoundScript>(
01130         v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin)));
01131   }
01132 
01133   inline MaybeLocal<BoundScript> CompileScript(
01134     v8::Local<v8::String> s
01135   ) {
01136     return MaybeLocal<BoundScript>(v8::Script::Compile(s));
01137   }
01138 
01139   inline
01140   MaybeLocal<v8::Value> RunScript(v8::Local<v8::Script> script) {
01141     return MaybeLocal<v8::Value>(script->Run());
01142   }
01143 
01144   inline v8::Local<v8::Value> MakeCallback(
01145       v8::Local<v8::Object> target
01146     , v8::Local<v8::Function> func
01147     , int argc
01148     , v8::Local<v8::Value>* argv) {
01149     return New(node::MakeCallback(target, func, argc, argv));
01150   }
01151 
01152   inline v8::Local<v8::Value> MakeCallback(
01153       v8::Local<v8::Object> target
01154     , v8::Local<v8::String> symbol
01155     , int argc
01156     , v8::Local<v8::Value>* argv) {
01157     return New(node::MakeCallback(target, symbol, argc, argv));
01158   }
01159 
01160   inline v8::Local<v8::Value> MakeCallback(
01161       v8::Local<v8::Object> target
01162     , const char* method
01163     , int argc
01164     , v8::Local<v8::Value>* argv) {
01165     return New(node::MakeCallback(target, method, argc, argv));
01166   }
01167 
01168   inline void FatalException(const TryCatch& try_catch) {
01169     node::FatalException(const_cast<v8::TryCatch &>(try_catch.try_catch_));
01170   }
01171 
01172   inline v8::Local<v8::Value> ErrnoException(
01173           int errorno
01174        ,  const char* syscall = NULL
01175        ,  const char* message = NULL
01176        ,  const char* path = NULL) {
01177     return node::ErrnoException(errorno, syscall, message, path);
01178   }
01179 
01180   NAN_DEPRECATED inline v8::Local<v8::Value> NanErrnoException(
01181           int errorno
01182        ,  const char* syscall = NULL
01183        ,  const char* message = NULL
01184        ,  const char* path = NULL) {
01185     return ErrnoException(errorno, syscall, message, path);
01186   }
01187 
01188 
01189   template<typename T>
01190   inline void SetIsolateData(
01191       v8::Isolate *isolate
01192     , T *data
01193   ) {
01194       isolate->SetData(data);
01195   }
01196 
01197   template<typename T>
01198   inline T *GetIsolateData(
01199       v8::Isolate *isolate
01200   ) {
01201       return static_cast<T*>(isolate->GetData());
01202   }
01203 
01204 class Utf8String {
01205  public:
01206   inline explicit Utf8String(v8::Local<v8::Value> from) :
01207       length_(0), str_(str_st_) {
01208     if (!from.IsEmpty()) {
01209       v8::Local<v8::String> string = from->ToString();
01210       if (!string.IsEmpty()) {
01211         size_t len = 3 * string->Length() + 1;
01212         assert(len <= INT_MAX);
01213         if (len > sizeof (str_st_)) {
01214           str_ = static_cast<char*>(malloc(len));
01215           assert(str_ != 0);
01216         }
01217         const int flags =
01218             v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
01219         length_ = string->WriteUtf8(str_, static_cast<int>(len), 0, flags);
01220         str_[length_] = '\0';
01221       }
01222     }
01223   }
01224 
01225   inline int length() const {
01226     return length_;
01227   }
01228 
01229   inline char* operator*() { return str_; }
01230   inline const char* operator*() const { return str_; }
01231 
01232   inline ~Utf8String() {
01233     if (str_ != str_st_) {
01234       free(str_);
01235     }
01236   }
01237 
01238  private:
01239   NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
01240 
01241   int length_;
01242   char *str_;
01243   char str_st_[1024];
01244 };
01245 
01246 #endif  // NODE_MODULE_VERSION
01247 
01248 typedef void (*FreeCallback)(char *data, void *hint);
01249 
01250 typedef const FunctionCallbackInfo<v8::Value>& NAN_METHOD_ARGS_TYPE;
01251 typedef void NAN_METHOD_RETURN_TYPE;
01252 
01253 typedef const PropertyCallbackInfo<v8::Value>& NAN_GETTER_ARGS_TYPE;
01254 typedef void NAN_GETTER_RETURN_TYPE;
01255 
01256 typedef const PropertyCallbackInfo<void>& NAN_SETTER_ARGS_TYPE;
01257 typedef void NAN_SETTER_RETURN_TYPE;
01258 
01259 typedef const PropertyCallbackInfo<v8::Value>&
01260     NAN_PROPERTY_GETTER_ARGS_TYPE;
01261 typedef void NAN_PROPERTY_GETTER_RETURN_TYPE;
01262 
01263 typedef const PropertyCallbackInfo<v8::Value>&
01264     NAN_PROPERTY_SETTER_ARGS_TYPE;
01265 typedef void NAN_PROPERTY_SETTER_RETURN_TYPE;
01266 
01267 typedef const PropertyCallbackInfo<v8::Array>&
01268     NAN_PROPERTY_ENUMERATOR_ARGS_TYPE;
01269 typedef void NAN_PROPERTY_ENUMERATOR_RETURN_TYPE;
01270 
01271 typedef const PropertyCallbackInfo<v8::Boolean>&
01272     NAN_PROPERTY_DELETER_ARGS_TYPE;
01273 typedef void NAN_PROPERTY_DELETER_RETURN_TYPE;
01274 
01275 typedef const PropertyCallbackInfo<v8::Integer>&
01276     NAN_PROPERTY_QUERY_ARGS_TYPE;
01277 typedef void NAN_PROPERTY_QUERY_RETURN_TYPE;
01278 
01279 typedef const PropertyCallbackInfo<v8::Value>& NAN_INDEX_GETTER_ARGS_TYPE;
01280 typedef void NAN_INDEX_GETTER_RETURN_TYPE;
01281 
01282 typedef const PropertyCallbackInfo<v8::Value>& NAN_INDEX_SETTER_ARGS_TYPE;
01283 typedef void NAN_INDEX_SETTER_RETURN_TYPE;
01284 
01285 typedef const PropertyCallbackInfo<v8::Array>&
01286     NAN_INDEX_ENUMERATOR_ARGS_TYPE;
01287 typedef void NAN_INDEX_ENUMERATOR_RETURN_TYPE;
01288 
01289 typedef const PropertyCallbackInfo<v8::Boolean>&
01290     NAN_INDEX_DELETER_ARGS_TYPE;
01291 typedef void NAN_INDEX_DELETER_RETURN_TYPE;
01292 
01293 typedef const PropertyCallbackInfo<v8::Integer>&
01294     NAN_INDEX_QUERY_ARGS_TYPE;
01295 typedef void NAN_INDEX_QUERY_RETURN_TYPE;
01296 
01297 #define NAN_METHOD(name)                                                       \
01298     Nan::NAN_METHOD_RETURN_TYPE name(Nan::NAN_METHOD_ARGS_TYPE info)
01299 #define NAN_GETTER(name)                                                       \
01300     Nan::NAN_GETTER_RETURN_TYPE name(                                          \
01301         v8::Local<v8::String> property                                         \
01302       , Nan::NAN_GETTER_ARGS_TYPE info)
01303 #define NAN_SETTER(name)                                                       \
01304     Nan::NAN_SETTER_RETURN_TYPE name(                                          \
01305         v8::Local<v8::String> property                                         \
01306       , v8::Local<v8::Value> value                                             \
01307       , Nan::NAN_SETTER_ARGS_TYPE info)
01308 #define NAN_PROPERTY_GETTER(name)                                              \
01309     Nan::NAN_PROPERTY_GETTER_RETURN_TYPE name(                                 \
01310         v8::Local<v8::String> property                                         \
01311       , Nan::NAN_PROPERTY_GETTER_ARGS_TYPE info)
01312 #define NAN_PROPERTY_SETTER(name)                                              \
01313     Nan::NAN_PROPERTY_SETTER_RETURN_TYPE name(                                 \
01314         v8::Local<v8::String> property                                         \
01315       , v8::Local<v8::Value> value                                             \
01316       , Nan::NAN_PROPERTY_SETTER_ARGS_TYPE info)
01317 #define NAN_PROPERTY_ENUMERATOR(name)                                          \
01318     Nan::NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(                             \
01319         Nan::NAN_PROPERTY_ENUMERATOR_ARGS_TYPE info)
01320 #define NAN_PROPERTY_DELETER(name)                                             \
01321     Nan::NAN_PROPERTY_DELETER_RETURN_TYPE name(                                \
01322         v8::Local<v8::String> property                                         \
01323       , Nan::NAN_PROPERTY_DELETER_ARGS_TYPE info)
01324 #define NAN_PROPERTY_QUERY(name)                                               \
01325     Nan::NAN_PROPERTY_QUERY_RETURN_TYPE name(                                  \
01326         v8::Local<v8::String> property                                         \
01327       , Nan::NAN_PROPERTY_QUERY_ARGS_TYPE info)
01328 # define NAN_INDEX_GETTER(name)                                                \
01329     Nan::NAN_INDEX_GETTER_RETURN_TYPE name(                                    \
01330         uint32_t index                                                         \
01331       , Nan::NAN_INDEX_GETTER_ARGS_TYPE info)
01332 #define NAN_INDEX_SETTER(name)                                                 \
01333     Nan::NAN_INDEX_SETTER_RETURN_TYPE name(                                    \
01334         uint32_t index                                                         \
01335       , v8::Local<v8::Value> value                                             \
01336       , Nan::NAN_INDEX_SETTER_ARGS_TYPE info)
01337 #define NAN_INDEX_ENUMERATOR(name)                                             \
01338     Nan::NAN_INDEX_ENUMERATOR_RETURN_TYPE                                      \
01339     name(Nan::NAN_INDEX_ENUMERATOR_ARGS_TYPE info)
01340 #define NAN_INDEX_DELETER(name)                                                \
01341     Nan::NAN_INDEX_DELETER_RETURN_TYPE name(                                   \
01342         uint32_t index                                                         \
01343       , Nan::NAN_INDEX_DELETER_ARGS_TYPE info)
01344 #define NAN_INDEX_QUERY(name)                                                  \
01345     Nan::NAN_INDEX_QUERY_RETURN_TYPE name(                                     \
01346         uint32_t index                                                         \
01347       , Nan::NAN_INDEX_QUERY_ARGS_TYPE info)
01348 
01349 class Callback {
01350  public:
01351   Callback() {}
01352 
01353   explicit Callback(const v8::Local<v8::Function> &fn) : handle_(fn) {}
01354 
01355   ~Callback() {
01356     handle_.Reset();
01357   }
01358 
01359   bool operator==(const Callback &other) const {
01360     return handle_ == other.handle_;
01361   }
01362 
01363   bool operator!=(const Callback &other) const {
01364     return !operator==(other);
01365   }
01366 
01367   inline
01368   v8::Local<v8::Function> operator*() const { return GetFunction(); }
01369 
01370   inline v8::Local<v8::Value> operator()(
01371       v8::Local<v8::Object> target
01372     , int argc = 0
01373     , v8::Local<v8::Value> argv[] = 0) const {
01374     return this->Call(target, argc, argv);
01375   }
01376 
01377   inline v8::Local<v8::Value> operator()(
01378       int argc = 0
01379     , v8::Local<v8::Value> argv[] = 0) const {
01380     return this->Call(argc, argv);
01381   }
01382 
01383   // TODO(kkoopa): remove
01384   inline void SetFunction(const v8::Local<v8::Function> &fn) {
01385     Reset(fn);
01386   }
01387 
01388   inline void Reset(const v8::Local<v8::Function> &fn) {
01389     handle_.Reset(fn);
01390   }
01391 
01392   inline void Reset() {
01393     handle_.Reset();
01394   }
01395 
01396   inline v8::Local<v8::Function> GetFunction() const {
01397     return New(handle_);
01398   }
01399 
01400   inline bool IsEmpty() const {
01401     return handle_.IsEmpty();
01402   }
01403 
01404   inline v8::Local<v8::Value>
01405   Call(v8::Local<v8::Object> target
01406      , int argc
01407      , v8::Local<v8::Value> argv[]) const {
01408 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
01409     v8::Isolate *isolate = v8::Isolate::GetCurrent();
01410     return Call_(isolate, target, argc, argv);
01411 #else
01412     return Call_(target, argc, argv);
01413 #endif
01414   }
01415 
01416   inline v8::Local<v8::Value>
01417   Call(int argc, v8::Local<v8::Value> argv[]) const {
01418 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
01419     v8::Isolate *isolate = v8::Isolate::GetCurrent();
01420     return Call_(isolate, isolate->GetCurrentContext()->Global(), argc, argv);
01421 #else
01422     return Call_(v8::Context::GetCurrent()->Global(), argc, argv);
01423 #endif
01424   }
01425 
01426  private:
01427   NAN_DISALLOW_ASSIGN_COPY_MOVE(Callback)
01428   Persistent<v8::Function> handle_;
01429 
01430 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
01431   v8::Local<v8::Value> Call_(v8::Isolate *isolate
01432                            , v8::Local<v8::Object> target
01433                            , int argc
01434                            , v8::Local<v8::Value> argv[]) const {
01435     EscapableHandleScope scope;
01436 
01437     v8::Local<v8::Function> callback = New(handle_);
01438 # if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
01439     return scope.Escape(New(node::MakeCallback(
01440         isolate
01441       , target
01442       , callback
01443       , argc
01444       , argv
01445     )));
01446 # else
01447     return scope.Escape(node::MakeCallback(
01448         isolate
01449       , target
01450       , callback
01451       , argc
01452       , argv
01453     ));
01454 # endif
01455   }
01456 #else
01457   v8::Local<v8::Value> Call_(v8::Local<v8::Object> target
01458                            , int argc
01459                            , v8::Local<v8::Value> argv[]) const {
01460     EscapableHandleScope scope;
01461 
01462     v8::Local<v8::Function> callback = New(handle_);
01463     return scope.Escape(New(node::MakeCallback(
01464         target
01465       , callback
01466       , argc
01467       , argv
01468     )));
01469   }
01470 #endif
01471 };
01472 
01473 /* abstract */ class AsyncWorker {
01474  public:
01475   explicit AsyncWorker(Callback *callback_)
01476       : callback(callback_), errmsg_(NULL) {
01477     request.data = this;
01478 
01479     HandleScope scope;
01480     v8::Local<v8::Object> obj = New<v8::Object>();
01481     persistentHandle.Reset(obj);
01482   }
01483 
01484   virtual ~AsyncWorker() {
01485     HandleScope scope;
01486 
01487     if (!persistentHandle.IsEmpty())
01488       persistentHandle.Reset();
01489     delete callback;
01490     delete[] errmsg_;
01491   }
01492 
01493   virtual void WorkComplete() {
01494     HandleScope scope;
01495 
01496     if (errmsg_ == NULL)
01497       HandleOKCallback();
01498     else
01499       HandleErrorCallback();
01500     delete callback;
01501     callback = NULL;
01502   }
01503 
01504   inline void SaveToPersistent(
01505       const char *key, const v8::Local<v8::Value> &value) {
01506     HandleScope scope;
01507     New(persistentHandle)->Set(New(key).ToLocalChecked(), value);
01508   }
01509 
01510   inline void SaveToPersistent(
01511       const v8::Local<v8::String> &key, const v8::Local<v8::Value> &value) {
01512     HandleScope scope;
01513     New(persistentHandle)->Set(key, value);
01514   }
01515 
01516   inline void SaveToPersistent(
01517       uint32_t index, const v8::Local<v8::Value> &value) {
01518     HandleScope scope;
01519     New(persistentHandle)->Set(index, value);
01520   }
01521 
01522   inline v8::Local<v8::Value> GetFromPersistent(const char *key) const {
01523     EscapableHandleScope scope;
01524     return scope.Escape(
01525         New(persistentHandle)->Get(New(key).ToLocalChecked()));
01526   }
01527 
01528   inline v8::Local<v8::Value>
01529   GetFromPersistent(const v8::Local<v8::String> &key) const {
01530     EscapableHandleScope scope;
01531     return scope.Escape(New(persistentHandle)->Get(key));
01532   }
01533 
01534   inline v8::Local<v8::Value> GetFromPersistent(uint32_t index) const {
01535     EscapableHandleScope scope;
01536     return scope.Escape(New(persistentHandle)->Get(index));
01537   }
01538 
01539   virtual void Execute() = 0;
01540 
01541   uv_work_t request;
01542 
01543   virtual void Destroy() {
01544       delete this;
01545   }
01546 
01547  protected:
01548   Persistent<v8::Object> persistentHandle;
01549   Callback *callback;
01550 
01551   virtual void HandleOKCallback() {
01552     callback->Call(0, NULL);
01553   }
01554 
01555   virtual void HandleErrorCallback() {
01556     HandleScope scope;
01557 
01558     v8::Local<v8::Value> argv[] = {
01559       v8::Exception::Error(New<v8::String>(ErrorMessage()).ToLocalChecked())
01560     };
01561     callback->Call(1, argv);
01562   }
01563 
01564   void SetErrorMessage(const char *msg) {
01565     delete[] errmsg_;
01566 
01567     size_t size = strlen(msg) + 1;
01568     errmsg_ = new char[size];
01569     memcpy(errmsg_, msg, size);
01570   }
01571 
01572   const char* ErrorMessage() const {
01573     return errmsg_;
01574   }
01575 
01576  private:
01577   NAN_DISALLOW_ASSIGN_COPY_MOVE(AsyncWorker)
01578   char *errmsg_;
01579 };
01580 
01581 
01582 template<class T>
01583 /* abstract */ class AsyncProgressWorkerBase : public AsyncWorker {
01584  public:
01585   explicit AsyncProgressWorkerBase(Callback *callback_)
01586       : AsyncWorker(callback_), asyncdata_(NULL), asyncsize_(0) {
01587     async = new uv_async_t;
01588     uv_async_init(
01589         uv_default_loop()
01590       , async
01591       , AsyncProgress_
01592     );
01593     async->data = this;
01594 
01595     uv_mutex_init(&async_lock);
01596   }
01597 
01598   virtual ~AsyncProgressWorkerBase() {
01599     uv_mutex_destroy(&async_lock);
01600 
01601     delete[] asyncdata_;
01602   }
01603 
01604   void WorkProgress() {
01605     uv_mutex_lock(&async_lock);
01606     T *data = asyncdata_;
01607     size_t size = asyncsize_;
01608     asyncdata_ = NULL;
01609     uv_mutex_unlock(&async_lock);
01610 
01611     // Don't send progress events after we've already completed.
01612     if (callback) {
01613         HandleProgressCallback(data, size);
01614     }
01615     delete[] data;
01616   }
01617 
01618   class ExecutionProgress {
01619     friend class AsyncProgressWorkerBase;
01620    public:
01621     void Signal() const {
01622         uv_async_send(that_->async);
01623     }
01624 
01625     void Send(const T* data, size_t size) const {
01626         that_->SendProgress_(data, size);
01627     }
01628 
01629    private:
01630     explicit ExecutionProgress(AsyncProgressWorkerBase *that) : that_(that) {}
01631     NAN_DISALLOW_ASSIGN_COPY_MOVE(ExecutionProgress)
01632     AsyncProgressWorkerBase* const that_;
01633   };
01634 
01635   virtual void Execute(const ExecutionProgress& progress) = 0;
01636   virtual void HandleProgressCallback(const T *data, size_t size) = 0;
01637 
01638   virtual void Destroy() {
01639       uv_close(reinterpret_cast<uv_handle_t*>(async), AsyncClose_);
01640   }
01641 
01642  private:
01643   void Execute() /*final override*/ {
01644       ExecutionProgress progress(this);
01645       Execute(progress);
01646   }
01647 
01648   void SendProgress_(const T *data, size_t size) {
01649     T *new_data = new T[size];
01650     {
01651       T *it = new_data;
01652       std::copy(data, data + size, it);
01653     }
01654 
01655     uv_mutex_lock(&async_lock);
01656     T *old_data = asyncdata_;
01657     asyncdata_ = new_data;
01658     asyncsize_ = size;
01659     uv_mutex_unlock(&async_lock);
01660 
01661     delete[] old_data;
01662     uv_async_send(async);
01663   }
01664 
01665   inline static NAUV_WORK_CB(AsyncProgress_) {
01666     AsyncProgressWorkerBase *worker =
01667             static_cast<AsyncProgressWorkerBase*>(async->data);
01668     worker->WorkProgress();
01669   }
01670 
01671   inline static void AsyncClose_(uv_handle_t* handle) {
01672     AsyncProgressWorkerBase *worker =
01673             static_cast<AsyncProgressWorkerBase*>(handle->data);
01674     delete reinterpret_cast<uv_async_t*>(handle);
01675     delete worker;
01676   }
01677 
01678   uv_async_t *async;
01679   uv_mutex_t async_lock;
01680   T *asyncdata_;
01681   size_t asyncsize_;
01682 };
01683 
01684 // This ensures compatibility to the previous un-templated AsyncProgressWorker
01685 // class definition.
01686 typedef AsyncProgressWorkerBase<char> AsyncProgressWorker;
01687 
01688 inline void AsyncExecute (uv_work_t* req) {
01689   AsyncWorker *worker = static_cast<AsyncWorker*>(req->data);
01690   worker->Execute();
01691 }
01692 
01693 inline void AsyncExecuteComplete (uv_work_t* req) {
01694   AsyncWorker* worker = static_cast<AsyncWorker*>(req->data);
01695   worker->WorkComplete();
01696   worker->Destroy();
01697 }
01698 
01699 inline void AsyncQueueWorker (AsyncWorker* worker) {
01700   uv_queue_work(
01701       uv_default_loop()
01702     , &worker->request
01703     , AsyncExecute
01704     , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
01705   );
01706 }
01707 
01708 namespace imp {
01709 
01710 inline
01711 ExternalOneByteStringResource const*
01712 GetExternalResource(v8::Local<v8::String> str) {
01713 #if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION
01714     return str->GetExternalAsciiStringResource();
01715 #else
01716     return str->GetExternalOneByteStringResource();
01717 #endif
01718 }
01719 
01720 inline
01721 bool
01722 IsExternal(v8::Local<v8::String> str) {
01723 #if NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION
01724     return str->IsExternalAscii();
01725 #else
01726     return str->IsExternalOneByte();
01727 #endif
01728 }
01729 
01730 }  // end of namespace imp
01731 
01732 enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER};
01733 
01734 #if NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION
01735 # include "nan_string_bytes.h"  // NOLINT(build/include)
01736 #endif
01737 
01738 inline v8::Local<v8::Value> Encode(
01739     const void *buf, size_t len, enum Encoding encoding = BINARY) {
01740 #if (NODE_MODULE_VERSION >= ATOM_0_21_MODULE_VERSION)
01741   v8::Isolate* isolate = v8::Isolate::GetCurrent();
01742   node::encoding node_enc = static_cast<node::encoding>(encoding);
01743 
01744   if (encoding == UCS2) {
01745     return node::Encode(
01746         isolate
01747       , reinterpret_cast<const uint16_t *>(buf)
01748       , len / 2);
01749   } else {
01750     return node::Encode(
01751         isolate
01752       , reinterpret_cast<const char *>(buf)
01753       , len
01754       , node_enc);
01755   }
01756 #elif (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
01757   return node::Encode(
01758       v8::Isolate::GetCurrent()
01759     , buf, len
01760     , static_cast<node::encoding>(encoding));
01761 #else
01762 # if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
01763   return node::Encode(buf, len, static_cast<node::encoding>(encoding));
01764 # else
01765   return imp::Encode(reinterpret_cast<const char*>(buf), len, encoding);
01766 # endif
01767 #endif
01768 }
01769 
01770 inline ssize_t DecodeBytes(
01771     v8::Local<v8::Value> val, enum Encoding encoding = BINARY) {
01772 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
01773   return node::DecodeBytes(
01774       v8::Isolate::GetCurrent()
01775     , val
01776     , static_cast<node::encoding>(encoding));
01777 #else
01778 # if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)
01779   if (encoding == BUFFER) {
01780     return node::DecodeBytes(val, node::BINARY);
01781   }
01782 # endif
01783   return node::DecodeBytes(val, static_cast<node::encoding>(encoding));
01784 #endif
01785 }
01786 
01787 inline ssize_t DecodeWrite(
01788     char *buf
01789   , size_t len
01790   , v8::Local<v8::Value> val
01791   , enum Encoding encoding = BINARY) {
01792 #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
01793   return node::DecodeWrite(
01794       v8::Isolate::GetCurrent()
01795     , buf
01796     , len
01797     , val
01798     , static_cast<node::encoding>(encoding));
01799 #else
01800 # if (NODE_MODULE_VERSION < NODE_0_10_MODULE_VERSION)
01801   if (encoding == BUFFER) {
01802     return node::DecodeWrite(buf, len, val, node::BINARY);
01803   }
01804 # endif
01805   return node::DecodeWrite(
01806       buf
01807     , len
01808     , val
01809     , static_cast<node::encoding>(encoding));
01810 #endif
01811 }
01812 
01813 inline void SetPrototypeTemplate(
01814     v8::Local<v8::FunctionTemplate> templ
01815   , const char *name
01816   , v8::Local<v8::Data> value
01817 ) {
01818   SetTemplate(templ->PrototypeTemplate(), name, value);
01819 }
01820 
01821 inline void SetPrototypeTemplate(
01822     v8::Local<v8::FunctionTemplate> templ
01823   , v8::Local<v8::String> name
01824   , v8::Local<v8::Data> value
01825   , v8::PropertyAttribute attributes
01826 ) {
01827   SetTemplate(templ->PrototypeTemplate(), name, value, attributes);
01828 }
01829 
01830 inline void SetInstanceTemplate(
01831     v8::Local<v8::FunctionTemplate> templ
01832   , const char *name
01833   , v8::Local<v8::Data> value
01834 ) {
01835   SetTemplate(templ->InstanceTemplate(), name, value);
01836 }
01837 
01838 inline void SetInstanceTemplate(
01839     v8::Local<v8::FunctionTemplate> templ
01840   , v8::Local<v8::String> name
01841   , v8::Local<v8::Data> value
01842   , v8::PropertyAttribute attributes
01843 ) {
01844   SetTemplate(templ->InstanceTemplate(), name, value, attributes);
01845 }
01846 
01847 namespace imp {
01848 
01849 // Note(@agnat): Helper to distinguish different receiver types. The first
01850 // version deals with receivers derived from v8::Template. The second version
01851 // handles everything else. The final argument only serves as discriminator and
01852 // is unused.
01853 template <typename T>
01854 inline
01855 void
01856 SetMethodAux(T recv,
01857              v8::Local<v8::String> name,
01858              v8::Local<v8::FunctionTemplate> tpl,
01859              v8::Template *) {
01860   recv->Set(name, tpl);
01861 }
01862 
01863 template <typename T>
01864 inline
01865 void
01866 SetMethodAux(T recv,
01867              v8::Local<v8::String> name,
01868              v8::Local<v8::FunctionTemplate> tpl,
01869              ...) {
01870   recv->Set(name, GetFunction(tpl).ToLocalChecked());
01871 }
01872 
01873 }  // end of namespace imp
01874 
01875 template <typename T, template <typename> class HandleType>
01876 inline void SetMethod(
01877     HandleType<T> recv
01878   , const char *name
01879   , FunctionCallback callback) {
01880   HandleScope scope;
01881   v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(callback);
01882   v8::Local<v8::String> fn_name = New(name).ToLocalChecked();
01883   t->SetClassName(fn_name);
01884   // Note(@agnat): Pass an empty T* as discriminator. See note on
01885   // SetMethodAux(...) above
01886   imp::SetMethodAux(recv, fn_name, t, static_cast<T*>(0));
01887 }
01888 
01889 inline void SetPrototypeMethod(
01890     v8::Local<v8::FunctionTemplate> recv
01891   , const char* name, FunctionCallback callback) {
01892   HandleScope scope;
01893   v8::Local<v8::FunctionTemplate> t = New<v8::FunctionTemplate>(
01894       callback
01895     , v8::Local<v8::Value>()
01896     , New<v8::Signature>(recv));
01897   v8::Local<v8::String> fn_name = New(name).ToLocalChecked();
01898   recv->PrototypeTemplate()->Set(fn_name, t);
01899   t->SetClassName(fn_name);
01900 }
01901 
01902 //=== Accessors and Such =======================================================
01903 
01904 inline void SetAccessor(
01905     v8::Local<v8::ObjectTemplate> tpl
01906   , v8::Local<v8::String> name
01907   , GetterCallback getter
01908   , SetterCallback setter = 0
01909   , v8::Local<v8::Value> data = v8::Local<v8::Value>()
01910   , v8::AccessControl settings = v8::DEFAULT
01911   , v8::PropertyAttribute attribute = v8::None
01912   , imp::Sig signature = imp::Sig()) {
01913   HandleScope scope;
01914 
01915   imp::NativeGetter getter_ =
01916       imp::GetterCallbackWrapper;
01917   imp::NativeSetter setter_ =
01918       setter ? imp::SetterCallbackWrapper : 0;
01919 
01920   v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
01921   otpl->SetInternalFieldCount(imp::kAccessorFieldCount);
01922   v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
01923 
01924   obj->SetInternalField(
01925       imp::kGetterIndex
01926     , New<v8::External>(reinterpret_cast<void *>(getter)));
01927 
01928   if (setter != 0) {
01929     obj->SetInternalField(
01930         imp::kSetterIndex
01931       , New<v8::External>(reinterpret_cast<void *>(setter)));
01932   }
01933 
01934   if (!data.IsEmpty()) {
01935     obj->SetInternalField(imp::kDataIndex, data);
01936   }
01937 
01938   tpl->SetAccessor(
01939       name
01940     , getter_
01941     , setter_
01942     , obj
01943     , settings
01944     , attribute
01945     , signature);
01946 }
01947 
01948 inline bool SetAccessor(
01949     v8::Local<v8::Object> obj
01950   , v8::Local<v8::String> name
01951   , GetterCallback getter
01952   , SetterCallback setter = 0
01953   , v8::Local<v8::Value> data = v8::Local<v8::Value>()
01954   , v8::AccessControl settings = v8::DEFAULT
01955   , v8::PropertyAttribute attribute = v8::None) {
01956   EscapableHandleScope scope;
01957 
01958   imp::NativeGetter getter_ =
01959       imp::GetterCallbackWrapper;
01960   imp::NativeSetter setter_ =
01961       setter ? imp::SetterCallbackWrapper : 0;
01962 
01963   v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
01964   otpl->SetInternalFieldCount(imp::kAccessorFieldCount);
01965   v8::Local<v8::Object> dataobj = NewInstance(otpl).ToLocalChecked();
01966 
01967   dataobj->SetInternalField(
01968       imp::kGetterIndex
01969     , New<v8::External>(reinterpret_cast<void *>(getter)));
01970 
01971   if (!data.IsEmpty()) {
01972     dataobj->SetInternalField(imp::kDataIndex, data);
01973   }
01974 
01975   if (setter) {
01976     dataobj->SetInternalField(
01977         imp::kSetterIndex
01978       , New<v8::External>(reinterpret_cast<void *>(setter)));
01979   }
01980 
01981 #if (NODE_MODULE_VERSION >= NODE_6_0_MODULE_VERSION)
01982   return obj->SetAccessor(
01983       GetCurrentContext()
01984     , name
01985     , getter_
01986     , setter_
01987     , dataobj
01988     , settings
01989     , attribute).FromMaybe(false);
01990 #else
01991   return obj->SetAccessor(
01992       name
01993     , getter_
01994     , setter_
01995     , dataobj
01996     , settings
01997     , attribute);
01998 #endif
01999 }
02000 
02001 inline void SetNamedPropertyHandler(
02002     v8::Local<v8::ObjectTemplate> tpl
02003   , PropertyGetterCallback getter
02004   , PropertySetterCallback setter = 0
02005   , PropertyQueryCallback query = 0
02006   , PropertyDeleterCallback deleter = 0
02007   , PropertyEnumeratorCallback enumerator = 0
02008   , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
02009   HandleScope scope;
02010 
02011   imp::NativePropertyGetter getter_ =
02012       imp::PropertyGetterCallbackWrapper;
02013   imp::NativePropertySetter setter_ =
02014       setter ? imp::PropertySetterCallbackWrapper : 0;
02015   imp::NativePropertyQuery query_ =
02016       query ? imp::PropertyQueryCallbackWrapper : 0;
02017   imp::NativePropertyDeleter *deleter_ =
02018       deleter ? imp::PropertyDeleterCallbackWrapper : 0;
02019   imp::NativePropertyEnumerator enumerator_ =
02020       enumerator ? imp::PropertyEnumeratorCallbackWrapper : 0;
02021 
02022   v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
02023   otpl->SetInternalFieldCount(imp::kPropertyFieldCount);
02024   v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
02025   obj->SetInternalField(
02026       imp::kPropertyGetterIndex
02027     , New<v8::External>(reinterpret_cast<void *>(getter)));
02028 
02029   if (setter) {
02030     obj->SetInternalField(
02031         imp::kPropertySetterIndex
02032       , New<v8::External>(reinterpret_cast<void *>(setter)));
02033   }
02034 
02035   if (query) {
02036     obj->SetInternalField(
02037         imp::kPropertyQueryIndex
02038       , New<v8::External>(reinterpret_cast<void *>(query)));
02039   }
02040 
02041   if (deleter) {
02042     obj->SetInternalField(
02043         imp::kPropertyDeleterIndex
02044       , New<v8::External>(reinterpret_cast<void *>(deleter)));
02045   }
02046 
02047   if (enumerator) {
02048     obj->SetInternalField(
02049         imp::kPropertyEnumeratorIndex
02050       , New<v8::External>(reinterpret_cast<void *>(enumerator)));
02051   }
02052 
02053   if (!data.IsEmpty()) {
02054     obj->SetInternalField(imp::kDataIndex, data);
02055   }
02056 
02057 #if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
02058   tpl->SetHandler(v8::NamedPropertyHandlerConfiguration(
02059       getter_, setter_, query_, deleter_, enumerator_, obj));
02060 #else
02061   tpl->SetNamedPropertyHandler(
02062       getter_
02063     , setter_
02064     , query_
02065     , deleter_
02066     , enumerator_
02067     , obj);
02068 #endif
02069 }
02070 
02071 inline void SetIndexedPropertyHandler(
02072     v8::Local<v8::ObjectTemplate> tpl
02073   , IndexGetterCallback getter
02074   , IndexSetterCallback setter = 0
02075   , IndexQueryCallback query = 0
02076   , IndexDeleterCallback deleter = 0
02077   , IndexEnumeratorCallback enumerator = 0
02078   , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
02079   HandleScope scope;
02080 
02081   imp::NativeIndexGetter getter_ =
02082       imp::IndexGetterCallbackWrapper;
02083   imp::NativeIndexSetter setter_ =
02084       setter ? imp::IndexSetterCallbackWrapper : 0;
02085   imp::NativeIndexQuery query_ =
02086       query ? imp::IndexQueryCallbackWrapper : 0;
02087   imp::NativeIndexDeleter deleter_ =
02088       deleter ? imp::IndexDeleterCallbackWrapper : 0;
02089   imp::NativeIndexEnumerator enumerator_ =
02090       enumerator ? imp::IndexEnumeratorCallbackWrapper : 0;
02091 
02092   v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
02093   otpl->SetInternalFieldCount(imp::kIndexPropertyFieldCount);
02094   v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
02095   obj->SetInternalField(
02096       imp::kIndexPropertyGetterIndex
02097     , New<v8::External>(reinterpret_cast<void *>(getter)));
02098 
02099   if (setter) {
02100     obj->SetInternalField(
02101         imp::kIndexPropertySetterIndex
02102       , New<v8::External>(reinterpret_cast<void *>(setter)));
02103   }
02104 
02105   if (query) {
02106     obj->SetInternalField(
02107         imp::kIndexPropertyQueryIndex
02108       , New<v8::External>(reinterpret_cast<void *>(query)));
02109   }
02110 
02111   if (deleter) {
02112     obj->SetInternalField(
02113         imp::kIndexPropertyDeleterIndex
02114       , New<v8::External>(reinterpret_cast<void *>(deleter)));
02115   }
02116 
02117   if (enumerator) {
02118     obj->SetInternalField(
02119         imp::kIndexPropertyEnumeratorIndex
02120       , New<v8::External>(reinterpret_cast<void *>(enumerator)));
02121   }
02122 
02123   if (!data.IsEmpty()) {
02124     obj->SetInternalField(imp::kDataIndex, data);
02125   }
02126 
02127 #if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
02128   tpl->SetHandler(v8::IndexedPropertyHandlerConfiguration(
02129       getter_, setter_, query_, deleter_, enumerator_, obj));
02130 #else
02131   tpl->SetIndexedPropertyHandler(
02132       getter_
02133     , setter_
02134     , query_
02135     , deleter_
02136     , enumerator_
02137     , obj);
02138 #endif
02139 }
02140 
02141 inline void SetCallHandler(
02142     v8::Local<v8::FunctionTemplate> tpl
02143   , FunctionCallback callback
02144   , v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
02145   HandleScope scope;
02146 
02147   v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
02148   otpl->SetInternalFieldCount(imp::kFunctionFieldCount);
02149   v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
02150 
02151   obj->SetInternalField(
02152       imp::kFunctionIndex
02153     , New<v8::External>(reinterpret_cast<void *>(callback)));
02154 
02155   if (!data.IsEmpty()) {
02156     obj->SetInternalField(imp::kDataIndex, data);
02157   }
02158 
02159   tpl->SetCallHandler(imp::FunctionCallbackWrapper, obj);
02160 }
02161 
02162 
02163 inline void SetCallAsFunctionHandler(
02164     v8::Local<v8::ObjectTemplate> tpl,
02165     FunctionCallback callback,
02166     v8::Local<v8::Value> data = v8::Local<v8::Value>()) {
02167   HandleScope scope;
02168 
02169   v8::Local<v8::ObjectTemplate> otpl = New<v8::ObjectTemplate>();
02170   otpl->SetInternalFieldCount(imp::kFunctionFieldCount);
02171   v8::Local<v8::Object> obj = NewInstance(otpl).ToLocalChecked();
02172 
02173   obj->SetInternalField(
02174       imp::kFunctionIndex
02175     , New<v8::External>(reinterpret_cast<void *>(callback)));
02176 
02177   if (!data.IsEmpty()) {
02178     obj->SetInternalField(imp::kDataIndex, data);
02179   }
02180 
02181   tpl->SetCallAsFunctionHandler(imp::FunctionCallbackWrapper, obj);
02182 }
02183 
02184 //=== Weak Persistent Handling =================================================
02185 
02186 #include "nan_weak.h"  // NOLINT(build/include)
02187 
02188 //=== ObjectWrap ===============================================================
02189 
02190 #include "nan_object_wrap.h"  // NOLINT(build/include)
02191 
02192 //=== Export ==================================================================
02193 
02194 inline
02195 void
02196 Export(ADDON_REGISTER_FUNCTION_ARGS_TYPE target, const char *name,
02197     FunctionCallback f) {
02198   Set(target, New<v8::String>(name).ToLocalChecked(),
02199       GetFunction(New<v8::FunctionTemplate>(f)).ToLocalChecked());
02200 }
02201 
02202 //=== Tap Reverse Binding =====================================================
02203 
02204 struct Tap {
02205   explicit Tap(v8::Local<v8::Value> t) : t_() {
02206     t_.Reset(To<v8::Object>(t).ToLocalChecked());
02207   }
02208 
02209   ~Tap() { t_.Reset(); }  // not sure if neccessary
02210 
02211   inline void plan(int i) {
02212     v8::Local<v8::Value> arg = New(i);
02213     MakeCallback(New(t_), "plan", 1, &arg);
02214   }
02215 
02216   inline void ok(bool isOk, const char *msg = NULL) {
02217     v8::Local<v8::Value> args[2];
02218     args[0] = New(isOk);
02219     if (msg) args[1] = New(msg).ToLocalChecked();
02220     MakeCallback(New(t_), "ok", msg ? 2 : 1, args);
02221   }
02222 
02223   inline void pass(const char * msg = NULL) {
02224     v8::Local<v8::Value> hmsg;
02225     if (msg) hmsg = New(msg).ToLocalChecked();
02226     MakeCallback(New(t_), "pass", msg ? 1 : 0, &hmsg);
02227   }
02228 
02229  private:
02230   Persistent<v8::Object> t_;
02231 };
02232 
02233 #define NAN_STRINGIZE2(x) #x
02234 #define NAN_STRINGIZE(x) NAN_STRINGIZE2(x)
02235 #define NAN_TEST_EXPRESSION(expression) \
02236   ( expression ), __FILE__ ":" NAN_STRINGIZE(__LINE__) ": " #expression
02237 
02238 #define NAN_EXPORT(target, function) Export(target, #function, function)
02239 
02240 #undef TYPE_CHECK
02241 
02242 //=== Generic Maybefication ===================================================
02243 
02244 namespace imp {
02245 
02246 template <typename T> struct Maybefier;
02247 
02248 template <typename T> struct Maybefier<v8::Local<T> > {
02249   static MaybeLocal<T> convert(v8::Local<T> v) {
02250     return MaybeLocal<T>(v);
02251   }
02252 };
02253 
02254 template <typename T> struct Maybefier<MaybeLocal<T> > {
02255   static MaybeLocal<T> convert(MaybeLocal<T> v) {
02256     return v;
02257   }
02258 };
02259 
02260 }  // end of namespace imp
02261 
02262 template <typename T, template <typename> class MaybeMaybe>
02263 MaybeLocal<T>
02264 MakeMaybe(MaybeMaybe<T> v) {
02265   return imp::Maybefier<MaybeMaybe<T> >::convert(v);
02266 }
02267 
02268 //=== TypedArrayContents =======================================================
02269 
02270 #include "nan_typedarray_contents.h"  // NOLINT(build/include)
02271 
02272 }  // end of namespace Nan
02273 
02274 #endif  // NAN_H_


dji_ronin
Author(s):
autogenerated on Sat Jun 8 2019 20:15:31