PageRenderTime 144ms CodeModel.GetById 16ms app.highlight 116ms RepoModel.GetById 1ms app.codeStats 1ms

/node_modules/nan/nan.h

https://bitbucket.org/coleman333/smartsite
C Header | 2276 lines | 1858 code | 351 blank | 67 comment | 112 complexity | 9bcfcae8fb1e8dbc12a0ba1f743edced MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*********************************************************************
   2 * NAN - Native Abstractions for Node.js
   3 *
   4 * Copyright (c) 2016 NAN contributors:
   5 *   - Rod Vagg <https://github.com/rvagg>
   6 *   - Benjamin Byholm <https://github.com/kkoopa>
   7 *   - Trevor Norris <https://github.com/trevnorris>
   8 *   - Nathan Rajlich <https://github.com/TooTallNate>
   9 *   - Brett Lawson <https://github.com/brett19>
  10 *   - Ben Noordhuis <https://github.com/bnoordhuis>
  11 *   - David Siegel <https://github.com/agnat>
  12 *
  13 * MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
  14 *
  15 * Version 2.3.5: current Node 6.2.0, Node 12: 0.12.14, Node 10: 0.10.45, iojs: 3.3.1
  16 *
  17 * See https://github.com/nodejs/nan for the latest update to this file
  18 **********************************************************************************/
  19
  20#ifndef NAN_H_
  21#define NAN_H_
  22
  23#include <node_version.h>
  24
  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
  35
  36#ifdef _MSC_VER
  37# define NAN_HAS_CPLUSPLUS_11 (_MSC_VER >= 1800)
  38#else
  39# define NAN_HAS_CPLUSPLUS_11 (__cplusplus >= 201103L)
  40#endif
  41
  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
  44#endif
  45
  46#include <uv.h>
  47#include <node.h>
  48#include <node_buffer.h>
  49#include <node_object_wrap.h>
  50#include <algorithm>
  51#include <cstring>
  52#include <climits>
  53#include <cstdlib>
  54#if defined(_MSC_VER)
  55# pragma warning( push )
  56# pragma warning( disable : 4530 )
  57# include <string>
  58# include <vector>
  59# pragma warning( pop )
  60#else
  61# include <string>
  62# include <vector>
  63#endif
  64
  65// uv helpers
  66#ifdef UV_VERSION_MAJOR
  67# ifndef UV_VERSION_PATCH
  68#  define UV_VERSION_PATCH 0
  69# endif
  70# define NAUV_UVVERSION ((UV_VERSION_MAJOR << 16) | \
  71                         (UV_VERSION_MINOR <<  8) | \
  72                         (UV_VERSION_PATCH))
  73#else
  74# define NAUV_UVVERSION 0x000b00
  75#endif
  76
  77#if NAUV_UVVERSION < 0x000b0b
  78# ifdef WIN32
  79#  include <windows.h>
  80# else
  81#  include <pthread.h>
  82# endif
  83#endif
  84
  85namespace Nan {
  86
  87#define NAN_INLINE inline  // TODO(bnoordhuis) Remove in v3.0.0.
  88
  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)
  95#else
  96# define NAN_DEPRECATED
  97#endif
  98
  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;
 105#else
 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)
 109#endif
 110
 111#define NAN_DISALLOW_ASSIGN_COPY(CLASS)                                        \
 112    NAN_DISALLOW_ASSIGN(CLASS)                                                 \
 113    NAN_DISALLOW_COPY(CLASS)
 114
 115#define NAN_DISALLOW_ASSIGN_MOVE(CLASS)                                        \
 116    NAN_DISALLOW_ASSIGN(CLASS)                                                 \
 117    NAN_DISALLOW_MOVE(CLASS)
 118
 119#define NAN_DISALLOW_COPY_MOVE(CLASS)                                          \
 120    NAN_DISALLOW_COPY(CLASS)                                                   \
 121    NAN_DISALLOW_MOVE(CLASS)
 122
 123#define NAN_DISALLOW_ASSIGN_COPY_MOVE(CLASS)                                   \
 124    NAN_DISALLOW_ASSIGN(CLASS)                                                 \
 125    NAN_DISALLOW_COPY(CLASS)                                                   \
 126    NAN_DISALLOW_MOVE(CLASS)
 127
 128#define TYPE_CHECK(T, S)                                                       \
 129    while (false) {                                                            \
 130      *(static_cast<T *volatile *>(0)) = static_cast<S*>(0);                   \
 131    }
 132
 133//=== RegistrationFunction =====================================================
 134
 135#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 136  typedef v8::Handle<v8::Object> ADDON_REGISTER_FUNCTION_ARGS_TYPE;
 137#else
 138  typedef v8::Local<v8::Object> ADDON_REGISTER_FUNCTION_ARGS_TYPE;
 139#endif
 140
 141#define NAN_MODULE_INIT(name)                                                  \
 142    void name(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target)
 143
 144//=== CallbackInfo =============================================================
 145
 146#include "nan_callbacks.h"  // NOLINT(build/include)
 147
 148//==============================================================================
 149
 150#if (NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION)
 151typedef v8::Script             UnboundScript;
 152typedef v8::Script             BoundScript;
 153#else
 154typedef v8::UnboundScript      UnboundScript;
 155typedef v8::Script             BoundScript;
 156#endif
 157
 158#if (NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION)
 159typedef v8::String::ExternalAsciiStringResource
 160    ExternalOneByteStringResource;
 161#else
 162typedef v8::String::ExternalOneByteStringResource
 163    ExternalOneByteStringResource;
 164#endif
 165
 166#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
 167template<typename T>
 168class NonCopyablePersistentTraits :
 169    public v8::NonCopyablePersistentTraits<T> {};
 170template<typename T>
 171class CopyablePersistentTraits :
 172    public v8::CopyablePersistentTraits<T> {};
 173
 174template<typename T>
 175class PersistentBase :
 176    public v8::PersistentBase<T> {};
 177
 178template<typename T, typename M = v8::NonCopyablePersistentTraits<T> >
 179class Persistent;
 180#else
 181template<typename T> class NonCopyablePersistentTraits;
 182template<typename T> class PersistentBase;
 183template<typename T, typename P> class WeakCallbackData;
 184template<typename T, typename M = NonCopyablePersistentTraits<T> >
 185class Persistent;
 186#endif  // NODE_MODULE_VERSION
 187
 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)
 191#else
 192# include "nan_maybe_pre_43_inl.h"  // NOLINT(build/include)
 193#endif
 194
 195#include "nan_converters.h"  // NOLINT(build/include)
 196#include "nan_new.h"  // NOLINT(build/include)
 197
 198#if NAUV_UVVERSION < 0x000b17
 199#define NAUV_WORK_CB(func) \
 200    void func(uv_async_t *async, int)
 201#else
 202#define NAUV_WORK_CB(func) \
 203    void func(uv_async_t *async)
 204#endif
 205
 206#if NAUV_UVVERSION >= 0x000b0b
 207
 208typedef uv_key_t nauv_key_t;
 209
 210inline int nauv_key_create(nauv_key_t *key) {
 211  return uv_key_create(key);
 212}
 213
 214inline void nauv_key_delete(nauv_key_t *key) {
 215  uv_key_delete(key);
 216}
 217
 218inline void* nauv_key_get(nauv_key_t *key) {
 219  return uv_key_get(key);
 220}
 221
 222inline void nauv_key_set(nauv_key_t *key, void *value) {
 223  uv_key_set(key, value);
 224}
 225
 226#else
 227
 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.
 231 */
 232
 233#ifndef WIN32
 234
 235typedef pthread_key_t nauv_key_t;
 236
 237inline int nauv_key_create(nauv_key_t* key) {
 238  return -pthread_key_create(key, NULL);
 239}
 240
 241inline void nauv_key_delete(nauv_key_t* key) {
 242  if (pthread_key_delete(*key))
 243    abort();
 244}
 245
 246inline void* nauv_key_get(nauv_key_t* key) {
 247  return pthread_getspecific(*key);
 248}
 249
 250inline void nauv_key_set(nauv_key_t* key, void* value) {
 251  if (pthread_setspecific(*key, value))
 252    abort();
 253}
 254
 255#else
 256
 257typedef struct {
 258  DWORD tls_index;
 259} nauv_key_t;
 260
 261inline int nauv_key_create(nauv_key_t* key) {
 262  key->tls_index = TlsAlloc();
 263  if (key->tls_index == TLS_OUT_OF_INDEXES)
 264    return UV_ENOMEM;
 265  return 0;
 266}
 267
 268inline void nauv_key_delete(nauv_key_t* key) {
 269  if (TlsFree(key->tls_index) == FALSE)
 270    abort();
 271  key->tls_index = TLS_OUT_OF_INDEXES;
 272}
 273
 274inline void* nauv_key_get(nauv_key_t* key) {
 275  void* value = TlsGetValue(key->tls_index);
 276  if (value == NULL)
 277    if (GetLastError() != ERROR_SUCCESS)
 278      abort();
 279  return value;
 280}
 281
 282inline void nauv_key_set(nauv_key_t* key, void* value) {
 283  if (TlsSetValue(key->tls_index, value) == FALSE)
 284    abort();
 285}
 286
 287#endif
 288#endif
 289
 290#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 291template<typename T>
 292v8::Local<T> New(v8::Handle<T>);
 293#endif
 294
 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;
 298#else
 299struct WeakCallbackType {
 300  enum E {kParameter, kInternalFields};
 301  E type;
 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); }
 305};
 306#endif
 307
 308template<typename P> class WeakCallbackInfo;
 309
 310#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
 311# include "nan_persistent_12_inl.h"  // NOLINT(build/include)
 312#else
 313# include "nan_persistent_pre_12_inl.h"  // NOLINT(build/include)
 314#endif
 315
 316namespace imp {
 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;
 325#else
 326  static const unsigned kReplaceInvalidUtf8 = 0;
 327#endif
 328}  // end of namespace imp
 329
 330//=== HandleScope ==============================================================
 331
 332class HandleScope {
 333  v8::HandleScope scope;
 334
 335 public:
 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());
 340  }
 341#else
 342  inline HandleScope() : scope() {}
 343  inline static int NumberOfHandles() {
 344    return v8::HandleScope::NumberOfHandles();
 345  }
 346#endif
 347
 348 private:
 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);
 355};
 356
 357class EscapableHandleScope {
 358 public:
 359#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
 360  inline EscapableHandleScope() : scope(v8::Isolate::GetCurrent()) {}
 361
 362  inline static int NumberOfHandles() {
 363    return v8::EscapableHandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
 364  }
 365
 366  template<typename T>
 367  inline v8::Local<T> Escape(v8::Local<T> value) {
 368    return scope.Escape(value);
 369  }
 370
 371 private:
 372  v8::EscapableHandleScope scope;
 373#else
 374  inline EscapableHandleScope() : scope() {}
 375
 376  inline static int NumberOfHandles() {
 377    return v8::HandleScope::NumberOfHandles();
 378  }
 379
 380  template<typename T>
 381  inline v8::Local<T> Escape(v8::Local<T> value) {
 382    return scope.Close(value);
 383  }
 384
 385 private:
 386  v8::HandleScope scope;
 387#endif
 388
 389 private:
 390  // Make it hard to create heap-allocated or illegal handle scopes by
 391  // disallowing certain operations.
 392  EscapableHandleScope(const EscapableHandleScope &);
 393  void operator=(const EscapableHandleScope &);
 394  void *operator new(size_t size);
 395  void operator delete(void *, size_t);
 396};
 397
 398//=== TryCatch =================================================================
 399
 400class TryCatch {
 401  v8::TryCatch try_catch_;
 402  friend void FatalException(const TryCatch&);
 403
 404 public:
 405#if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
 406  TryCatch() : try_catch_(v8::Isolate::GetCurrent()) {}
 407#endif
 408
 409  inline bool HasCaught() const { return try_catch_.HasCaught(); }
 410
 411  inline bool CanContinue() const { return try_catch_.CanContinue(); }
 412
 413  inline v8::Local<v8::Value> ReThrow() {
 414#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 415    return New(try_catch_.ReThrow());
 416#else
 417    return try_catch_.ReThrow();
 418#endif
 419  }
 420
 421  inline v8::Local<v8::Value> Exception() const {
 422    return try_catch_.Exception();
 423  }
 424
 425#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
 426  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
 427  inline v8::MaybeLocal<v8::Value> StackTrace() const {
 428    return try_catch_.StackTrace(GetCurrentContext());
 429  }
 430#else
 431  inline MaybeLocal<v8::Value> StackTrace() const {
 432    return MaybeLocal<v8::Value>(try_catch_.StackTrace());
 433  }
 434#endif
 435
 436  inline v8::Local<v8::Message> Message() const {
 437    return try_catch_.Message();
 438  }
 439
 440  inline void Reset() { try_catch_.Reset(); }
 441
 442  inline void SetVerbose(bool value) { try_catch_.SetVerbose(value); }
 443
 444  inline void SetCaptureMessage(bool value) {
 445    try_catch_.SetCaptureMessage(value);
 446  }
 447};
 448
 449//============ =================================================================
 450
 451/* node 0.12  */
 452#if NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION
 453  inline
 454  void SetCounterFunction(v8::CounterLookupCallback cb) {
 455    v8::Isolate::GetCurrent()->SetCounterFunction(cb);
 456  }
 457
 458  inline
 459  void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
 460    v8::Isolate::GetCurrent()->SetCreateHistogramFunction(cb);
 461  }
 462
 463  inline
 464  void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
 465    v8::Isolate::GetCurrent()->SetAddHistogramSampleFunction(cb);
 466  }
 467
 468#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
 469  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
 470  inline bool IdleNotification(int idle_time_in_ms) {
 471    return v8::Isolate::GetCurrent()->IdleNotificationDeadline(
 472        idle_time_in_ms * 0.001);
 473  }
 474# else
 475  inline bool IdleNotification(int idle_time_in_ms) {
 476    return v8::Isolate::GetCurrent()->IdleNotification(idle_time_in_ms);
 477  }
 478#endif
 479
 480  inline void LowMemoryNotification() {
 481    v8::Isolate::GetCurrent()->LowMemoryNotification();
 482  }
 483
 484  inline void ContextDisposedNotification() {
 485    v8::Isolate::GetCurrent()->ContextDisposedNotification();
 486  }
 487#else
 488  inline
 489  void SetCounterFunction(v8::CounterLookupCallback cb) {
 490    v8::V8::SetCounterFunction(cb);
 491  }
 492
 493  inline
 494  void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
 495    v8::V8::SetCreateHistogramFunction(cb);
 496  }
 497
 498  inline
 499  void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
 500    v8::V8::SetAddHistogramSampleFunction(cb);
 501  }
 502
 503  inline bool IdleNotification(int idle_time_in_ms) {
 504    return v8::V8::IdleNotification(idle_time_in_ms);
 505  }
 506
 507  inline void LowMemoryNotification() {
 508    v8::V8::LowMemoryNotification();
 509  }
 510
 511  inline void ContextDisposedNotification() {
 512    v8::V8::ContextDisposedNotification();
 513  }
 514#endif
 515
 516#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)  // Node 0.12
 517  inline v8::Local<v8::Primitive> Undefined() {
 518# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 519    EscapableHandleScope scope;
 520    return scope.Escape(New(v8::Undefined(v8::Isolate::GetCurrent())));
 521# else
 522    return v8::Undefined(v8::Isolate::GetCurrent());
 523# endif
 524  }
 525
 526  inline v8::Local<v8::Primitive> Null() {
 527# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 528    EscapableHandleScope scope;
 529    return scope.Escape(New(v8::Null(v8::Isolate::GetCurrent())));
 530# else
 531    return v8::Null(v8::Isolate::GetCurrent());
 532# endif
 533  }
 534
 535  inline v8::Local<v8::Boolean> True() {
 536# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 537    EscapableHandleScope scope;
 538    return scope.Escape(New(v8::True(v8::Isolate::GetCurrent())));
 539# else
 540    return v8::True(v8::Isolate::GetCurrent());
 541# endif
 542  }
 543
 544  inline v8::Local<v8::Boolean> False() {
 545# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 546    EscapableHandleScope scope;
 547    return scope.Escape(New(v8::False(v8::Isolate::GetCurrent())));
 548# else
 549    return v8::False(v8::Isolate::GetCurrent());
 550# endif
 551  }
 552
 553  inline v8::Local<v8::String> EmptyString() {
 554    return v8::String::Empty(v8::Isolate::GetCurrent());
 555  }
 556
 557  inline int AdjustExternalMemory(int bc) {
 558    return static_cast<int>(
 559        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
 560  }
 561
 562  inline void SetTemplate(
 563      v8::Local<v8::Template> templ
 564    , const char *name
 565    , v8::Local<v8::Data> value) {
 566    templ->Set(v8::Isolate::GetCurrent(), name, value);
 567  }
 568
 569  inline void SetTemplate(
 570      v8::Local<v8::Template> templ
 571    , v8::Local<v8::String> name
 572    , v8::Local<v8::Data> value
 573    , v8::PropertyAttribute attributes) {
 574    templ->Set(name, value, attributes);
 575  }
 576
 577  inline v8::Local<v8::Context> GetCurrentContext() {
 578    return v8::Isolate::GetCurrent()->GetCurrentContext();
 579  }
 580
 581  inline void* GetInternalFieldPointer(
 582      v8::Local<v8::Object> object
 583    , int index) {
 584    return object->GetAlignedPointerFromInternalField(index);
 585  }
 586
 587  inline void SetInternalFieldPointer(
 588      v8::Local<v8::Object> object
 589    , int index
 590    , void* value) {
 591    object->SetAlignedPointerInInternalField(index, value);
 592  }
 593
 594# define NAN_GC_CALLBACK(name)                                                 \
 595    void name(v8::Isolate *isolate, v8::GCType type, v8::GCCallbackFlags flags)
 596
 597#if NODE_MODULE_VERSION <= NODE_4_0_MODULE_VERSION
 598  typedef v8::Isolate::GCEpilogueCallback GCEpilogueCallback;
 599  typedef v8::Isolate::GCPrologueCallback GCPrologueCallback;
 600#else
 601  typedef v8::Isolate::GCCallback GCEpilogueCallback;
 602  typedef v8::Isolate::GCCallback GCPrologueCallback;
 603#endif
 604
 605  inline void AddGCEpilogueCallback(
 606      GCEpilogueCallback callback
 607    , v8::GCType gc_type_filter = v8::kGCTypeAll) {
 608    v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);
 609  }
 610
 611  inline void RemoveGCEpilogueCallback(
 612      GCEpilogueCallback callback) {
 613    v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);
 614  }
 615
 616  inline void AddGCPrologueCallback(
 617      GCPrologueCallback callback
 618    , v8::GCType gc_type_filter = v8::kGCTypeAll) {
 619    v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);
 620  }
 621
 622  inline void RemoveGCPrologueCallback(
 623      GCPrologueCallback callback) {
 624    v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);
 625  }
 626
 627  inline void GetHeapStatistics(
 628      v8::HeapStatistics *heap_statistics) {
 629    v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);
 630  }
 631
 632# define X(NAME)                                                               \
 633    inline v8::Local<v8::Value> NAME(const char *msg) {                    \
 634      EscapableHandleScope scope;                                              \
 635      return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked()));     \
 636    }                                                                          \
 637                                                                               \
 638    inline                                                                 \
 639    v8::Local<v8::Value> NAME(v8::Local<v8::String> msg) {                     \
 640      return v8::Exception::NAME(msg);                                         \
 641    }                                                                          \
 642                                                                               \
 643    inline void Throw ## NAME(const char *msg) {                           \
 644      HandleScope scope;                                                       \
 645      v8::Isolate::GetCurrent()->ThrowException(                               \
 646          v8::Exception::NAME(New(msg).ToLocalChecked()));                     \
 647    }                                                                          \
 648                                                                               \
 649    inline void Throw ## NAME(v8::Local<v8::String> msg) {                 \
 650      HandleScope scope;                                                       \
 651      v8::Isolate::GetCurrent()->ThrowException(                               \
 652          v8::Exception::NAME(msg));                                           \
 653    }
 654
 655  X(Error)
 656  X(RangeError)
 657  X(ReferenceError)
 658  X(SyntaxError)
 659  X(TypeError)
 660
 661# undef X
 662
 663  inline void ThrowError(v8::Local<v8::Value> error) {
 664    v8::Isolate::GetCurrent()->ThrowException(error);
 665  }
 666
 667  inline MaybeLocal<v8::Object> NewBuffer(
 668      char *data
 669    , size_t length
 670#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
 671    , node::Buffer::FreeCallback callback
 672#else
 673    , node::smalloc::FreeCallback callback
 674#endif
 675    , void *hint
 676  ) {
 677    // arbitrary buffer lengths requires
 678    // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
 679    assert(length <= imp::kMaxLength && "too large buffer");
 680#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
 681    return node::Buffer::New(
 682        v8::Isolate::GetCurrent(), data, length, callback, hint);
 683#else
 684    return MaybeLocal<v8::Object>(node::Buffer::New(
 685        v8::Isolate::GetCurrent(), data, length, callback, hint));
 686#endif
 687  }
 688
 689  inline MaybeLocal<v8::Object> CopyBuffer(
 690      const char *data
 691    , uint32_t size
 692  ) {
 693    // arbitrary buffer lengths requires
 694    // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
 695    assert(size <= imp::kMaxLength && "too large buffer");
 696#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
 697    return node::Buffer::Copy(
 698        v8::Isolate::GetCurrent(), data, size);
 699#else
 700    return MaybeLocal<v8::Object>(node::Buffer::New(
 701        v8::Isolate::GetCurrent(), data, size));
 702#endif
 703  }
 704
 705  inline MaybeLocal<v8::Object> NewBuffer(uint32_t size) {
 706    // arbitrary buffer lengths requires
 707    // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
 708    assert(size <= imp::kMaxLength && "too large buffer");
 709#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
 710    return node::Buffer::New(
 711        v8::Isolate::GetCurrent(), size);
 712#else
 713    return MaybeLocal<v8::Object>(node::Buffer::New(
 714        v8::Isolate::GetCurrent(), size));
 715#endif
 716  }
 717
 718  inline MaybeLocal<v8::Object> NewBuffer(
 719      char* data
 720    , uint32_t size
 721  ) {
 722    // arbitrary buffer lengths requires
 723    // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
 724    assert(size <= imp::kMaxLength && "too large buffer");
 725#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
 726    return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
 727#else
 728    return MaybeLocal<v8::Object>(
 729        node::Buffer::Use(v8::Isolate::GetCurrent(), data, size));
 730#endif
 731  }
 732
 733#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 ||                      \
 734  (V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
 735  inline MaybeLocal<v8::String>
 736  NewOneByteString(const uint8_t * value, int length = -1) {
 737    return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), value,
 738          v8::NewStringType::kNormal, length);
 739  }
 740
 741  inline MaybeLocal<BoundScript> CompileScript(
 742      v8::Local<v8::String> s
 743    , const v8::ScriptOrigin& origin
 744  ) {
 745    v8::ScriptCompiler::Source source(s, origin);
 746    return v8::ScriptCompiler::Compile(GetCurrentContext(), &source);
 747  }
 748
 749  inline MaybeLocal<BoundScript> CompileScript(
 750      v8::Local<v8::String> s
 751  ) {
 752    v8::ScriptCompiler::Source source(s);
 753    return v8::ScriptCompiler::Compile(GetCurrentContext(), &source);
 754  }
 755
 756  inline MaybeLocal<v8::Value> RunScript(
 757      v8::Local<UnboundScript> script
 758  ) {
 759    return script->BindToCurrentContext()->Run(GetCurrentContext());
 760  }
 761
 762  inline MaybeLocal<v8::Value> RunScript(
 763      v8::Local<BoundScript> script
 764  ) {
 765    return script->Run(GetCurrentContext());
 766  }
 767#else
 768  inline MaybeLocal<v8::String>
 769  NewOneByteString(const uint8_t * value, int length = -1) {
 770    return MaybeLocal<v8::String>(
 771        v8::String::NewFromOneByte(
 772            v8::Isolate::GetCurrent()
 773          , value
 774          , v8::String::kNormalString, length));
 775  }
 776
 777  inline MaybeLocal<BoundScript> CompileScript(
 778      v8::Local<v8::String> s
 779    , const v8::ScriptOrigin& origin
 780  ) {
 781    v8::ScriptCompiler::Source source(s, origin);
 782    return MaybeLocal<BoundScript>(
 783        v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source));
 784  }
 785
 786  inline MaybeLocal<BoundScript> CompileScript(
 787      v8::Local<v8::String> s
 788  ) {
 789    v8::ScriptCompiler::Source source(s);
 790    return MaybeLocal<BoundScript>(
 791        v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source));
 792  }
 793
 794  inline MaybeLocal<v8::Value> RunScript(
 795      v8::Local<UnboundScript> script
 796  ) {
 797    return MaybeLocal<v8::Value>(script->BindToCurrentContext()->Run());
 798  }
 799
 800  inline MaybeLocal<v8::Value> RunScript(
 801      v8::Local<BoundScript> script
 802  ) {
 803    return MaybeLocal<v8::Value>(script->Run());
 804  }
 805#endif
 806
 807  inline v8::Local<v8::Value> MakeCallback(
 808      v8::Local<v8::Object> target
 809    , v8::Local<v8::Function> func
 810    , int argc
 811    , v8::Local<v8::Value>* argv) {
 812#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 813    return New(node::MakeCallback(
 814        v8::Isolate::GetCurrent(), target, func, argc, argv));
 815#else
 816    return node::MakeCallback(
 817        v8::Isolate::GetCurrent(), target, func, argc, argv);
 818#endif
 819  }
 820
 821  inline v8::Local<v8::Value> MakeCallback(
 822      v8::Local<v8::Object> target
 823    , v8::Local<v8::String> symbol
 824    , int argc
 825    , v8::Local<v8::Value>* argv) {
 826#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 827    return New(node::MakeCallback(
 828        v8::Isolate::GetCurrent(), target, symbol, argc, argv));
 829#else
 830    return node::MakeCallback(
 831        v8::Isolate::GetCurrent(), target, symbol, argc, argv);
 832#endif
 833  }
 834
 835  inline v8::Local<v8::Value> MakeCallback(
 836      v8::Local<v8::Object> target
 837    , const char* method
 838    , int argc
 839    , v8::Local<v8::Value>* argv) {
 840#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
 841    return New(node::MakeCallback(
 842        v8::Isolate::GetCurrent(), target, method, argc, argv));
 843#else
 844    return node::MakeCallback(
 845        v8::Isolate::GetCurrent(), target, method, argc, argv);
 846#endif
 847  }
 848
 849  inline void FatalException(const TryCatch& try_catch) {
 850    node::FatalException(v8::Isolate::GetCurrent(), try_catch.try_catch_);
 851  }
 852
 853  inline v8::Local<v8::Value> ErrnoException(
 854          int errorno
 855       ,  const char* syscall = NULL
 856       ,  const char* message = NULL
 857       ,  const char* path = NULL) {
 858    return node::ErrnoException(v8::Isolate::GetCurrent(), errorno, syscall,
 859            message, path);
 860  }
 861
 862  NAN_DEPRECATED inline v8::Local<v8::Value> NanErrnoException(
 863          int errorno
 864       ,  const char* syscall = NULL
 865       ,  const char* message = NULL
 866       ,  const char* path = NULL) {
 867    return ErrnoException(errorno, syscall, message, path);
 868  }
 869
 870  template<typename T>
 871  inline void SetIsolateData(
 872      v8::Isolate *isolate
 873    , T *data
 874  ) {
 875      isolate->SetData(0, data);
 876  }
 877
 878  template<typename T>
 879  inline T *GetIsolateData(
 880      v8::Isolate *isolate
 881  ) {
 882      return static_cast<T*>(isolate->GetData(0));
 883  }
 884
 885class Utf8String {
 886 public:
 887  inline explicit Utf8String(v8::Local<v8::Value> from) :
 888      length_(0), str_(str_st_) {
 889    if (!from.IsEmpty()) {
 890      v8::Local<v8::String> string = from->ToString();
 891      if (!string.IsEmpty()) {
 892        size_t len = 3 * string->Length() + 1;
 893        assert(len <= INT_MAX);
 894        if (len > sizeof (str_st_)) {
 895          str_ = static_cast<char*>(malloc(len));
 896          assert(str_ != 0);
 897        }
 898        const int flags =
 899            v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
 900        length_ = string->WriteUtf8(str_, static_cast<int>(len), 0, flags);
 901        str_[length_] = '\0';
 902      }
 903    }
 904  }
 905
 906  inline int length() const {
 907    return length_;
 908  }
 909
 910  inline char* operator*() { return str_; }
 911  inline const char* operator*() const { return str_; }
 912
 913  inline ~Utf8String() {
 914    if (str_ != str_st_) {
 915      free(str_);
 916    }
 917  }
 918
 919 private:
 920  NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
 921
 922  int length_;
 923  char *str_;
 924  char str_st_[1024];
 925};
 926
 927#else  // Node 0.8 and 0.10
 928  inline v8::Local<v8::Primitive> Undefined() {
 929    EscapableHandleScope scope;
 930    return scope.Escape(New(v8::Undefined()));
 931  }
 932
 933  inline v8::Local<v8::Primitive> Null() {
 934    EscapableHandleScope scope;
 935    return scope.Escape(New(v8::Null()));
 936  }
 937
 938  inline v8::Local<v8::Boolean> True() {
 939    EscapableHandleScope scope;
 940    return scope.Escape(New(v8::True()));
 941  }
 942
 943  inline v8::Local<v8::Boolean> False() {
 944    EscapableHandleScope scope;
 945    return scope.Escape(New(v8::False()));
 946  }
 947
 948  inline v8::Local<v8::String> EmptyString() {
 949    return v8::String::Empty();
 950  }
 951
 952  inline int AdjustExternalMemory(int bc) {
 953    return static_cast<int>(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
 954  }
 955
 956  inline void SetTemplate(
 957      v8::Local<v8::Template> templ
 958    , const char *name
 959    , v8::Local<v8::Data> value) {
 960    templ->Set(name, value);
 961  }
 962
 963  inline void SetTemplate(
 964      v8::Local<v8::Template> templ
 965    , v8::Local<v8::String> name
 966    , v8::Local<v8::Data> value
 967    , v8::PropertyAttribute attributes) {
 968    templ->Set(name, value, attributes);
 969  }
 970
 971  inline v8::Local<v8::Context> GetCurrentContext() {
 972    return v8::Context::GetCurrent();
 973  }
 974
 975  inline void* GetInternalFieldPointer(
 976      v8::Local<v8::Object> object
 977    , int index) {
 978    return object->GetPointerFromInternalField(index);
 979  }
 980
 981  inline void SetInternalFieldPointer(
 982      v8::Local<v8::Object> object
 983    , int index
 984    , void* value) {
 985    object->SetPointerInInternalField(index, value);
 986  }
 987
 988# define NAN_GC_CALLBACK(name)                                                 \
 989    void name(v8::GCType type, v8::GCCallbackFlags flags)
 990
 991  inline void AddGCEpilogueCallback(
 992    v8::GCEpilogueCallback callback
 993  , v8::GCType gc_type_filter = v8::kGCTypeAll) {
 994    v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);
 995  }
 996  inline void RemoveGCEpilogueCallback(
 997    v8::GCEpilogueCallback callback) {
 998    v8::V8::RemoveGCEpilogueCallback(callback);
 999  }
1000  inline void AddGCPrologueCallback(
1001    v8::GCPrologueCallback callback
1002  , v8::GCType gc_type_filter = v8::kGCTypeAll) {
1003    v8::V8::AddGCPrologueCallback(callback, gc_type_filter);
1004  }
1005  inline void RemoveGCPrologueCallback(
1006    v8::GCPrologueCallback callback) {
1007    v8::V8::RemoveGCPrologueCallback(callback);
1008  }
1009  inline void GetHeapStatistics(
1010    v8::HeapStatistics *heap_statistics) {
1011    v8::V8::GetHeapStatistics(heap_statistics);
1012  }
1013
1014# define X(NAME)                                                               \
1015    inline v8::Local<v8::Value> NAME(const char *msg) {                    \
1016      EscapableHandleScope scope;                                              \
1017      return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked()));     \
1018    }                                                                          \
1019                                                                               \
1020    inline                                                                 \
1021    v8::Local<v8::Value> NAME(v8::Local<v8::String> msg) {                     \
1022      return v8::Exception::NAME(msg);                                         \
1023    }                                                                          \
1024                                                                               \
1025    inline void Throw ## NAME(const char *msg) {                           \
1026      HandleScope scope;                                                       \
1027      v8::ThrowException(v8::Exception::NAME(New(msg).ToLocalChecked()));      \
1028    }                                                                          \
1029                                                                               \
1030    inline                                                                 \
1031    void Throw ## NAME(v8::Local<v8::String> errmsg) {                         \
1032      v8::ThrowException(v8::Exception::NAME(errmsg));                         \
1033    }
1034
1035  X(Error)
1036  X(RangeError)
1037  X(ReferenceError)
1038  X(SyntaxError)
1039  X(TypeError)
1040
1041# undef X
1042
1043  inline void ThrowError(v8::Local<v8::Value> error) {
1044    v8::ThrowException(error);
1045  }
1046
1047  inline MaybeLocal<v8::Object> NewBuffer(
1048      char *data
1049    , size_t length
1050    , node::Buffer::free_callback callback
1051    , void *hint
1052  ) {
1053    EscapableHandleScope scope;
1054    // arbitrary buffer lengths requires
1055    // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1056    assert(length <= imp::kMaxLength && "too large buffer");
1057    return MaybeLocal<v8::Object>(scope.Escape(
1058        New(node::Buffer::New(data, length, callback, hint)->handle_)));
1059  }
1060
1061  inline MaybeLocal<v8::Object> CopyBuffer(
1062      const char *data
1063    , uint32_t size
1064  ) {
1065    EscapableHandleScope scope;
1066    // arbitrary buffer lengths requires
1067    // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1068    assert(size <= imp::kMaxLength && "too large buffer");
1069#if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
1070    return MaybeLocal<v8::Object>(
1071        scope.Escape(New(node::Buffer::New(data, size)->handle_)));
1072#else
1073    return MaybeLocal<v8::Object>(scope.Escape(
1074        New(node::Buffer::New(const_cast<char*>(data), size)->handle_)));
1075#endif
1076  }
1077
1078  inline MaybeLocal<v8::Object> NewBuffer(uint32_t size) {
1079    // arbitrary buffer lengths requires
1080    // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1081    EscapableHandleScope scope;
1082    assert(size <= imp::kMaxLength && "too large buffer");
1083    return MaybeLocal<v8::Object>(
1084        scope.Escape(New(node::Buffer::New(size)->handle_)));
1085  }
1086
1087  inline void FreeData(char *data, void *hint) {
1088    (void) hint;  // unused
1089    delete[] data;
1090  }
1091
1092  inline MaybeLocal<v8::Object> NewBuffer(
1093      char* data
1094    , uint32_t size
1095  ) {
1096    EscapableHandleScope scope;
1097    // arbitrary buffer lengths requires
1098    // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
1099    assert(size <= imp::kMaxLength && "too large buffer");
1100    return MaybeLocal<v8::Object>(scope.Escape(New(
1101        node::Buffer::New(data, size, FreeData, NULL)->handle_)));
1102  }
1103
1104namespace imp {
1105inline void
1106widenString(std::vector<uint16_t> *ws, const uint8_t *s, int l) {
1107  size_t len = static_cast<size_t>(l);
1108  if (l < 0) {
1109    len = strlen(reinterpret_cast<const char*>(s));
1110  }
1111  assert(len <= INT_MAX && "string too long");
1112  ws->resize(len);
1113  std::copy(s, s + len, ws->begin());  // NOLINT(build/include_what_you_use)
1114}
1115}  // end of namespace imp
1116
1117  inline MaybeLocal<v8::String>
1118  NewOneByteString(const uint8_t * value, int length = -1) {
1119    std::vector<uint16_t> wideString;  // NOLINT(build/include_what_you_use)
1120    imp::widenString(&wideString, value, length);
1121    return imp::Factory<v8::String>::return_t(v8::String::New(
1122        &wideString.front(), static_cast<int>(wideString.size())));
1123  }
1124
1125  inline MaybeLocal<BoundScript> CompileScript(
1126      v8::Local<v8::String> s
1127    , const v8::ScriptOrigin& origin
1128  ) {
1129    return MaybeLocal<BoundScript>(
1130        v8::Script::Compile(s, const_cast<v8::ScriptOrigin *>(&origin)));
1131  }
1132
1133  inline MaybeLocal<BoundScript> CompileScript(
1134    v8::Local<v8::String> s
1135  ) {
1136    return MaybeLocal<BoundScript>(v8::Script::Compile(s));
1137  }
1138
1139  inline
1140  MaybeLocal<v8::Value> RunScript(v8::Local<v8::Script> script) {
1141    return MaybeLocal<v8::Value>(script->Run());
1142  }
1143
1144  inline v8::Local<v8::Value> MakeCallback(
1145      v8::Local<v8::Object> target
1146    , v8::Local<v8::Function> func
1147    , int argc
1148    , v8::Local<v8::Value>* argv) {
1149    return New(node::MakeCallback(target, func, argc, argv));
1150  }
1151
1152  inline v8::Local<v8::Value> MakeCallback(
1153      v8::Local<v8::Object> target
1154    , v8::Local<v8::String> symbol
1155    , int argc
1156    , v8::Local<v8::Value>* argv) {
1157    return New(node::MakeCallback(target, symbol, argc, argv));
1158  }
1159
1160  inline v8::Local<v8::Value> MakeCallback(
1161      v8::Local<v8::Object> target
1162    , const char* method
1163    , int argc
1164    , v8::Local<v8::Value>* argv) {
1165    return New(node::MakeCallback(target, method, argc, argv));
1166  }
1167
1168  inline void FatalException(const TryCatch& try_catch) {
1169    node::FatalException(const_cast<v8::TryCatch &>(try_catch.try_catch_));
1170  }
1171
1172  inline v8::Local<v8::Value> ErrnoException(
1173          int errorno
1174       ,  const char* syscall = NULL
1175       ,  const char* message = NULL
1176       ,  const char* path = NULL) {
1177    return node::ErrnoException(errorno, syscall, message, path);
1178  }
1179
1180  NAN_DEPRECATED inline v8::Local<v8::Value> NanErrnoException(
1181          int errorno
1182       ,  const char* syscall = NULL
1183       ,  const char* message = NULL
1184       ,  const char* path = NULL) {
1185    return ErrnoException(errorno, syscall, message, path);
1186  }
1187
1188
1189  template<typename T>
1190  inline void SetIsolateData(
1191      v8::Isolate *isolate
1192    , T *data
1193  ) {
1194      isolate->SetData(data);
1195  }
1196
1197  template<typename T>
1198  inline T *GetIsolateData(
1199      v8::Isolate *isolate
1200  ) {
1201      return static_cast<T*>(isolate->GetData());
1202  }
1203
1204class Utf8String {
1205 public:
1206  inline explicit Utf8String(v8::Local<v8::Value> from) :
1207      length_(0), str_(str_st_) {
1208    if (!from.IsEmpty()) {
1209      v8::Local<v8::String> string = from->ToString();
1210      if (!string.IsEmpty()) {
1211        size_t len = 3 * string->Length() + 1;
1212        assert(len <= INT_MAX);
1213        if (len > sizeof (str_st_)) {
1214          str_ = static_cast<char*>(malloc(len));
1215          assert(str_ != 0);
1216        }
1217        const int flags =
1218            v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
1219        length_ = string->WriteUtf8(str_, static_cast<int>(len), 0, flags);
1220        str_[length_] = '\0';
1221      }
1222    }
1223  }
1224
1225  inline int length() const {
1226    return length_;
1227  }
1228
1229  inline char* operator*() { return str_; }
1230  inline const char* operator*() const { return str_; }
1231
1232  inline ~Utf8String() {
1233    if (str_ != str_st_) {
1234      free(str_);
1235    }
1236  }
1237
1238 private:
1239  NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
1240
1241  int length_;
1242  char *str_;
1243  char str_st_[1024];
1244};
1245
1246#endif  // NODE_MODULE_VERSION
1247
1248typedef void (*FreeCallback)(char *data, void *hint);
1249
1250typedef const FunctionCallbackInfo<v8::Value>& NAN_METHOD_ARGS_TYPE;
1251typedef void NAN_METHOD_RETURN_TYPE;
1252
1253typedef const PropertyCallbackInfo<v8::Value>& NAN_GETTER_ARGS_TYPE;
1254typedef void NAN_GETTER_RETURN_TYPE;
1255
1256typedef const PropertyCallbackInfo<void>& NAN_SETTER_ARGS_TYPE;
1257typedef void NAN_SETTER_RETURN_TYPE;
1258
1259typedef const PropertyCallbackInfo<v8::Value>&
1260    NAN_PROPERTY_GETTER_ARGS_TYPE;
1261typedef void NAN_PROPERTY_GETTER_RETURN_TYPE;
1262
1263typedef const PropertyCallbackInfo<v8::Value>&
1264    NAN_PROPERTY_SETTER_ARGS_TYPE;
1265typedef void NAN_PROPERTY_SETTER_RETURN_TYPE;
1266
1267typedef const PropertyCallbackInfo<v8::Array>&
1268    NAN_PROPERTY_ENUMERATOR_ARGS_TYPE;
1269typedef void NAN_PROPERTY_ENUMERATOR_RETURN_TYPE;
1270
1271typedef const PropertyCallbackInfo<v8::Boolean>&
1272    NAN_PROPERTY_DELETER_ARGS_TYPE;
1273typedef void NAN_PROPERTY_DELETER_RETURN_TYPE;
1274
1275typedef const PropertyCallbackInfo<v8::Integer>&
1276    NAN_PROPERTY_QUERY_ARGS_TYPE;
1277typedef void NAN_PROPERTY_QUERY_RETURN_TYPE;
1278
1279typedef const PropertyCallbackInfo<v8::Value>& NAN_INDEX_GETTER_ARGS_TYPE;
1280typedef void NAN_INDEX_GETTER_RETURN_TYPE;
1281
1282typedef const PropertyCallbackInfo<v8::Value>& NAN_INDEX_SETTER_ARGS_TYPE;
1283typedef void NAN_INDEX_SETTER_RETURN_TYPE;
1284
1285typedef const PropertyCallbackInfo<v8::Array>&
1286    NAN_INDEX_ENUMERATOR_ARGS_TYPE;
1287typedef void NAN_INDEX_ENUMERATOR_RETURN_TYPE;
1288
1289typedef const PropertyCallbackInfo<v8::Boolean>&
1290    NAN_INDEX_DELETER_ARGS_TYPE;
1291typedef void NAN_INDEX_DELETER_RETURN_TYPE;
1292
1293typedef const PropertyCallbackInfo<v8::Integer>&
1294    NAN_INDEX_QUERY_ARGS_TYPE;
1295typedef void NAN_INDEX_QUERY_RETURN_TYPE;
1296
1297#define NAN_METHOD(name)                                                       \
1298    Nan::NAN_METHOD_RETURN_TYPE name(Nan::NAN_METHOD_ARGS_TYPE info)
1299#define NAN_GETTER(name)                                                       \
1300    Nan::NAN_GETTER_RETURN_TYPE name(                                          \
1301        v8::Local<v8::String> property                                         \
1302      , Nan::NAN_GETTER_ARGS_TYPE info)
1303#define NAN_SETTER(name)                                                       \
1304    Nan::NAN_SETTER_RETURN_TYPE name(                                          \
1305        v8::Local<v8::String> property                                         \
1306      , v8::Local<v8::Value> value                                             \
1307      , Nan::NAN_SETTER_ARGS_TYPE info)
1308#define NAN_PROPERTY_GETTER(name)                                              \
1309    Nan::NAN_PROPERTY_GETTER_RETURN_TYPE name(                                 \
1310        v8::Local<v8::String> property                                         \
1311      , Nan::NAN_PROPERTY_GETTER_ARGS_TYPE info)
1312#define NAN_PROPERTY_SETTER(name)                                              \
1313    Nan::NAN_PROPERTY_SETTER_RETURN_TYPE name(                                 \
1314        v8::Local<v8::String> property                                         \
1315      , v8::Local<v8::Value> value                                             \
1316      , Nan::NAN_PROPERTY_SETTER_ARGS_TYPE info)
1317#define NAN_PROPERTY_ENUMERATOR(name)                                          \
1318    Nan::NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(                             \
1319        Nan::NAN_PROPERTY_ENUMERATOR_ARGS_TYPE info)
1320#define NAN_PROPERTY_DELETER(name)                                             \
1321    Nan::NAN_PROPERTY_DELETER_RETURN_TYPE name(                                \
1322        v8::Local<v8::String> property                                         \
1323      , Nan::NAN_PROPERTY_DELETER_ARGS_TYPE info)
1324#define NAN_PROPERTY_QUERY(name)                                               \
1325    Nan::NAN_PROPERTY_QUERY_RETURN_TYPE name(                                  \
1326        v8::Local<v8::String> property                                         \
1327      , Nan::NAN_PROPERTY_QUERY_ARGS_TYPE info)
1328# define NAN_INDEX_GETTER(name)                                                \
1329    Nan::NAN_INDEX_GETTER_RETURN_TYPE name(                                    \
1330        uint32_t index                                                         \
1331      , Nan::NAN_INDEX_GETTER_ARGS_TYPE info)
1332#define NAN_INDEX_SETTER(name)                                                 \
1333    Nan::NAN_INDEX_SETTER_RETURN_TYPE name(                                    \
1334        uint32_t index                                                         \
1335      , v8::Local<v8::Value> value                                             \
1336      , Nan::NAN_INDEX_SETTER_ARGS_TYPE info)
1337#define NAN_INDEX_ENUMERATOR(name)                                             \
1338    Nan::NAN_INDEX_ENUMERATOR_RETURN_TYPE                                      \
1339    name(Nan::NAN_INDEX_ENUMERATOR_ARGS_TYPE info)
1340#define NAN_INDEX_DELETER(name)                                                \
1341    Nan::NAN_INDEX_DELETER_RETURN_TYPE name(                                   \
1342        uint32_t index                                                         \
1343      , Nan::NAN_INDEX_DELETER_ARGS_TYPE info)
1344#define NAN_INDEX_QUERY(name)                                                  \
1345    Nan::NAN_INDEX_QUERY_RETURN_TYPE name(                                     \
1346        uint32_t index                                                         \
1347      , Nan::NAN_INDEX_QUERY_ARGS_TYPE info)
1348
1349class Callback {
1350 public:
1351  Callback() {
1352    HandleScope scope;
1353    v8::Local<v8::Object> obj = New<v8::Object>();
1354    handle.Reset(obj);
1355  }
1356
1357  explicit Callback(const v8::Local<v8::Function> &fn) {
1358    HandleScope scope;
1359    v8::Local<v8::Object> obj = New<v8::Object>();
1360    handle.Reset(obj);
1361    SetFunction(fn);
1362  }
1363
1364  ~Callback() {
1365    if (handle.IsEmpty()) return;
1366    handle.Reset();
1367  }
1368
1369  bool operator==(const Callback &other) const {
1370    HandleScope scope;
1371    v8::Local<v8::Value> a = New(handle)->Get(kCallbackIndex);
1372    v8::Local<v8::Value> b = New(other.handle)->Get(kCallbackIndex);
1373    return a->StrictEquals(b);
1374  }
1375
1376  bool operator!=(const Callback &other) const {
1377    return !this->operator==(other);
1378  }
1379
1380  inline
1381  v8::Local<v8::Function> operator*() const { return this->GetFunction(); }
1382
1383  inline v8::Local<v8::Value> operator()(
1384      v8::Local<v8::Object> target
1385    , int argc = 0
1386    , v8::Local<v8::Value> argv[] = 0) const {
1387    return this->Call(target, argc, argv);
1388  }
1389
1390  inline v8::Local<v8::Value> operator()(
1391      int argc = 0
1392    , v8::Local<v8::Value> argv[] = 0) const {
1393    return this->Call(argc, argv);
1394  }
1395
1396  inline void SetFunction(const v8::Local<v8::Function> &fn) {
1397    HandleScope scope;
1398    Set(New(handle), kCallbackIndex, fn);
1399  }
1400
1401  inline v8::Local<v8::Function> GetFunction() const {
1402    EscapableHandleScope scope;
1403    return scope.Escape(New(handle)->Get(kCallbackIndex)
1404        .As<v8::Function>());
1405  }
1406
1407  inline bool IsEmpty() const {
1408    HandleScope scope;
1409    return New(handle)->Get(kCallbackIndex)->IsUndefined();
1410  }
1411
1412  inline v8::Local<v8::Value>
1413  Call(v8::Local<v8::Object> target
1414     , int argc
1415     , v8::Local<v8::Value> argv[]) const {
1416#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1417    v8::Isolate *isolate = v8::Isolate::GetCurrent();
1418    return Call_(isolate, target, argc, argv);
1419#else
1420    return Call_(target, argc, argv);
1421#endif
1422  }
1423
1424  inline v8::Local<v8::Value>
1425  Call(int argc, v8::Local<v8::Value> argv[]) const {
1426#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1427    v8::Isolate *isolate = v8::Isolate::GetCurrent();
1428    return Call_(isolate, isolate->GetCurrentContext()->Global(), argc, argv);
1429#else
1430    return Call_(v8::Context::GetCurrent()->Global(), argc, argv);
1431#endif
1432  }
1433
1434 private:
1435  NAN_DISALLOW_ASSIGN_COPY_MOVE(Callback)
1436  Persistent<v8::Object> handle;
1437  static const uint32_t kCallbackIndex = 0;
1438
1439#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
1440  v8::Local<v8::Value> Call_(v8::Isolate *isolate
1441                           , v8::Local<v8::Object> target
1442                           , int argc
1443                           , v8::Local<v8::Value> argv[]) const {
1444    EscapableHandleScope scope;
1445
1446    v8::Local<v8::Function> callback = New(handle)->
1447        Get(kCallbackIndex).As<v8::Function>();
1448# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
1449    return scope.Escape(New(node::MakeCallback(
1450        isolate
1451      , target
1452      , callback
1453      , argc
1454      , argv
1455    )));
1456# else
1457    return scope.Escape(node::MakeCallback(
1458        isolate
1459      , target
1460      , callback
1461      , argc
1462      , argv
1463    ));
1464# endif
1465  }
1466#else
1467  v8::Local<v8::Value> Call_(v8::Local<v8::Object> target
1468                           , int argc
1469                           , v8::Local<v8::Value> argv[]) const {
1470    EscapableHandleScope scope;
1471
1472    v8::Local<v8::Function> callback = New(handle)->
1473        Get(kCallbackIndex).As<v8::Function>();
1474    return scope.Escape(New(node::MakeCallback(
1475        target
1476      , callback
1477      , argc
1478      , argv
1479    )));
1480  }
1481#endif
1482};
1483
1484/* abstract */ class AsyncWorker {
1485 public:
1486  explicit AsyncWorker(Callback *callback_)
1487      : callback(callback_), errmsg_(NULL) {
1488    request.data = this;
1489
1490    HandleScope scope;
1491    v8::Local<v8::Object> obj = New<v8::Object>();
1492    persistentHandle.Reset(obj);
1493  }
1494
1495  virtual ~AsyncWorker() {
1496    HandleScope scope;
1497
1498    if (!persistentHandle.IsEmpty())
1499      persistentHandle.Reset();
1500    delete callback;
1501    delete[] errmsg_;
1502  }
1503
1504  virtual void WorkComplete() {
1505    HandleScope scope;
1506
1507    if (errmsg_ == NULL)
1508      HandleOKCallback();
1509    else
1510      HandleErrorCallback();
1511    delete callback;
1512    callback = NULL;
1513  }
1514
1515  inline void SaveToPersistent(
1516      const char *key, const v8::Local<v8::Value> &value) {
1517    HandleScope scope;
1518    New(persistentHandle)->Set(New(key).ToLocalChecked(), value);
1519  }
1520
1521  inline void SaveToPersistent(
1522      const v8::Local<v8::String> &key, const v8::Local<v8::Value> &value) {
1523    HandleScope scope;
1524    New(persistentHandle)->Set(key, value);
1525  }
1526
1527  inline void SaveToPersistent(
1528      uint32_t index, const v8::Local<v8::Value> &value) {
1529    HandleScope scope;
1530    New(persistentHandle)->Set(index, value);
1531  }
1532
1533  inline v8::Local<v8::Value> GetFromPersistent(const char *key) const {
1534    EscapableHandleScope scope;
1535    return scope.Escape(
1536        New(persistentHandle)->Get(New(key).ToLocalChecked()));
1537  }
1538
1539  inline v8::Local<v8::Value>
1540  GetFromPersistent(const v8::Local<v8::String> &key) const {
1541    EscapableHandleScope scope;
1542    return scope.Escape(New(persistentHandle)->Get(key));
1543  }
1544
1545  inline v8::Local<v8::Value> GetFromPersistent(uint32_t index) const {
1546    EscapableHandleScope scope;
1547    return scope.Escape(New(persistentHandle)->Get(index));
1548  }
1549
1550  virtual void Execute() = 0;
1551
1552  uv_work_t request;
1553
1554  virtual void Destroy() {
1555      delete this;
1556  }
1557
1558 protected:
1559  Persistent<v8::Object> persistentHandle;
1560  Callback *callback;
1561
1562  virtual void HandleOKCallback() {
1563    callback->Call(0, NULL);
1564  }
1565
1566  virtual void HandleErrorCallback() {
1567    HandleScope scope;
1568
1569    v8::Local<v8::Value> argv[] = {
1570      v8::Exception::Error(New<v8::String>(ErrorMessage()).ToLocalChecked())
1571    };
1572    callback->Call(1, argv);
1573  }
1574
1575  void SetErrorMessage(const char *msg) {
1576    delete[] errmsg_;
1577
1578    size_t size = strlen(msg) + 1;
1579    errmsg_ = new char[size];
1580    memcpy(errmsg_, msg, size);
1581  }
1582
1583  const char* ErrorMessage() const {
1584    return errmsg_;
1585  }
1586
1587 private:
1588  NAN_DISALLOW_ASSIGN_COPY_MOVE(AsyncWorker)
1589  char *errmsg_;
1590};
1591
1592/* abstract */ class AsyncProgressWorker : public AsyncWorker {
1593 public:
1594  explicit AsyncProgressWorker(Callback *callback_)
1595      : AsyncWorker(callback_), asyncdata_(NULL), asyncsize_(0) {
1596    async = new uv_async_t;
1597    uv_async_init(
1598        uv_default_loop()
1599      , async
1600      , AsyncProgress_
1601    );
1602    async->data = this;
1603
1604    uv_mutex_init(&async_lock);
1605  }
1606
1607  virtual ~AsyncProgressWorker() {
1608    uv_mutex_destroy(&async_lock);
1609
1610    delete[] asyncdata_;
1611  }
1612
1613  void WorkProgress() {
1614    uv_mutex_lock(&async_lock);
1615    char *data = asyncdata_;
1616    size_t size = asyncsize_;
1617    asyncdata_ = NULL;
1618    uv_mutex_unlock(&async_lock

Large files files are truncated, but you can click here to view the full file