package.nan.h Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nan Show documentation
Show all versions of nan Show documentation
Native Abstractions for Node.js: C++ header for Node 0.8 -> 18 compatibility
/*********************************************************************
* NAN - Native Abstractions for Node.js
*
* Copyright (c) 2018 NAN contributors:
* - Rod Vagg
* - Benjamin Byholm
* - Trevor Norris
* - Nathan Rajlich
* - Brett Lawson
* - Ben Noordhuis
* - David Siegel
* - Michael Ira Krufky
*
* MIT License
*
* Version 2.17.0: current Node 18.10.0, Node 0.12: 0.12.18, Node 0.10: 0.10.48, iojs: 3.3.1
*
* See https://github.com/nodejs/nan for the latest update to this file
**********************************************************************************/
#ifndef NAN_H_
#define NAN_H_
#include
#define NODE_0_10_MODULE_VERSION 11
#define NODE_0_12_MODULE_VERSION 14
#define ATOM_0_21_MODULE_VERSION 41
#define IOJS_1_0_MODULE_VERSION 42
#define IOJS_1_1_MODULE_VERSION 43
#define IOJS_2_0_MODULE_VERSION 44
#define IOJS_3_0_MODULE_VERSION 45
#define NODE_4_0_MODULE_VERSION 46
#define NODE_5_0_MODULE_VERSION 47
#define NODE_6_0_MODULE_VERSION 48
#define NODE_7_0_MODULE_VERSION 51
#define NODE_8_0_MODULE_VERSION 57
#define NODE_9_0_MODULE_VERSION 59
#define NODE_10_0_MODULE_VERSION 64
#define NODE_11_0_MODULE_VERSION 67
#define NODE_12_0_MODULE_VERSION 72
#define NODE_13_0_MODULE_VERSION 79
#define NODE_14_0_MODULE_VERSION 83
#define NODE_15_0_MODULE_VERSION 88
#define NODE_16_0_MODULE_VERSION 93
#define NODE_17_0_MODULE_VERSION 102
#define NODE_18_0_MODULE_VERSION 108
#ifdef _MSC_VER
# define NAN_HAS_CPLUSPLUS_11 (_MSC_VER >= 1800)
#else
# define NAN_HAS_CPLUSPLUS_11 (__cplusplus >= 201103L)
#endif
#if NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION && !NAN_HAS_CPLUSPLUS_11
# error This version of node/NAN/v8 requires a C++11 compiler
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if defined(_MSC_VER)
# pragma warning( push )
# pragma warning( disable : 4530 )
# include
# include
# include
# pragma warning( pop )
#else
# include
# include
# include
#endif
// uv helpers
#ifdef UV_VERSION_MAJOR
# ifndef UV_VERSION_PATCH
# define UV_VERSION_PATCH 0
# endif
# define NAUV_UVVERSION ((UV_VERSION_MAJOR << 16) | \
(UV_VERSION_MINOR << 8) | \
(UV_VERSION_PATCH))
#else
# define NAUV_UVVERSION 0x000b00
#endif
#if NAUV_UVVERSION < 0x000b0b
# ifdef WIN32
# include
# else
# include
# endif
#endif
namespace Nan {
#define NAN_CONCAT(a, b) NAN_CONCAT_HELPER(a, b)
#define NAN_CONCAT_HELPER(a, b) a##b
#define NAN_INLINE inline // TODO(bnoordhuis) Remove in v3.0.0.
#if defined(__GNUC__) && \
!(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
# define NAN_DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER) && \
!(defined(V8_DISABLE_DEPRECATIONS) && V8_DISABLE_DEPRECATIONS)
# define NAN_DEPRECATED __declspec(deprecated)
#else
# define NAN_DEPRECATED
#endif
#if NAN_HAS_CPLUSPLUS_11
# define NAN_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&) = delete;
# define NAN_DISALLOW_COPY(CLASS) CLASS(const CLASS&) = delete;
# define NAN_DISALLOW_MOVE(CLASS) \
CLASS(CLASS&&) = delete; /* NOLINT(build/c++11) */ \
void operator=(CLASS&&) = delete;
#else
# define NAN_DISALLOW_ASSIGN(CLASS) void operator=(const CLASS&);
# define NAN_DISALLOW_COPY(CLASS) CLASS(const CLASS&);
# define NAN_DISALLOW_MOVE(CLASS)
#endif
#define NAN_DISALLOW_ASSIGN_COPY(CLASS) \
NAN_DISALLOW_ASSIGN(CLASS) \
NAN_DISALLOW_COPY(CLASS)
#define NAN_DISALLOW_ASSIGN_MOVE(CLASS) \
NAN_DISALLOW_ASSIGN(CLASS) \
NAN_DISALLOW_MOVE(CLASS)
#define NAN_DISALLOW_COPY_MOVE(CLASS) \
NAN_DISALLOW_COPY(CLASS) \
NAN_DISALLOW_MOVE(CLASS)
#define NAN_DISALLOW_ASSIGN_COPY_MOVE(CLASS) \
NAN_DISALLOW_ASSIGN(CLASS) \
NAN_DISALLOW_COPY(CLASS) \
NAN_DISALLOW_MOVE(CLASS)
#define TYPE_CHECK(T, S) \
while (false) { \
*(static_cast(0)) = static_cast(0); \
}
//=== RegistrationFunction =====================================================
#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
typedef v8::Handle ADDON_REGISTER_FUNCTION_ARGS_TYPE;
#else
typedef v8::Local ADDON_REGISTER_FUNCTION_ARGS_TYPE;
#endif
#define NAN_MODULE_INIT(name) \
void name(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target)
#if NODE_MAJOR_VERSION >= 10 || \
NODE_MAJOR_VERSION == 9 && NODE_MINOR_VERSION >= 3
#define NAN_MODULE_WORKER_ENABLED(module_name, registration) \
extern "C" NODE_MODULE_EXPORT void \
NAN_CONCAT(node_register_module_v, NODE_MODULE_VERSION)( \
v8::Local exports, v8::Local module, \
v8::Local context) \
{ \
registration(exports); \
}
#else
#define NAN_MODULE_WORKER_ENABLED(module_name, registration) \
NODE_MODULE(module_name, registration)
#endif
//=== CallbackInfo =============================================================
#include "nan_callbacks.h" // NOLINT(build/include)
//==============================================================================
#if (NODE_MODULE_VERSION < NODE_0_12_MODULE_VERSION)
typedef v8::Script UnboundScript;
typedef v8::Script BoundScript;
#else
typedef v8::UnboundScript UnboundScript;
typedef v8::Script BoundScript;
#endif
#if (NODE_MODULE_VERSION < ATOM_0_21_MODULE_VERSION)
typedef v8::String::ExternalAsciiStringResource
ExternalOneByteStringResource;
#else
typedef v8::String::ExternalOneByteStringResource
ExternalOneByteStringResource;
#endif
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION)
template
class NonCopyablePersistentTraits :
public v8::NonCopyablePersistentTraits {};
template
class CopyablePersistentTraits :
public v8::CopyablePersistentTraits {};
template
class PersistentBase :
public v8::PersistentBase {};
template >
class Persistent;
#else
template class NonCopyablePersistentTraits;
template class PersistentBase;
template class WeakCallbackData;
template >
class Persistent;
#endif // NODE_MODULE_VERSION
template
class Maybe {
public:
inline bool IsNothing() const { return !has_value_; }
inline bool IsJust() const { return has_value_; }
inline T ToChecked() const { return FromJust(); }
inline void Check() const { FromJust(); }
inline bool To(T* out) const {
if (IsJust()) *out = value_;
return IsJust();
}
inline T FromJust() const {
#if defined(V8_ENABLE_CHECKS)
assert(IsJust() && "FromJust is Nothing");
#endif // V8_ENABLE_CHECKS
return value_;
}
inline T FromMaybe(const T& default_value) const {
return has_value_ ? value_ : default_value;
}
inline bool operator==(const Maybe &other) const {
return (IsJust() == other.IsJust()) &&
(!IsJust() || FromJust() == other.FromJust());
}
inline bool operator!=(const Maybe &other) const {
return !operator==(other);
}
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
// Allow implicit conversions from v8::Maybe to Nan::Maybe.
Maybe(const v8::Maybe& that) // NOLINT(runtime/explicit)
: has_value_(that.IsJust())
, value_(that.FromMaybe(T())) {}
#endif
private:
Maybe() : has_value_(false) {}
explicit Maybe(const T& t) : has_value_(true), value_(t) {}
bool has_value_;
T value_;
template
friend Maybe Nothing();
template
friend Maybe Just(const U& u);
};
template
inline Maybe Nothing() {
return Maybe();
}
template
inline Maybe Just(const T& t) {
return Maybe(t);
}
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
# include "nan_maybe_43_inl.h" // NOLINT(build/include)
#else
# include "nan_maybe_pre_43_inl.h" // NOLINT(build/include)
#endif
#include "nan_converters.h" // NOLINT(build/include)
#include "nan_new.h" // NOLINT(build/include)
#if NAUV_UVVERSION < 0x000b17
#define NAUV_WORK_CB(func) \
void func(uv_async_t *async, int)
#else
#define NAUV_WORK_CB(func) \
void func(uv_async_t *async)
#endif
#if NAUV_UVVERSION >= 0x000b0b
typedef uv_key_t nauv_key_t;
inline int nauv_key_create(nauv_key_t *key) {
return uv_key_create(key);
}
inline void nauv_key_delete(nauv_key_t *key) {
uv_key_delete(key);
}
inline void* nauv_key_get(nauv_key_t *key) {
return uv_key_get(key);
}
inline void nauv_key_set(nauv_key_t *key, void *value) {
uv_key_set(key, value);
}
#else
/* Implement thread local storage for older versions of libuv.
* This is essentially a backport of libuv commit 5d2434bf
* written by Ben Noordhuis, adjusted for names and inline.
*/
#ifndef WIN32
typedef pthread_key_t nauv_key_t;
inline int nauv_key_create(nauv_key_t* key) {
return -pthread_key_create(key, NULL);
}
inline void nauv_key_delete(nauv_key_t* key) {
if (pthread_key_delete(*key))
abort();
}
inline void* nauv_key_get(nauv_key_t* key) {
return pthread_getspecific(*key);
}
inline void nauv_key_set(nauv_key_t* key, void* value) {
if (pthread_setspecific(*key, value))
abort();
}
#else
typedef struct {
DWORD tls_index;
} nauv_key_t;
inline int nauv_key_create(nauv_key_t* key) {
key->tls_index = TlsAlloc();
if (key->tls_index == TLS_OUT_OF_INDEXES)
return UV_ENOMEM;
return 0;
}
inline void nauv_key_delete(nauv_key_t* key) {
if (TlsFree(key->tls_index) == FALSE)
abort();
key->tls_index = TLS_OUT_OF_INDEXES;
}
inline void* nauv_key_get(nauv_key_t* key) {
void* value = TlsGetValue(key->tls_index);
if (value == NULL)
if (GetLastError() != ERROR_SUCCESS)
abort();
return value;
}
inline void nauv_key_set(nauv_key_t* key, void* value) {
if (TlsSetValue(key->tls_index, value) == FALSE)
abort();
}
#endif
#endif
#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
template
v8::Local New(v8::Handle);
#endif
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
typedef v8::WeakCallbackType WeakCallbackType;
#else
struct WeakCallbackType {
enum E {kParameter, kInternalFields};
E type;
WeakCallbackType(E other) : type(other) {} // NOLINT(runtime/explicit)
inline bool operator==(E other) { return other == this->type; }
inline bool operator!=(E other) { return !operator==(other); }
};
#endif
template class WeakCallbackInfo;
#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
# include "nan_persistent_12_inl.h" // NOLINT(build/include)
#else
# include "nan_persistent_pre_12_inl.h" // NOLINT(build/include)
#endif
namespace imp {
static const size_t kMaxLength = 0x3fffffff;
// v8::String::REPLACE_INVALID_UTF8 was introduced
// in node.js v0.10.29 and v0.8.27.
#if NODE_MAJOR_VERSION > 0 || \
NODE_MINOR_VERSION > 10 || \
NODE_MINOR_VERSION == 10 && NODE_PATCH_VERSION >= 29 || \
NODE_MINOR_VERSION == 8 && NODE_PATCH_VERSION >= 27
static const unsigned kReplaceInvalidUtf8 = v8::String::REPLACE_INVALID_UTF8;
#else
static const unsigned kReplaceInvalidUtf8 = 0;
#endif
} // end of namespace imp
//=== HandleScope ==============================================================
class HandleScope {
v8::HandleScope scope;
public:
#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
inline HandleScope() : scope(v8::Isolate::GetCurrent()) {}
inline static int NumberOfHandles() {
return v8::HandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
}
#else
inline HandleScope() : scope() {}
inline static int NumberOfHandles() {
return v8::HandleScope::NumberOfHandles();
}
#endif
private:
// Make it hard to create heap-allocated or illegal handle scopes by
// disallowing certain operations.
HandleScope(const HandleScope &);
void operator=(const HandleScope &);
void *operator new(size_t size);
void operator delete(void *, size_t) {
abort();
}
};
class EscapableHandleScope {
public:
#if NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION
inline EscapableHandleScope() : scope(v8::Isolate::GetCurrent()) {}
inline static int NumberOfHandles() {
return v8::EscapableHandleScope::NumberOfHandles(v8::Isolate::GetCurrent());
}
template
inline v8::Local Escape(v8::Local value) {
return scope.Escape(value);
}
private:
v8::EscapableHandleScope scope;
#else
inline EscapableHandleScope() : scope() {}
inline static int NumberOfHandles() {
return v8::HandleScope::NumberOfHandles();
}
template
inline v8::Local Escape(v8::Local value) {
return scope.Close(value);
}
private:
v8::HandleScope scope;
#endif
private:
// Make it hard to create heap-allocated or illegal handle scopes by
// disallowing certain operations.
EscapableHandleScope(const EscapableHandleScope &);
void operator=(const EscapableHandleScope &);
void *operator new(size_t size);
void operator delete(void *, size_t) {
abort();
}
};
//=== TryCatch =================================================================
class TryCatch {
v8::TryCatch try_catch_;
friend void FatalException(const TryCatch&);
public:
#if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
TryCatch() : try_catch_(v8::Isolate::GetCurrent()) {}
#endif
inline bool HasCaught() const { return try_catch_.HasCaught(); }
inline bool CanContinue() const { return try_catch_.CanContinue(); }
inline v8::Local ReThrow() {
#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
return New(try_catch_.ReThrow());
#else
return try_catch_.ReThrow();
#endif
}
inline v8::Local Exception() const {
return try_catch_.Exception();
}
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
inline v8::MaybeLocal StackTrace() const {
v8::Isolate *isolate = v8::Isolate::GetCurrent();
v8::EscapableHandleScope scope(isolate);
return scope.Escape(try_catch_.StackTrace(isolate->GetCurrentContext())
.FromMaybe(v8::Local()));
}
#else
inline MaybeLocal StackTrace() const {
return try_catch_.StackTrace();
}
#endif
inline v8::Local Message() const {
return try_catch_.Message();
}
inline void Reset() { try_catch_.Reset(); }
inline void SetVerbose(bool value) { try_catch_.SetVerbose(value); }
inline void SetCaptureMessage(bool value) {
try_catch_.SetCaptureMessage(value);
}
};
v8::Local MakeCallback(v8::Local target,
v8::Local func,
int argc,
v8::Local* argv);
v8::Local MakeCallback(v8::Local target,
v8::Local symbol,
int argc,
v8::Local* argv);
v8::Local MakeCallback(v8::Local target,
const char* method,
int argc,
v8::Local* argv);
// === AsyncResource ===========================================================
class AsyncResource {
public:
AsyncResource(
v8::Local name
, v8::Local resource = New()) {
#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (resource.IsEmpty()) {
resource = New();
}
context = node::EmitAsyncInit(isolate, resource, name);
#endif
}
AsyncResource(
const char* name
, v8::Local resource = New()) {
#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (resource.IsEmpty()) {
resource = New();
}
v8::Local name_string =
New(name).ToLocalChecked();
context = node::EmitAsyncInit(isolate, resource, name_string);
#endif
}
~AsyncResource() {
#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
v8::Isolate* isolate = v8::Isolate::GetCurrent();
node::EmitAsyncDestroy(isolate, context);
#endif
}
inline MaybeLocal runInAsyncScope(
v8::Local target
, v8::Local func
, int argc
, v8::Local* argv) {
#if NODE_MODULE_VERSION < NODE_9_0_MODULE_VERSION
return MakeCallback(target, func, argc, argv);
#else
return node::MakeCallback(
v8::Isolate::GetCurrent(), target, func, argc, argv, context);
#endif
}
inline MaybeLocal runInAsyncScope(
v8::Local target
, v8::Local symbol
, int argc
, v8::Local* argv) {
#if NODE_MODULE_VERSION < NODE_9_0_MODULE_VERSION
return MakeCallback(target, symbol, argc, argv);
#else
return node::MakeCallback(
v8::Isolate::GetCurrent(), target, symbol, argc, argv, context);
#endif
}
inline MaybeLocal runInAsyncScope(
v8::Local target
, const char* method
, int argc
, v8::Local* argv) {
#if NODE_MODULE_VERSION < NODE_9_0_MODULE_VERSION
return MakeCallback(target, method, argc, argv);
#else
return node::MakeCallback(
v8::Isolate::GetCurrent(), target, method, argc, argv, context);
#endif
}
private:
NAN_DISALLOW_ASSIGN_COPY_MOVE(AsyncResource)
#if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
node::async_context context;
#endif
};
inline uv_loop_t* GetCurrentEventLoop() {
#if NODE_MAJOR_VERSION >= 10 || \
NODE_MAJOR_VERSION == 9 && NODE_MINOR_VERSION >= 3 || \
NODE_MAJOR_VERSION == 8 && NODE_MINOR_VERSION >= 10
return node::GetCurrentEventLoop(v8::Isolate::GetCurrent());
#else
return uv_default_loop();
#endif
}
//============ =================================================================
/* node 0.12 */
#if NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION
inline
void SetCounterFunction(v8::CounterLookupCallback cb) {
v8::Isolate::GetCurrent()->SetCounterFunction(cb);
}
inline
void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
v8::Isolate::GetCurrent()->SetCreateHistogramFunction(cb);
}
inline
void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
v8::Isolate::GetCurrent()->SetAddHistogramSampleFunction(cb);
}
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
inline bool IdleNotification(int idle_time_in_ms) {
return v8::Isolate::GetCurrent()->IdleNotificationDeadline(
idle_time_in_ms * 0.001);
}
# else
inline bool IdleNotification(int idle_time_in_ms) {
return v8::Isolate::GetCurrent()->IdleNotification(idle_time_in_ms);
}
#endif
inline void LowMemoryNotification() {
v8::Isolate::GetCurrent()->LowMemoryNotification();
}
inline void ContextDisposedNotification() {
v8::Isolate::GetCurrent()->ContextDisposedNotification();
}
#else
inline
void SetCounterFunction(v8::CounterLookupCallback cb) {
v8::V8::SetCounterFunction(cb);
}
inline
void SetCreateHistogramFunction(v8::CreateHistogramCallback cb) {
v8::V8::SetCreateHistogramFunction(cb);
}
inline
void SetAddHistogramSampleFunction(v8::AddHistogramSampleCallback cb) {
v8::V8::SetAddHistogramSampleFunction(cb);
}
inline bool IdleNotification(int idle_time_in_ms) {
return v8::V8::IdleNotification(idle_time_in_ms);
}
inline void LowMemoryNotification() {
v8::V8::LowMemoryNotification();
}
inline void ContextDisposedNotification() {
v8::V8::ContextDisposedNotification();
}
#endif
#if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION) // Node 0.12
inline v8::Local Undefined() {
# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
EscapableHandleScope scope;
return scope.Escape(New(v8::Undefined(v8::Isolate::GetCurrent())));
# else
return v8::Undefined(v8::Isolate::GetCurrent());
# endif
}
inline v8::Local Null() {
# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
EscapableHandleScope scope;
return scope.Escape(New(v8::Null(v8::Isolate::GetCurrent())));
# else
return v8::Null(v8::Isolate::GetCurrent());
# endif
}
inline v8::Local True() {
# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
EscapableHandleScope scope;
return scope.Escape(New(v8::True(v8::Isolate::GetCurrent())));
# else
return v8::True(v8::Isolate::GetCurrent());
# endif
}
inline v8::Local False() {
# if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
EscapableHandleScope scope;
return scope.Escape(New(v8::False(v8::Isolate::GetCurrent())));
# else
return v8::False(v8::Isolate::GetCurrent());
# endif
}
inline v8::Local EmptyString() {
return v8::String::Empty(v8::Isolate::GetCurrent());
}
inline int AdjustExternalMemory(int bc) {
return static_cast(
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc));
}
inline void SetTemplate(
v8::Local templ
, const char *name
, v8::Local value) {
templ->Set(v8::Isolate::GetCurrent(), name, value);
}
inline void SetTemplate(
v8::Local templ
, v8::Local name
, v8::Local value
, v8::PropertyAttribute attributes) {
templ->Set(name, value, attributes);
}
inline v8::Local GetCurrentContext() {
return v8::Isolate::GetCurrent()->GetCurrentContext();
}
inline void* GetInternalFieldPointer(
v8::Local object
, int index) {
return object->GetAlignedPointerFromInternalField(index);
}
inline void SetInternalFieldPointer(
v8::Local object
, int index
, void* value) {
object->SetAlignedPointerInInternalField(index, value);
}
# define NAN_GC_CALLBACK(name) \
void name(v8::Isolate *isolate, v8::GCType type, v8::GCCallbackFlags flags)
#if NODE_MODULE_VERSION <= NODE_4_0_MODULE_VERSION
typedef v8::Isolate::GCEpilogueCallback GCEpilogueCallback;
typedef v8::Isolate::GCPrologueCallback GCPrologueCallback;
#else
typedef v8::Isolate::GCCallback GCEpilogueCallback;
typedef v8::Isolate::GCCallback GCPrologueCallback;
#endif
inline void AddGCEpilogueCallback(
GCEpilogueCallback callback
, v8::GCType gc_type_filter = v8::kGCTypeAll) {
v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter);
}
inline void RemoveGCEpilogueCallback(
GCEpilogueCallback callback) {
v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback);
}
inline void AddGCPrologueCallback(
GCPrologueCallback callback
, v8::GCType gc_type_filter = v8::kGCTypeAll) {
v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter);
}
inline void RemoveGCPrologueCallback(
GCPrologueCallback callback) {
v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback);
}
inline void GetHeapStatistics(
v8::HeapStatistics *heap_statistics) {
v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics);
}
# define X(NAME) \
inline v8::Local NAME(const char *msg) { \
EscapableHandleScope scope; \
return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked())); \
} \
\
inline \
v8::Local NAME(v8::Local msg) { \
return v8::Exception::NAME(msg); \
} \
\
inline void Throw ## NAME(const char *msg) { \
HandleScope scope; \
v8::Isolate::GetCurrent()->ThrowException( \
v8::Exception::NAME(New(msg).ToLocalChecked())); \
} \
\
inline void Throw ## NAME(v8::Local msg) { \
HandleScope scope; \
v8::Isolate::GetCurrent()->ThrowException( \
v8::Exception::NAME(msg)); \
}
X(Error)
X(RangeError)
X(ReferenceError)
X(SyntaxError)
X(TypeError)
# undef X
inline void ThrowError(v8::Local error) {
v8::Isolate::GetCurrent()->ThrowException(error);
}
inline MaybeLocal NewBuffer(
char *data
, size_t length
#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
, node::Buffer::FreeCallback callback
#else
, node::smalloc::FreeCallback callback
#endif
, void *hint
) {
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
assert(length <= imp::kMaxLength && "too large buffer");
#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
return node::Buffer::New(
v8::Isolate::GetCurrent(), data, length, callback, hint);
#else
return node::Buffer::New(v8::Isolate::GetCurrent(), data, length, callback,
hint);
#endif
}
inline MaybeLocal CopyBuffer(
const char *data
, uint32_t size
) {
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
assert(size <= imp::kMaxLength && "too large buffer");
#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
return node::Buffer::Copy(
v8::Isolate::GetCurrent(), data, size);
#else
return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
#endif
}
inline MaybeLocal NewBuffer(uint32_t size) {
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
assert(size <= imp::kMaxLength && "too large buffer");
#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
return node::Buffer::New(
v8::Isolate::GetCurrent(), size);
#else
return node::Buffer::New(v8::Isolate::GetCurrent(), size);
#endif
}
inline MaybeLocal NewBuffer(
char* data
, uint32_t size
) {
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
assert(size <= imp::kMaxLength && "too large buffer");
#if NODE_MODULE_VERSION > IOJS_2_0_MODULE_VERSION
return node::Buffer::New(v8::Isolate::GetCurrent(), data, size);
#else
return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size);
#endif
}
#if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 4 || \
(V8_MAJOR_VERSION == 4 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 3))
inline MaybeLocal
NewOneByteString(const uint8_t * value, int length = -1) {
return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), value,
v8::NewStringType::kNormal, length);
}
inline MaybeLocal CompileScript(
v8::Local s
, const v8::ScriptOrigin& origin
) {
v8::Isolate *isolate = v8::Isolate::GetCurrent();
v8::EscapableHandleScope scope(isolate);
v8::ScriptCompiler::Source source(s, origin);
return scope.Escape(
v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &source)
.FromMaybe(v8::Local()));
}
inline MaybeLocal CompileScript(
v8::Local s
) {
v8::Isolate *isolate = v8::Isolate::GetCurrent();
v8::EscapableHandleScope scope(isolate);
v8::ScriptCompiler::Source source(s);
return scope.Escape(
v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &source)
.FromMaybe(v8::Local()));
}
inline MaybeLocal RunScript(
v8::Local script
) {
v8::Isolate *isolate = v8::Isolate::GetCurrent();
v8::EscapableHandleScope scope(isolate);
return scope.Escape(script->BindToCurrentContext()
->Run(isolate->GetCurrentContext())
.FromMaybe(v8::Local()));
}
inline MaybeLocal RunScript(
v8::Local script
) {
v8::Isolate *isolate = v8::Isolate::GetCurrent();
v8::EscapableHandleScope scope(isolate);
return scope.Escape(script->Run(isolate->GetCurrentContext())
.FromMaybe(v8::Local()));
}
#else
inline MaybeLocal
NewOneByteString(const uint8_t * value, int length = -1) {
return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), value,
v8::String::kNormalString, length);
}
inline MaybeLocal CompileScript(
v8::Local s
, const v8::ScriptOrigin& origin
) {
v8::ScriptCompiler::Source source(s, origin);
return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
}
inline MaybeLocal CompileScript(
v8::Local s
) {
v8::ScriptCompiler::Source source(s);
return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source);
}
inline MaybeLocal RunScript(
v8::Local script
) {
EscapableHandleScope scope;
return scope.Escape(script->BindToCurrentContext()->Run());
}
inline MaybeLocal RunScript(
v8::Local script
) {
return script->Run();
}
#endif
NAN_DEPRECATED inline v8::Local MakeCallback(
v8::Local target
, v8::Local func
, int argc
, v8::Local* argv) {
#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
EscapableHandleScope scope;
return scope.Escape(New(node::MakeCallback(
v8::Isolate::GetCurrent(), target, func, argc, argv)));
#else
# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
AsyncResource res("nan:makeCallback");
return res.runInAsyncScope(target, func, argc, argv)
.FromMaybe(v8::Local());
# else
return node::MakeCallback(
v8::Isolate::GetCurrent(), target, func, argc, argv);
# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
#endif // NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
}
NAN_DEPRECATED inline v8::Local MakeCallback(
v8::Local target
, v8::Local symbol
, int argc
, v8::Local* argv) {
#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
EscapableHandleScope scope;
return scope.Escape(New(node::MakeCallback(
v8::Isolate::GetCurrent(), target, symbol, argc, argv)));
#else
# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
AsyncResource res("nan:makeCallback");
return res.runInAsyncScope(target, symbol, argc, argv)
.FromMaybe(v8::Local());
# else
return node::MakeCallback(
v8::Isolate::GetCurrent(), target, symbol, argc, argv);
# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
#endif // NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
}
NAN_DEPRECATED inline v8::Local MakeCallback(
v8::Local target
, const char* method
, int argc
, v8::Local* argv) {
#if NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
EscapableHandleScope scope;
return scope.Escape(New(node::MakeCallback(
v8::Isolate::GetCurrent(), target, method, argc, argv)));
#else
# if NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
AsyncResource res("nan:makeCallback");
return res.runInAsyncScope(target, method, argc, argv)
.FromMaybe(v8::Local());
# else
return node::MakeCallback(
v8::Isolate::GetCurrent(), target, method, argc, argv);
# endif // NODE_MODULE_VERSION >= NODE_9_0_MODULE_VERSION
#endif // NODE_MODULE_VERSION < IOJS_3_0_MODULE_VERSION
}
inline void FatalException(const TryCatch& try_catch) {
node::FatalException(v8::Isolate::GetCurrent(), try_catch.try_catch_);
}
inline v8::Local ErrnoException(
int errorno
, const char* syscall = NULL
, const char* message = NULL
, const char* path = NULL) {
return node::ErrnoException(v8::Isolate::GetCurrent(), errorno, syscall,
message, path);
}
NAN_DEPRECATED inline v8::Local NanErrnoException(
int errorno
, const char* syscall = NULL
, const char* message = NULL
, const char* path = NULL) {
return ErrnoException(errorno, syscall, message, path);
}
template
inline void SetIsolateData(
v8::Isolate *isolate
, T *data
) {
isolate->SetData(0, data);
}
template
inline T *GetIsolateData(
v8::Isolate *isolate
) {
return static_cast(isolate->GetData(0));
}
class Utf8String {
public:
inline explicit Utf8String(v8::Local from) :
length_(0), str_(str_st_) {
HandleScope scope;
if (!from.IsEmpty()) {
#if NODE_MAJOR_VERSION >= 10
v8::Local context = GetCurrentContext();
v8::Local string =
from->ToString(context).FromMaybe(v8::Local());
#else
v8::Local string = from->ToString();
#endif
if (!string.IsEmpty()) {
size_t len = 3 * string->Length() + 1;
assert(len <= INT_MAX);
if (len > sizeof (str_st_)) {
str_ = static_cast(malloc(len));
assert(str_ != 0);
}
const int flags =
v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
#if NODE_MAJOR_VERSION >= 11
length_ = string->WriteUtf8(v8::Isolate::GetCurrent(), str_,
static_cast(len), 0, flags);
#else
// See https://github.com/nodejs/nan/issues/832.
// Disable the warning as there is no way around it.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4996)
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
length_ = string->WriteUtf8(str_, static_cast(len), 0, flags);
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // NODE_MAJOR_VERSION < 11
str_[length_] = '\0';
}
}
}
inline int length() const {
return length_;
}
inline char* operator*() { return str_; }
inline const char* operator*() const { return str_; }
inline ~Utf8String() {
if (str_ != str_st_) {
free(str_);
}
}
private:
NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
int length_;
char *str_;
char str_st_[1024];
};
#else // Node 0.8 and 0.10
inline v8::Local Undefined() {
EscapableHandleScope scope;
return scope.Escape(New(v8::Undefined()));
}
inline v8::Local Null() {
EscapableHandleScope scope;
return scope.Escape(New(v8::Null()));
}
inline v8::Local True() {
EscapableHandleScope scope;
return scope.Escape(New(v8::True()));
}
inline v8::Local False() {
EscapableHandleScope scope;
return scope.Escape(New(v8::False()));
}
inline v8::Local EmptyString() {
return v8::String::Empty();
}
inline int AdjustExternalMemory(int bc) {
return static_cast(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc));
}
inline void SetTemplate(
v8::Local templ
, const char *name
, v8::Local value) {
templ->Set(name, value);
}
inline void SetTemplate(
v8::Local templ
, v8::Local name
, v8::Local value
, v8::PropertyAttribute attributes) {
templ->Set(name, value, attributes);
}
inline v8::Local GetCurrentContext() {
return v8::Context::GetCurrent();
}
inline void* GetInternalFieldPointer(
v8::Local object
, int index) {
return object->GetPointerFromInternalField(index);
}
inline void SetInternalFieldPointer(
v8::Local object
, int index
, void* value) {
object->SetPointerInInternalField(index, value);
}
# define NAN_GC_CALLBACK(name) \
void name(v8::GCType type, v8::GCCallbackFlags flags)
inline void AddGCEpilogueCallback(
v8::GCEpilogueCallback callback
, v8::GCType gc_type_filter = v8::kGCTypeAll) {
v8::V8::AddGCEpilogueCallback(callback, gc_type_filter);
}
inline void RemoveGCEpilogueCallback(
v8::GCEpilogueCallback callback) {
v8::V8::RemoveGCEpilogueCallback(callback);
}
inline void AddGCPrologueCallback(
v8::GCPrologueCallback callback
, v8::GCType gc_type_filter = v8::kGCTypeAll) {
v8::V8::AddGCPrologueCallback(callback, gc_type_filter);
}
inline void RemoveGCPrologueCallback(
v8::GCPrologueCallback callback) {
v8::V8::RemoveGCPrologueCallback(callback);
}
inline void GetHeapStatistics(
v8::HeapStatistics *heap_statistics) {
v8::V8::GetHeapStatistics(heap_statistics);
}
# define X(NAME) \
inline v8::Local NAME(const char *msg) { \
EscapableHandleScope scope; \
return scope.Escape(v8::Exception::NAME(New(msg).ToLocalChecked())); \
} \
\
inline \
v8::Local NAME(v8::Local msg) { \
return v8::Exception::NAME(msg); \
} \
\
inline void Throw ## NAME(const char *msg) { \
HandleScope scope; \
v8::ThrowException(v8::Exception::NAME(New(msg).ToLocalChecked())); \
} \
\
inline \
void Throw ## NAME(v8::Local errmsg) { \
HandleScope scope; \
v8::ThrowException(v8::Exception::NAME(errmsg)); \
}
X(Error)
X(RangeError)
X(ReferenceError)
X(SyntaxError)
X(TypeError)
# undef X
inline void ThrowError(v8::Local error) {
v8::ThrowException(error);
}
inline MaybeLocal NewBuffer(
char *data
, size_t length
, node::Buffer::free_callback callback
, void *hint
) {
EscapableHandleScope scope;
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
assert(length <= imp::kMaxLength && "too large buffer");
return scope.Escape(
New(node::Buffer::New(data, length, callback, hint)->handle_));
}
inline MaybeLocal CopyBuffer(
const char *data
, uint32_t size
) {
EscapableHandleScope scope;
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
assert(size <= imp::kMaxLength && "too large buffer");
#if NODE_MODULE_VERSION >= NODE_0_10_MODULE_VERSION
return scope.Escape(New(node::Buffer::New(data, size)->handle_));
#else
return scope.Escape(
New(node::Buffer::New(const_cast(data), size)->handle_));
#endif
}
inline MaybeLocal NewBuffer(uint32_t size) {
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
EscapableHandleScope scope;
assert(size <= imp::kMaxLength && "too large buffer");
return scope.Escape(New(node::Buffer::New(size)->handle_));
}
inline void FreeData(char *data, void *hint) {
(void) hint; // unused
delete[] data;
}
inline MaybeLocal NewBuffer(
char* data
, uint32_t size
) {
EscapableHandleScope scope;
// arbitrary buffer lengths requires
// NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION
assert(size <= imp::kMaxLength && "too large buffer");
return scope.Escape(
New(node::Buffer::New(data, size, FreeData, NULL)->handle_));
}
namespace imp {
inline void
widenString(std::vector *ws, const uint8_t *s, int l) {
size_t len = static_cast(l);
if (l < 0) {
len = strlen(reinterpret_cast(s));
}
assert(len <= INT_MAX && "string too long");
ws->resize(len);
std::copy(s, s + len, ws->begin()); // NOLINT(build/include_what_you_use)
}
} // end of namespace imp
inline MaybeLocal
NewOneByteString(const uint8_t * value, int length = -1) {
std::vector wideString; // NOLINT(build/include_what_you_use)
imp::widenString(&wideString, value, length);
return v8::String::New(wideString.data(),
static_cast(wideString.size()));
}
inline MaybeLocal CompileScript(
v8::Local s
, const v8::ScriptOrigin& origin
) {
return v8::Script::Compile(s, const_cast(&origin));
}
inline MaybeLocal CompileScript(
v8::Local s
) {
return v8::Script::Compile(s);
}
inline
MaybeLocal RunScript(v8::Local script) {
return script->Run();
}
inline v8::Local MakeCallback(
v8::Local target
, v8::Local func
, int argc
, v8::Local* argv) {
v8::HandleScope scope;
return scope.Close(New(node::MakeCallback(target, func, argc, argv)));
}
inline v8::Local MakeCallback(
v8::Local target
, v8::Local symbol
, int argc
, v8::Local* argv) {
v8::HandleScope scope;
return scope.Close(New(node::MakeCallback(target, symbol, argc, argv)));
}
inline v8::Local MakeCallback(
v8::Local target
, const char* method
, int argc
, v8::Local* argv) {
v8::HandleScope scope;
return scope.Close(New(node::MakeCallback(target, method, argc, argv)));
}
inline void FatalException(const TryCatch& try_catch) {
node::FatalException(const_cast(try_catch.try_catch_));
}
inline v8::Local ErrnoException(
int errorno
, const char* syscall = NULL
, const char* message = NULL
, const char* path = NULL) {
return node::ErrnoException(errorno, syscall, message, path);
}
NAN_DEPRECATED inline v8::Local NanErrnoException(
int errorno
, const char* syscall = NULL
, const char* message = NULL
, const char* path = NULL) {
return ErrnoException(errorno, syscall, message, path);
}
template
inline void SetIsolateData(
v8::Isolate *isolate
, T *data
) {
isolate->SetData(data);
}
template
inline T *GetIsolateData(
v8::Isolate *isolate
) {
return static_cast(isolate->GetData());
}
class Utf8String {
public:
inline explicit Utf8String(v8::Local from) :
length_(0), str_(str_st_) {
v8::HandleScope scope;
if (!from.IsEmpty()) {
v8::Local string = from->ToString();
if (!string.IsEmpty()) {
size_t len = 3 * string->Length() + 1;
assert(len <= INT_MAX);
if (len > sizeof (str_st_)) {
str_ = static_cast(malloc(len));
assert(str_ != 0);
}
const int flags =
v8::String::NO_NULL_TERMINATION | imp::kReplaceInvalidUtf8;
length_ = string->WriteUtf8(str_, static_cast(len), 0, flags);
str_[length_] = '\0';
}
}
}
inline int length() const {
return length_;
}
inline char* operator*() { return str_; }
inline const char* operator*() const { return str_; }
inline ~Utf8String() {
if (str_ != str_st_) {
free(str_);
}
}
private:
NAN_DISALLOW_ASSIGN_COPY_MOVE(Utf8String)
int length_;
char *str_;
char str_st_[1024];
};
#endif // NODE_MODULE_VERSION
typedef void (*FreeCallback)(char *data, void *hint);
typedef const FunctionCallbackInfo& NAN_METHOD_ARGS_TYPE;
typedef void NAN_METHOD_RETURN_TYPE;
typedef const PropertyCallbackInfo& NAN_GETTER_ARGS_TYPE;
typedef void NAN_GETTER_RETURN_TYPE;
typedef const PropertyCallbackInfo& NAN_SETTER_ARGS_TYPE;
typedef void NAN_SETTER_RETURN_TYPE;
typedef const PropertyCallbackInfo&
NAN_PROPERTY_GETTER_ARGS_TYPE;
typedef void NAN_PROPERTY_GETTER_RETURN_TYPE;
typedef const PropertyCallbackInfo&
NAN_PROPERTY_SETTER_ARGS_TYPE;
typedef void NAN_PROPERTY_SETTER_RETURN_TYPE;
typedef const PropertyCallbackInfo&
NAN_PROPERTY_ENUMERATOR_ARGS_TYPE;
typedef void NAN_PROPERTY_ENUMERATOR_RETURN_TYPE;
typedef const PropertyCallbackInfo&
NAN_PROPERTY_DELETER_ARGS_TYPE;
typedef void NAN_PROPERTY_DELETER_RETURN_TYPE;
typedef const PropertyCallbackInfo&
NAN_PROPERTY_QUERY_ARGS_TYPE;
typedef void NAN_PROPERTY_QUERY_RETURN_TYPE;
typedef const PropertyCallbackInfo& NAN_INDEX_GETTER_ARGS_TYPE;
typedef void NAN_INDEX_GETTER_RETURN_TYPE;
typedef const PropertyCallbackInfo& NAN_INDEX_SETTER_ARGS_TYPE;
typedef void NAN_INDEX_SETTER_RETURN_TYPE;
typedef const PropertyCallbackInfo&
NAN_INDEX_ENUMERATOR_ARGS_TYPE;
typedef void NAN_INDEX_ENUMERATOR_RETURN_TYPE;
typedef const PropertyCallbackInfo&
NAN_INDEX_DELETER_ARGS_TYPE;
typedef void NAN_INDEX_DELETER_RETURN_TYPE;
typedef const PropertyCallbackInfo&
NAN_INDEX_QUERY_ARGS_TYPE;
typedef void NAN_INDEX_QUERY_RETURN_TYPE;
#define NAN_METHOD(name) \
Nan::NAN_METHOD_RETURN_TYPE name(Nan::NAN_METHOD_ARGS_TYPE info)
#define NAN_GETTER(name) \
Nan::NAN_GETTER_RETURN_TYPE name( \
v8::Local property \
, Nan::NAN_GETTER_ARGS_TYPE info)
#define NAN_SETTER(name) \
Nan::NAN_SETTER_RETURN_TYPE name( \
v8::Local