src: fix persistent handle lifecycle issue
Commit 636ca7c adds an optimization that casts strong Persistent<T> handles directly to Local<T> handles to avoid the overhead of creating new HandleScope-rooted Local<T> handles all the time. One gotcha that I missed is that it's no longer legal to reference the Local<T> after calling Persistent<T>::Dispose(). This commit addresses that.
This commit is contained in:
parent
db13983e68
commit
2bedf6efb1
@ -744,7 +744,7 @@ static void Query(const FunctionCallbackInfo<Value>& args) {
|
|||||||
// We must cache the wrap's js object here, because cares might make the
|
// We must cache the wrap's js object here, because cares might make the
|
||||||
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
||||||
// object reference, causing wrap->object() to return an empty handle.
|
// object reference, causing wrap->object() to return an empty handle.
|
||||||
Local<Object> object = wrap->object();
|
Local<Object> object = Local<Object>::New(node_isolate, wrap->persistent());
|
||||||
|
|
||||||
String::Utf8Value name(args[0]);
|
String::Utf8Value name(args[0]);
|
||||||
|
|
||||||
@ -772,7 +772,7 @@ static void QueryWithFamily(const FunctionCallbackInfo<Value>& args) {
|
|||||||
// We must cache the wrap's js object here, because cares might make the
|
// We must cache the wrap's js object here, because cares might make the
|
||||||
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
||||||
// object reference, causing wrap->object() to return an empty handle.
|
// object reference, causing wrap->object() to return an empty handle.
|
||||||
Local<Object> object = wrap->object();
|
Local<Object> object = Local<Object>::New(node_isolate, wrap->persistent());
|
||||||
|
|
||||||
String::Utf8Value name(args[0]);
|
String::Utf8Value name(args[0]);
|
||||||
int family = args[1]->Int32Value();
|
int family = args[1]->Int32Value();
|
||||||
|
@ -3248,7 +3248,7 @@ void EIO_PBKDF2After(uv_work_t* work_req, int status) {
|
|||||||
assert(status == 0);
|
assert(status == 0);
|
||||||
pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
|
pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
Local<Object> obj = PersistentToLocal(req->obj);
|
Local<Object> obj = Local<Object>::New(node_isolate, req->obj);
|
||||||
req->obj.Dispose();
|
req->obj.Dispose();
|
||||||
Local<Value> argv[2];
|
Local<Value> argv[2];
|
||||||
EIO_PBKDF2After(req, argv);
|
EIO_PBKDF2After(req, argv);
|
||||||
|
@ -62,10 +62,16 @@ public:
|
|||||||
void operator=(v8::Handle<v8::Value> that);
|
void operator=(v8::Handle<v8::Value> that);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If persistent.IsWeak() == false, then do not call persistent.Dispose()
|
||||||
|
// while the returned Local<T> is still in scope, it will destroy the
|
||||||
|
// reference to the object.
|
||||||
template <class TypeName>
|
template <class TypeName>
|
||||||
inline v8::Local<TypeName> PersistentToLocal(
|
inline v8::Local<TypeName> PersistentToLocal(
|
||||||
const v8::Persistent<TypeName>& persistent);
|
const v8::Persistent<TypeName>& persistent);
|
||||||
|
|
||||||
|
// If persistent.IsWeak() == false, then do not call persistent.Dispose()
|
||||||
|
// while the returned Local<T> is still in scope, it will destroy the
|
||||||
|
// reference to the object.
|
||||||
template <class TypeName>
|
template <class TypeName>
|
||||||
inline v8::Local<TypeName> PersistentToLocal(
|
inline v8::Local<TypeName> PersistentToLocal(
|
||||||
v8::Isolate* isolate,
|
v8::Isolate* isolate,
|
||||||
|
@ -174,7 +174,7 @@ Local<Object> WrappedContext::NewInstance() {
|
|||||||
|
|
||||||
|
|
||||||
Local<Context> WrappedContext::GetV8Context() {
|
Local<Context> WrappedContext::GetV8Context() {
|
||||||
return PersistentToLocal(context_);
|
return Local<Context>::New(node_isolate, context_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -405,7 +405,7 @@ void WrappedScript::EvalMachine(const FunctionCallbackInfo<Value>& args) {
|
|||||||
"'this' must be a result of previous new Script(code) call.");
|
"'this' must be a result of previous new Script(code) call.");
|
||||||
}
|
}
|
||||||
|
|
||||||
script = PersistentToLocal(n_script->script_);
|
script = Local<Script>::New(node_isolate, n_script->script_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_flag == returnResult) {
|
if (output_flag == returnResult) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user