local handles and handle scopes

287 views
Skip to first unread message

ondras

unread,
Feb 18, 2009, 3:28:04 AM2/18/09
to v8-users
Hi,

some small questions regarding this example, took from the Embedder's
guide:

void SetPointX(Local<String> property, Local<Value> value,
const AccessorInfo& info) {
Local<Object> self = info.Holder();
Local<External> wrap = Local<External>::Cast(self->GetInternalField
(0));
void* ptr = wrap->Value();
static_cast<Point*>(ptr)->x_ = value->Int32Value();
}


1) why there is no HandleScope in this method? When are those Local
handles destroyed?
2) what exactly is the difference between v8::Handle and v8::Local ?
3) if I declare a handle in a HandleScope, is it true that I must use
handle_scope.Close(myHandle) to safely return it from a function?


Thanks a lot for responses,
Ondrej Zara

Matthias Ernst

unread,
Feb 18, 2009, 3:45:17 AM2/18/09
to v8-u...@googlegroups.com
On Wed, Feb 18, 2009 at 9:28 AM, ondras <ondre...@gmail.com> wrote:
>
> Hi,
>
> some small questions regarding this example, took from the Embedder's
> guide:
>
> void SetPointX(Local<String> property, Local<Value> value,
> const AccessorInfo& info) {
> Local<Object> self = info.Holder();
> Local<External> wrap = Local<External>::Cast(self->GetInternalField
> (0));
> void* ptr = wrap->Value();
> static_cast<Point*>(ptr)->x_ = value->Int32Value();
> }
>
>
> 1) why there is no HandleScope in this method? When are those Local
> handles destroyed?

See
http://groups.google.com/group/v8-users/browse_thread/thread/27fcbb1e7da0b77d/1d65d64fed5c8480?lnk=gst&q=It%27s+option+1%3A+a+handle+scope+is+set+up+for+callbacks%2C+always%2C+so+if#1d65d64fed5c8480

A handle scope is created by v8 for each callback invocation.

> 2) what exactly is the difference between v8::Handle and v8::Local ?

Handle is the super class of both Local and Persistent.

> 3) if I declare a handle in a HandleScope, is it true that I must use
> handle_scope.Close(myHandle) to safely return it from a function?

Yes. The documentation to HandleScope says: "The behavior of accessing
a handle for which the handle scope has been deleted is undefined."

Ondrej Zara

unread,
Feb 18, 2009, 4:45:08 AM2/18/09
to v8-u...@googlegroups.com
Hi Matthias,

thanks for a prompt response!

>> 1) why there is no HandleScope in this method? When are those Local
>> handles destroyed?
>
> See
> http://groups.google.com/group/v8-users/browse_thread/thread/27fcbb1e7da0b77d/1d65d64fed5c8480?lnk=gst&q=It%27s+option+1%3A+a+handle+scope+is+set+up+for+callbacks%2C+always%2C+so+if#1d65d64fed5c8480
>
> A handle scope is created by v8 for each callback invocation.
>

Thanks for the link. That basically covers my question. So, is it safe
to return a handle from callback, *if* I don't create a (my own
explicit) HandleScope, okay?

>> 2) what exactly is the difference between v8::Handle and v8::Local ?
>
> Handle is the super class of both Local and Persistent.

I already figured this from the inheritance diagram (in autogenerated
docs), but it is still unclear to me what is the (from the
functionality point of view) difference beween writing

v8::Handle<v8::String> x = ...
and
v8::Local<v8::String> y = ...

Thanks,
Ondrej

Matthias Ernst

unread,
Feb 18, 2009, 5:23:54 AM2/18/09
to v8-u...@googlegroups.com
On Wed, Feb 18, 2009 at 10:45 AM, Ondrej Zara <ondre...@gmail.com> wrote:
>
> Hi Matthias,
>
> thanks for a prompt response!
>
>>> 1) why there is no HandleScope in this method? When are those Local
>>> handles destroyed?
>>
>> See
>> http://groups.google.com/group/v8-users/browse_thread/thread/27fcbb1e7da0b77d/1d65d64fed5c8480?lnk=gst&q=It%27s+option+1%3A+a+handle+scope+is+set+up+for+callbacks%2C+always%2C+so+if#1d65d64fed5c8480
>>
>> A handle scope is created by v8 for each callback invocation.
>>
>
> Thanks for the link. That basically covers my question. So, is it safe
> to return a handle from callback, *if* I don't create a (my own
> explicit) HandleScope, okay?

yes.

>
>>> 2) what exactly is the difference between v8::Handle and v8::Local ?
>>
>> Handle is the super class of both Local and Persistent.
>
> I already figured this from the inheritance diagram (in autogenerated
> docs), but it is still unclear to me what is the (from the
> functionality point of view) difference beween writing
>
> v8::Handle<v8::String> x = ...
> and
> v8::Local<v8::String> y = ...

There is no difference as far as I understand. These are just copies
of existing handles. Especially, an assignment like this does _not_
cause registration with a handle scope. Only Local::New does that.

Using Handle allows you to write code that doesn't care whether
certain handles are local or not.

Just speculating from what I read in v8.h, I guess "they" could rename
Local::New as Handle::NewLocal, change all usages of "Local" into
"Handle" and get rid of "Local" altogether.

Matthias



>
>
> Thanks,
> Ondrej
>
> >
>

Ondrej Zara

unread,
Feb 18, 2009, 5:35:12 AM2/18/09
to v8-u...@googlegroups.com
>> I already figured this from the inheritance diagram (in autogenerated
>> docs), but it is still unclear to me what is the (from the
>> functionality point of view) difference beween writing
>>
>> v8::Handle<v8::String> x = ...
>> and
>> v8::Local<v8::String> y = ...
>
> There is no difference as far as I understand. These are just copies
> of existing handles. Especially, an assignment like this does _not_
> cause registration with a handle scope. Only Local::New does that.

Well, I am getting more and more puzzled :) This code:

v8::Handle<v8::String> x = v8::String::New("hello");

creates a new local handle which is not registered in current handle
scope? When is this JS value GC'ed then? Should I use this instead:

v8::Handle<v8::String> x =

v8::Handle<v8::String>::New(v8::String::New("hello")) ?


O.

Alex Iskander

unread,
Feb 18, 2009, 7:27:31 AM2/18/09
to v8-u...@googlegroups.com
What he means is that the assignment itself does not cause
registration in the handle scope, but New does.

So, in your example, v8::String::New creates a new local in your
handle scope. When you make an assignment to one of your variables,
nothing scope-related happens. It is simply a reference.

For example, the following would cause a crash:

HandleScope scope_1;
Handle<String> value;
{
HandleScope scope_2;

//create a local belonging to scope_2
Handle<String> temp = String::New("hello");

//set value to point to the local belonging to scope_2
value = temp;
}

//use value here... oops, can't, because it points to something
belonging to scope_2


Hope that clears things up,

Alex
Alex Iskander
Web and Marketing
TPSi




Søren Gjesse

unread,
Feb 19, 2009, 3:22:00 AM2/19/09
to v8-u...@googlegroups.com
Note that you can use the Close method on a HandleScope to have a handle escape to the outer HandleScope. This is normally used to return a handle from a function having its own HandleScope.

  Handle<String> GetFoo() {
    HandleScope scope;
    Handle<String> result = String::New("foo");
    return scope.Close(result);
  }

  main(...) {
    HandleScope scope;
    ...
    Handle<String> foo = GetFoo();
    ...
  }

Having a HandleScope in a function called should be the general rule as otherwise all handles created will get "stuck" in some outer HandleScope causing them to stay alive longer than expected.

In the example from Alex using

  value = scope_2.Close(temp)

will move temp to scope_1. After using Close scope_2 is invalid.

Regards,
Søren

Ondrej Zara

unread,
Feb 19, 2009, 5:22:08 AM2/19/09
to v8-u...@googlegroups.com
> Having a HandleScope in a function called should be the general rule as
> otherwise all handles created will get "stuck" in some outer HandleScope
> causing them to stay alive longer than expected.

But this is only true for non-callback functions, because those
specified as argument to FunctionTemplate receive a handle scope
automatically, correct?


O.

Søren Gjesse

unread,
Feb 20, 2009, 3:32:39 AM2/20/09
to v8-u...@googlegroups.com
Thats right, when callback functions are called a HandleScope is set up by the caller (e.g HandleApiCall in builtins.cc). However it might still be beneficial to use additional handle scopes in the callback code to avoid holding on to unused objects, e.g. in other functions called from the callback.

Regards,
Søren
Reply all
Reply to author
Forward
0 new messages