Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

This vs. Holder for ObjectWrap::Unwrap

The v8::FunctionCallbackInfo class distinguishes between This and Holder. I know what this is in JavaScript, and assume that This reflects that setting. But I have only a vague notion of what Holder is, and very little idea as to when I should use Holder instead of This.

In particular, when writing a nan-based node.js extension and unwrapping an ObjectWrap, which of these should I pass?

Currently node::ObjectWrap documentation has examples using Holder while current Nan::ObjectWrap documentation uses This, so “just follow the examples in the documentation” doesn't help answering this question.

like image 557
MvG Avatar asked Oct 19 '22 20:10

MvG


1 Answers

While writing the question above, I did some more digging and eventually found some relevant threads on the v8-users Google Group. I'll quote a short portion of the two posts which seem most relevant to me, but they are taken out of context, so the containing threads may well be worth reading for further information. Formatting markup added by me.

Christian 'Little Jim' Plesner wrote in 2009:

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::Inherits from T. No guarantees hold about the type of This.

This statement is referenced by Stephan Beal in 2010. Later in that same thread, Anton Muhin wrote:

Overall Holder should be always in the prototype chain of This and hence if you read the property, you can freely use both. However setting the property would behave differently if This() != Holder() — the property would end at different object.

This aspect is again repeated by Ben Noordhuis in 2014.

The first statement seems to suggest that Holder is correct and nan documentation should be changed. The latter reminds us that in general, This is more appropriate unless one is directly interacting with some internal state like ObjectWrap does.

The example given in the first of the quoted posts about how This could be of an unexpected type was the following:

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

For that he wrote that “for compatibility reasons we have to allow this”. Trying the same with a nan-based extension type (from the nan test suite) I find that these days the above appears to result in a TypeError: Illegal invocation. So apparently the signature verification semantics have changed somewhat. It doesn't seem to matter much for ObjectWrap::Unwrap these days whether you use This or Holder. Things look different for Node 0.10, though, so I think Holder should be preferred at least for methods, and filed nan pull request #524 about this.

The situation for accessors is much more complicated. Using Holder() won't work for accessors installed on the prototype, so apparently one either has to install accessors on the instance template, or use This and do some manual type checking.

like image 57
MvG Avatar answered Oct 21 '22 14:10

MvG