Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ LINT_SOURCES = \
test/cpp/morenews.cpp \
test/cpp/converters.cpp \
test/cpp/isolatedata.cpp \
test/cpp/global.cpp \
test/cpp/makecallback.cpp \
test/cpp/morenews.cpp \
test/cpp/multifile1.cpp \
Expand Down
1 change: 0 additions & 1 deletion nan_callbacks_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class ReturnValue {
value_.Set(handle);
#else
value_.Set(*reinterpret_cast<const v8::Persistent<S>*>(&handle));
const_cast<Global<S> &>(handle).Reset();
#endif
}

Expand Down
1 change: 0 additions & 1 deletion nan_callbacks_pre_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class ReturnValue {
TYPE_CHECK(T, S);
value_->Dispose();
*value_ = v8::Persistent<T>::New(handle.persistent);
const_cast<Global<S> &>(handle).Reset();
}

// Fast primitive setters
Expand Down
5 changes: 3 additions & 2 deletions nan_maybe_pre_43_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ class MaybeLocal {

template<typename S>
# if NODE_MODULE_VERSION >= NODE_0_12_MODULE_VERSION
inline MaybeLocal(v8::Local<S> that) : val_(that) {}
inline MaybeLocal(v8::Local<S> that) : // NOLINT(runtime/explicit)
val_(that) {}
# else
inline MaybeLocal(v8::Local<S> that) :
inline MaybeLocal(v8::Local<S> that) : // NOLINT(runtime/explicit)
val_(*reinterpret_cast<v8::Local<T>*>(&that)) {}

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

# endif

Expand Down
69 changes: 53 additions & 16 deletions nan_persistent_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,38 @@ template<typename T, typename M> class Persistent :
public:
inline Persistent() : v8::Persistent<T, M>() {}

template<typename S> inline Persistent(v8::Local<S> that) :
template<typename S> inline explicit Persistent(v8::Local<S> that) :
v8::Persistent<T, M>(v8::Isolate::GetCurrent(), that) {}

template<typename S, typename M2>
inline Persistent(const v8::Persistent<S, M2> &that) :
inline explicit Persistent(const v8::Persistent<S, M2> &that) :
v8::Persistent<T, M2>(v8::Isolate::GetCurrent(), that) {}

This comment was marked as off-topic.


inline void Reset() { v8::PersistentBase<T>::Reset(); }

template <typename S>
template<typename S>
inline void Reset(const v8::Local<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
}

template <typename S>
template<typename S>
inline void Reset(const v8::PersistentBase<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
}

#if NODE_MODULE_VERSION == NODE_0_12_MODULE_VERSION
inline void Empty() {
v8::Persistent<T, M>::ClearAndLeak();
}
#endif

template<typename P>
inline void SetWeak(
P *parameter
, typename WeakCallbackInfo<P>::Callback callback
, WeakCallbackType type);

private:
inline T *operator*() const { return *PersistentBase<T>::persistent; }

template<typename S, typename M2>
inline void Copy(const Persistent<S, M2> &that) {
TYPE_CHECK(T, S);
Expand All @@ -62,11 +66,11 @@ class Global : public v8::Global<T> {
public:
inline Global() : v8::Global<T>() {}

template<typename S> inline Global(v8::Local<S> that) :
template<typename S> inline explicit Global(v8::Local<S> that) :
v8::Global<T>(v8::Isolate::GetCurrent(), that) {}

template<typename S>
inline Global(const v8::PersistentBase<S> &that) :
inline explicit Global(const v8::PersistentBase<S> &that) :
v8::Global<S>(v8::Isolate::GetCurrent(), that) {}

inline void Reset() { v8::PersistentBase<T>::Reset(); }
Expand All @@ -81,47 +85,80 @@ class Global : public v8::Global<T> {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
}

Global Pass() { return static_cast<Global&&>(*this); } // NOLINT(build/c++11)

This comment was marked as off-topic.

This comment was marked as off-topic.


template<typename P>
inline void SetWeak(
P *parameter
, typename WeakCallbackInfo<P>::Callback callback
, WeakCallbackType type) {
reinterpret_cast<Persistent<T>*>(this)->SetWeak(
parameter, callback, type);
static_cast<Persistent<T>*>(static_cast<v8::PersistentBase<T>*>(this))->
SetWeak(parameter, callback, type);
}
};
#else
template<typename T>
class Global : public v8::UniquePersistent<T> {
struct RValue {
inline explicit RValue(v8::UniquePersistent<T> *obj) : object_(obj) {}
v8::UniquePersistent<T> *object_;
};

public:
inline Global() : v8::UniquePersistent<T>() {}

template<typename S> inline Global(v8::Local<S> that) :
template<typename S> inline explicit Global(v8::Local<S> that) :
v8::UniquePersistent<T>(v8::Isolate::GetCurrent(), that) {}

template<typename S>
inline Global(const v8::PersistentBase<S> &that) :
inline explicit Global(const v8::PersistentBase<S> &that) :
v8::UniquePersistent<S>(v8::Isolate::GetCurrent(), that) {}

inline void Reset() { v8::PersistentBase<T>::Reset(); }

template <typename S>
template<typename S>
inline void Reset(const v8::Local<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
}

template <typename S>
template<typename S>
inline void Reset(const v8::PersistentBase<S> &other) {
v8::PersistentBase<T>::Reset(v8::Isolate::GetCurrent(), other);
}

#if NODE_MODULE_VERSION == NODE_0_12_MODULE_VERSION
inline void Empty() {
static_cast<v8::Persistent<T>*>(static_cast<v8::PersistentBase<T>*>(this))->
ClearAndLeak();
}
#endif

inline Global(RValue rvalue) { // NOLINT(runtime/explicit)
std::memcpy(this, rvalue.object_, sizeof (*rvalue.object_));
# if NODE_MODULE_VERSION > NODE_0_12_MODULE_VERSION
rvalue.object_->Empty();
# else
static_cast<v8::Persistent<T>*>(static_cast<v8::PersistentBase<T>*>(
rvalue.object_))->ClearAndLeak();
# endif
}

template<typename S>
inline Global &operator=(v8::UniquePersistent<S> other) {
return static_cast<Global&>(v8::UniquePersistent<S>::operator=(other));
}

inline operator RValue() { return RValue(this); }

This comment was marked as off-topic.

This comment was marked as off-topic.


Global Pass() { return Global(RValue(this)); }

template<typename P>
inline void SetWeak(
P *parameter
, typename WeakCallbackInfo<P>::Callback callback
, WeakCallbackType type) {
reinterpret_cast<Persistent<T>*>(this)->SetWeak(
parameter, callback, type);
static_cast<Persistent<T>*>(static_cast<v8::PersistentBase<T>*>(this))
->SetWeak(parameter, callback, type);
}
};
#endif
Expand Down
19 changes: 11 additions & 8 deletions nan_persistent_pre_12_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,32 +196,35 @@ class Global : public PersistentBase<T> {
inline Global() : PersistentBase<T>(0) { }

template <typename S>
inline Global(v8::Local<S> that)
inline explicit Global(v8::Local<S> that)
: PersistentBase<T>(v8::Persistent<T>::New(that)) {
TYPE_CHECK(T, S);
}

template <typename S>
inline Global(const PersistentBase<S> &that)
: PersistentBase<T>(that) {
inline explicit Global(const PersistentBase<S> &that) :
PersistentBase<T>(that) {
TYPE_CHECK(T, S);
}
/**
* Move constructor.
*/
inline Global(RValue rvalue)
inline Global(RValue rvalue) // NOLINT(runtime/explicit)

This comment was marked as off-topic.

: PersistentBase<T>(rvalue.object->persistent) {
rvalue.object->Reset();
rvalue.object->Empty();
}
inline ~Global() { this->Reset(); }
/**
* Move via assignment.
*/
template<typename S>
inline Global &operator=(Global<S> rhs) {
inline Global &operator=(Global<S> other) {
TYPE_CHECK(T, S);
this->Reset(rhs.persistent);
rhs.Reset();
if (!this->persistent.IsEmpty()) {
this->persistent.Dispose();
}
this->persistent = other.persistent;
other.Empty();
return *this;
}
/**
Expand Down
4 changes: 4 additions & 0 deletions test/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,8 @@
"target_name" : "typedarrays"
, "sources" : [ "cpp/typedarrays.cpp" ]
}
, {
"target_name" : "global"
, "sources" : [ "cpp/global.cpp" ]
}
]}
75 changes: 75 additions & 0 deletions test/cpp/global.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*********************************************************************
* NAN - Native Abstractions for Node.js
*
* Copyright (c) 2016 NAN contributors
*
* MIT License <https://github.com/nodejs/nan/blob/master/LICENSE.md>
********************************************************************/

#include <nan.h>

using namespace Nan; // NOLINT(build/namespaces)

template<typename T> Global<T> passer(v8::Local<T> handle) {
return Global<T>(handle).Pass();
}

NAN_METHOD(PassGlobal) {
info.GetReturnValue().Set(passer(New(42)));
}

NAN_METHOD(EmptyGlobal) {
Global<v8::String> g(New("value").ToLocalChecked());
bool b1 = !g.IsEmpty();
g.Empty(); // this will leak, never do it
info.GetReturnValue().Set(b1 && g.IsEmpty());
}

NAN_METHOD(MoveConstructGlobal) {
Global<v8::String> g(Global<v8::String>(New("value").ToLocalChecked()));
info.GetReturnValue().Set(!g.IsEmpty());
}

NAN_METHOD(CopyConstructGlobal) {
Persistent<v8::String> p(New("value").ToLocalChecked());
bool b1 = !p.IsEmpty();
Global<v8::String> g(p);
bool b2 = !p.IsEmpty();
p.Reset();
info.GetReturnValue().Set(b1 && b2 && !g.IsEmpty());
}

NAN_METHOD(MoveAssignGlobal) {
Global<v8::String> g = passer(New("value").ToLocalChecked());
info.GetReturnValue().Set(!g.IsEmpty());
}

NAN_MODULE_INIT(Init) {
Set(target
, New<v8::String>("passGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(PassGlobal))
.ToLocalChecked()
);
Set(target
, New<v8::String>("emptyGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(EmptyGlobal))
.ToLocalChecked()
);
Set(target
, New<v8::String>("moveConstructGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(MoveConstructGlobal))
.ToLocalChecked()
);
Set(target
, New<v8::String>("copyConstructGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(CopyConstructGlobal))
.ToLocalChecked()
);
Set(target
, New<v8::String>("moveAssignGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(MoveAssignGlobal))
.ToLocalChecked()
);
}

NODE_MODULE(global, Init)
59 changes: 59 additions & 0 deletions test/cpp/persistent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using namespace Nan; // NOLINT(build/namespaces)

static Persistent<v8::String> persistentTest1;
static Persistent<v8::String> persistentTest2;

NAN_METHOD(Save1) {
persistentTest1.Reset(info[0].As<v8::String>());
Expand Down Expand Up @@ -55,6 +56,39 @@ NAN_METHOD(PassGlobal) {
info.GetReturnValue().Set(passer(New(42)));
}

NAN_METHOD(EmptyPersistent) {
persistentTest2.Reset(New("value").ToLocalChecked());
bool b1 = !persistentTest2.IsEmpty();
persistentTest2.Empty(); // this will leak, never do it
info.GetReturnValue().Set(b1 && persistentTest2.IsEmpty());
}

NAN_METHOD(EmptyGlobal) {
Global<v8::String> g(New("value").ToLocalChecked());
bool b1 = !g.IsEmpty();
g.Empty(); // this will leak, never do it
info.GetReturnValue().Set(b1 && g.IsEmpty());
}

NAN_METHOD(MoveConstructGlobal) {
Global<v8::String> g(Global<v8::String>(New("value").ToLocalChecked()));
info.GetReturnValue().Set(!g.IsEmpty());
}

NAN_METHOD(CopyConstructGlobal) {
Persistent<v8::String> p(New("value").ToLocalChecked());
bool b1 = !p.IsEmpty();
Global<v8::String> g(p);
bool b2 = !p.IsEmpty();
p.Reset();
info.GetReturnValue().Set(b1 && b2 && !g.IsEmpty());
}

NAN_METHOD(MoveAssignGlobal) {
Global<v8::String> g = passer(New("value").ToLocalChecked());
info.GetReturnValue().Set(!g.IsEmpty());
}

NAN_MODULE_INIT(Init) {
Set(target
, New<v8::String>("save1").ToLocalChecked()
Expand Down Expand Up @@ -88,6 +122,31 @@ NAN_MODULE_INIT(Init) {
, GetFunction(New<v8::FunctionTemplate>(PassGlobal))
.ToLocalChecked()
);
Set(target
, New<v8::String>("emptyPersistent").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(EmptyPersistent))
.ToLocalChecked()
);
Set(target
, New<v8::String>("emptyGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(EmptyGlobal))
.ToLocalChecked()
);
Set(target
, New<v8::String>("moveConstructGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(MoveConstructGlobal))
.ToLocalChecked()
);
Set(target
, New<v8::String>("copyConstructGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(CopyConstructGlobal))
.ToLocalChecked()
);
Set(target
, New<v8::String>("moveAssignGlobal").ToLocalChecked()
, GetFunction(New<v8::FunctionTemplate>(MoveAssignGlobal))
.ToLocalChecked()
);
}

NODE_MODULE(persistent, Init)
Loading