00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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; \
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
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
00145
00146 #include "nan_callbacks.h"
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"
00191 #else
00192 # include "nan_maybe_pre_43_inl.h"
00193 #endif
00194
00195 #include "nan_converters.h"
00196 #include "nan_new.h"
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
00229
00230
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) {}
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"
00312 #else
00313 # include "nan_persistent_pre_12_inl.h"
00314 #endif
00315
00316 namespace imp {
00317 static const size_t kMaxLength = 0x3fffffff;
00318
00319
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 }
00329
00330
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
00350
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
00391
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
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
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
00678
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
00694
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
00707
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
00723
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
01055
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
01067
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
01080
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;
01089 delete[] data;
01090 }
01091
01092 inline MaybeLocal<v8::Object> NewBuffer(
01093 char* data
01094 , uint32_t size
01095 ) {
01096 EscapableHandleScope scope;
01097
01098
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());
01114 }
01115 }
01116
01117 inline MaybeLocal<v8::String>
01118 NewOneByteString(const uint8_t * value, int length = -1) {
01119 std::vector<uint16_t> wideString;
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
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 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 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
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() {
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
01685
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 }
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"
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
01850
01851
01852
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 }
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
01885
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
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
02185
02186 #include "nan_weak.h"
02187
02188
02189
02190 #include "nan_object_wrap.h"
02191
02192
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
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(); }
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
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 }
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
02269
02270 #include "nan_typedarray_contents.h"
02271
02272 }
02273
02274 #endif // NAN_H_