Hi, Anton,

Sorry for the confusion!


1. Through signature, we can get the right object when calling
info.Holder(). It will traverse the prototype chain and return the object
match the signature of the function. And then it can get its internal field
correctly. I might be wrong, however I got the concept of signature from the
thread:
http://groups.google.com/group/v8-users/browse_thread/thread/317f8845fd17d9a/a002fc8ebe8c0e84?lnk=gst&q=holder#a002fc8ebe8c0e84


The following is from chromium v8Htmlelement.cpp.
It use prototype inheritance  to construct a function template chain. It
used signature. Please check the underlined bold part.
By doing that it makes prototype of V8Node can access the DOM pointer
wrappered in internal field  of elements like V8HtmlTableElement.

static v8::Persistent<v8::FunctionTemplate> ConfigureV8HTMLElementTemplate(
v8::Persistent<v8::FunctionTemplate> desc) {
  v8::Local<v8::ObjectTemplate> instance = desc->InstanceTemplate();
  instance->SetInternalFieldCount(V8Custom::kNodeMinimumInternalFieldCount);
  v8::Local<v8::Signature> default_signature = v8::Signature::New(desc);
  v8::Local<v8::ObjectTemplate> proto = desc->PrototypeTemplate();
  /* no access check */
  batchConfigureAttributes(instance, proto, HTMLElement_attrs, sizeof(
HTMLElement_attrs)/sizeof(*HTMLElement_attrs));

// Function 'insertAdjacentHTML' (ExtAttr: '')
 * **proto**->**Set**(
      **v8**::**String**::**New**(**"insertAdjacentHTML"**),**
      **v8**::**FunctionTemplate**::**New**(**HTMLElementInternal**::**
insertAdjacentHTMLCallback**,** **v8**::**Handle**<**v8**::**Value**>**(),**
default_signature**),**
      **static_cast**<**v8**::**PropertyAttribute**>**(**v8**::**DontDelete*
*));*


 // Custom Signature 'insertAdjacentElement'
  const int insertAdjacentElement_argc = 2;
  v8::Handle<v8::FunctionTemplate> insertAdjacentElement_argv[
insertAdjacentElement_argc] = {v8::Handle<v8::FunctionTemplate>(), V8Element
::GetRawTemplate() };
  v8::Handle<v8::Signature> insertAdjacentElement_signature = v8::Signature
::New(desc, insertAdjacentElement_argc,insertAdjacentElement_argv);

  // Function 'insertAdjacentElement' (ExtAttr: '')
  proto->Set(
      v8::String::New("insertAdjacentElement"),
      v8::FunctionTemplate::New(HTMLElementInternal::
insertAdjacentElementCallback, v8::Handle<v8::Value>(),
insertAdjacentElement_signature),
      static_cast<v8::PropertyAttribute>(v8::DontDelete));


  // Function 'insertAdjacentText' (ExtAttr: '')
  proto->Set(
      v8::String::New("insertAdjacentText"),
      v8::FunctionTemplate::New(HTMLElementInternal::
insertAdjacentTextCallback, v8::Handle<v8::Value>(),default_signature),
      static_cast<v8::PropertyAttribute>(v8::DontDelete));
  desc->Inherit(V8DOMWrapper::getTemplate(V8ClassIndex::ELEMENT));
  desc->SetClassName(v8::String::New("HTMLElement"));
  return desc;
}


2. About the traversing problem.

When we called info.This(), we actually the handle of the prototype object,
right?
By current->GetPrototype(), we can only get the prototype of the prototype,
right?

As I wrappered the pointer in internal field of object, which inherit from
prototype object. It seems a reverse direction.

So, It puzzles me.


Really thanks for your precious time!

Sincerely~
Xiang







On Tue, Dec 1, 2009 at 9:41 PM, Anton Muhin <ant...@chromium.org> wrote:

> Xiang,
>
> what do you mean by signature for interceptors?  Interceptor could
> return any kind of the object it likes, e.g. interceptor for DOM HTML
> Document could return JS functions and plain fields.  Probably I just
> misunderstand what you're suggesting.
>
> Regarding traversing from this.  Technically that's the way JS
> works---if you'd like to lookup a property, you start your lookup from
> this and go through proto chain.  So you should be able to emulate
> that.  The trick is how to understand when you reached the proper
> object.  I might be missing something, but I don't remember if there
> is a way to check if the given object was created by the given object
> template (and alas, if there is no such thing, I cannot immediately
> tell how easy it'd be to implement).  To some extent you can emulate
> it in a hard way, something like that (do not expect that to compile):
>
>
> kObjectTemplateFieldIndex = 0;
>
> Handle<ObjectTemplate> myObjectTemplate;
>
> // Lookup code
>
> Handle<Object> current = args.This();
>
> while (true) {
>  if (current->GetInternalFieldCount() >= 2) {
>   Handle<Value> typeAsValue =
> current->GetInternalField(kObjectTemplateFieldIndex);
>   if (type->IsObjectTemplate() &&
> Hanlde<ObjectTemplate>::Cast(typeAsValue) == myObjectTemplate) {
>     return current->GetInternalField(1):
>   }
>  }
>
>  Handle<Value> proto = current->GetPrototype();
>  if (proto->IsNull()) break;
>  ASSERT(proto->IsObject());
>  current = Handle<Object>::Cast(proto);
> }
>
> // Creation code:
>
> object = myObjectTemplate::New();
> object->SetInternalField(kObjectTemplateFieldIndex, myObjectTemplate);
> object->SetInternalField(1, <your data>);
>
> I am sure there some shortcomings, but that probably should work.
> And, just in case, it won't be blazing fast.
>
> hth and yours,
> anton.
>
> On Tue, Dec 1, 2009 at 4:03 PM, Xiang Zhong <clock...@gmail.com> wrote:
> > And I also check the code of chromium binding.
> >
> > I found there are accessors for each attribute of all element, and the
> > implementation of these accessors are almost the same.
> > I think it would be very convenient if there is signature support
> > for interceptor in v8. By then chromium only have to bind all attribute
> > accessing through interceptor.
> >
> >
> >
> >
> > On Tue, Dec 1, 2009 at 8:59 PM, Xiang Zhong <clock...@gmail.com> wrote:
> >>
> >> Hi, Anton,
> >>
> >> Thanks for your clarification!
> >> I have to hook on the prototype, so that it is visible when other object
> >> inherit from this object.
> >> Is it true that the signature is a missed feature for Interceptor?
> >>
> >> And I am confused about traversing the This of AccessorInfo.
> >> It is easy to get __proto__ of one object, but how can we find the
> object
> >> itself through its prototype?
> >>
> >>
> >> Thanks~
> >> Cheers~
> >> Xiang
> >>
> >>
> >>
> >>
> >>
> >>
> >>
> >> On Tue, Dec 1, 2009 at 8:49 PM, Anton Muhin <ant...@chromium.org>
> wrote:
> >>>
> >>> Good day, Xiang.
> >>>
> >>> First of all, I think you'd better off keeping an interceptor on the
> >>> objects.  If you're still determined to keep it on the prototype, you
> >>> should be able to find an object, but you will have to traversal from
> >>> the This of AccessorInfo.  Please note that is somewhat fragile as one
> >>> can change prototype chain.
> >>>
> >>> yours,
> >>> anton.
> >>>
> >>> On Tue, Dec 1, 2009 at 3:11 PM, Xiang Zhong <clock...@gmail.com>
> wrote:
> >>> > Hi, All,
> >>> > There are two object involved:
> >>> > Prototype
> >>> >    ^
> >>> >    |
> >>> >    |
> >>> > Object
> >>> >
> >>> > I set interceptor on prototype template, and have set internal field
> on
> >>> > Object.
> >>> > Is there a way to access these internal field of Object in
> intercrptor
> >>> > of
> >>> > Prototype?
> >>> >
> >>> >
> >>> > For Accessor, there is a way to define signature, then the VM will
> pass
> >>> > the
> >>> > right object to accessor, how about inteceptors?
> >>> >
> >>> > Please check the following sample, it will crash if I try a access
> the
> >>> > internal filed.
> >>> >
> >>> > #include <v8.h>
> >>> > #include <iostream>
> >>> > #include <fstream>
> >>> > #include <sstream>
> >>> > #include <cmath>
> >>> > using namespace v8;
> >>> > v8::Handle<v8::Value> Getter(v8::Local<v8::String> propertyName,const
> >>> > v8::AccessorInfo &info) {
> >>> >    v8::HandleScope handleScope;
> >>> >     v8::Handle<v8::External> external =
> >>> > v8::Handle<v8::External>::Cast(info.Holder()->GetInternalField(0));
> >>> >     void * message = external->Value();
> >>> >     const char * str =  (const char *)message;
> >>> >     printf(str);
> >>> >     //return something that is not NULL back
> >>> >     return v8::True();
> >>> > }
> >>> > Handle<Value> CreateObjectWithInteceptor(const Arguments& args)
> >>> > {
> >>> >     HandleScope handleScope;
> >>> >     const char * test = "With Inteceptor";
> >>> >     v8::Handle<v8::External> external = v8::External::New((void
> >>> > *)test);
> >>> >     args.Holder()->SetInternalField(0, external);
> >>> >     return args.Holder();
> >>> > }
> >>> > int main()
> >>> > {
> >>> > HandleScope handleScope;
> >>> >
> >>> >   Handle<FunctionTemplate> functionTemplate =
> >>> > FunctionTemplate::New(CreateObjectWithInteceptor);
> >>> >
> >>> >
> functionTemplate->SetClassName(String::New("CreateObjectWithInteceptor"));
> >>> > v8::Local<v8::Signature> default_signature =
> >>> > v8::Signature::New(functionTemplate);
> >>> > Handle<ObjectTemplate> instanceTemplate =
> >>> > functionTemplate->InstanceTemplate();
> >>> > instanceTemplate->SetInternalFieldCount(1); // create an internal
> field
> >>> > for
> >>> > the C++ object
> >>> > Handle<ObjectTemplate> prot = functionTemplate->PrototypeTemplate();
> >>> > prot->SetNamedPropertyHandler(Getter);
> >>> >
> >>> > Handle<ObjectTemplate> globals = ObjectTemplate::New();
> >>> >   globals->Set(String::New("object"), instanceTemplate); // add our
> >>> > print
> >>> > function
> >>> > Persistent<Context> context = Context::New(0, globals);
> >>> > Context::Scope contextScope(context);
> >>> > Handle<Script> script =
> >>> > Script::Compile(v8::String::New("object.getValue"));
> >>> > Handle<Value> result = script->Run();
> >>> > context.Dispose();
> >>> > return 0;
> >>> > }
> >>> >
> >>> > Cheers~
> >>> > Xiang
> >>> >
> >>> > --
> >>> > v8-dev mailing list
> >>> > v8-dev@googlegroups.com
> >>> > http://groups.google.com/group/v8-dev
> >>>
> >>> --
> >>> v8-dev mailing list
> >>> v8-dev@googlegroups.com
> >>> http://groups.google.com/group/v8-dev
> >
> > --
> > v8-dev mailing list
> > v8-dev@googlegroups.com
> > http://groups.google.com/group/v8-dev
>
> --
> v8-dev mailing list
> v8-dev@googlegroups.com
> http://groups.google.com/group/v8-dev
>

-- 
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

Reply via email to