What is the difference between Arguments::Holder() and Arguments::This()?

1,595 views
Skip to first unread message

Stephan Beal

unread,
Mar 8, 2009, 10:12:27 AM3/8/09
to v8-users
The subject line says it all!

Does "holder" mean "the object of which the callee is a member"? If
so, how is that different from This(). If not, how is Holder() it
different from This()?

:-?

Alex Iskander

unread,
Mar 8, 2009, 12:25:53 PM3/8/09
to v8-u...@googlegroups.com
I can't quite tell the difference, even after looking through the v8 source code in builtins.cc, etc., which creates Arguments objects.

The code confuses me, but they look like they could be the same. The internal arvg pointer's member at [0] is used to create the Holder (after some checking to ensure it is valid, etc.). The argv array, changed by (argv - 1), is then passed to the actual arguments. To access "This", argv uses (argv + 1).

It looks like they come from the same source, but like Holder has a lot of extra processing. Perhaps it has something to do with how Holder is guaranteed to be an Object, while This is a Value.

Alex
Alex Iskander, TPSi




Christian 'Little Jim' Plesner

unread,
Mar 9, 2009, 3:46:31 AM3/9/09
to v8-u...@googlegroups.com
The value you get when calling 'This' is what would have been bound to
'this' if the function had been an ordinary javascript function.

The Holder value was introduced to deal with some corner cases that
happen because methods are just properties and can be moved around.
To explain it you need a bit of background but I'll get to the Holder
part in minute.

Consider this code:

var x = { };
x.createElement = document.createElement;
var div = x.createElement('div');

In the implementation of createElement we need to check what kind of
object we're being called on because createElement needs to use some
internal fields stored on the document object. To implement this we
use function signatures (by passing a Signature object to
FunctionTemplate::New for all dom methods). A signature specifies
what kind of objects a function can be called with. In this case we
would pass a signature that specifies that the receiver must be a
document and then v8 takes case of giving an error if it isn't.

However, with this type check in place there can still be problems.
Consider this code:

var x = { }
x.__proto__ = document;
var div = x.createElement('div');

In this case createElement is actually given a document, it's there in
the prototype chain, and for compatibility reasons we have to allow
this. However, 'This' is not a document so it's still not safe to try
to read internal fields from it. That's where Holder comes in. If
your function has a signature that says that it must be called on a
particular type v8 will search the prototype chain for an object of
that type when the function is called. If it is not there we given an
error. If it is there that's the value Holder will return to you.

In short: if you specify, through a Signature, that a function must
only be called on instances of function template T, the value returned
by Holder is guaranteed to hold an instance created from T or another
function template that directly or indirectly
"FunctionTemplate::Inherit"s from T. No guarantees hold about the
type of This.


-- Christian

Zac Hansen

unread,
May 29, 2017, 4:27:53 AM5/29/17
to v8-users, ple...@google.com
This post is not (or at least no longer) correct.

Holder only works if you have inherited in FunctionTemplate::Inherit, not if you use "javascript inheritance" as described:  x.__proto__ = document; x.createElement(...) <=== illegal invocation
Reply all
Reply to author
Forward
0 new messages