Browse Source

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.
v0.11.5-release
Ben Noordhuis 12 years ago
parent
commit
2bedf6efb1
  1. 4
      src/cares_wrap.cc
  2. 2
      src/node_crypto.cc
  3. 6
      src/node_internals.h
  4. 4
      src/node_script.cc

4
src/cares_wrap.cc

@ -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
// callback from the wrap->Send stack. This will destroy the wrap's internal
// 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]);
@ -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
// callback from the wrap->Send stack. This will destroy the wrap's internal
// 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]);
int family = args[1]->Int32Value();

2
src/node_crypto.cc

@ -3248,7 +3248,7 @@ void EIO_PBKDF2After(uv_work_t* work_req, int status) {
assert(status == 0);
pbkdf2_req* req = container_of(work_req, pbkdf2_req, work_req);
HandleScope scope(node_isolate);
Local<Object> obj = PersistentToLocal(req->obj);
Local<Object> obj = Local<Object>::New(node_isolate, req->obj);
req->obj.Dispose();
Local<Value> argv[2];
EIO_PBKDF2After(req, argv);

6
src/node_internals.h

@ -62,10 +62,16 @@ public:
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>
inline v8::Local<TypeName> PersistentToLocal(
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>
inline v8::Local<TypeName> PersistentToLocal(
v8::Isolate* isolate,

4
src/node_script.cc

@ -174,7 +174,7 @@ Local<Object> WrappedContext::NewInstance() {
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.");
}
script = PersistentToLocal(n_script->script_);
script = Local<Script>::New(node_isolate, n_script->script_);
}
if (output_flag == returnResult) {

Loading…
Cancel
Save