Hi, Anton,
I've checked. You are right about info.This(). I am ashamed to make that mistake:) About the signature, I need more time to think carefully. Thanks and best wishes:) Cheers~ Xiang On Tue, Dec 1, 2009 at 10:22 PM, Anton Muhin <ant...@google.com> wrote: > On Tue, Dec 1, 2009 at 5:15 PM, Xiang Zhong <clock...@gmail.com> wrote: > > 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; > > } > > Correct me if I am wrong, but signature describes parameters a > function could handle when called. So, as interceptor can return not > only functions, but plain properties, it's somewhat less obvious to me > how signature check would help here. Actually, when v8 calls into > native functions it performs a traversal of the kind I described: > starting from this aka receiver it goes down the prototype chain > looking for object which is instance of for the given function (?) > template. As I am not sure if we support such a check for object > templates, I suggested a workaround below. > > > > > 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. > > Sorry, could you check it? I would expect This to be not a prototype, > but the object on which the property is accessed. E.g. if you had o_1 > -> o_2 -> o_3 -> o_4 where o_4 is your prototype and o_3 your object, > code o_1.foo() would call into interceptor (which is on o_4) with > Holder o_4 and This o_1, but I might have missed something. (and -> > stands for proto). > > > Really thanks for your precious time! > > You're welcome. > > yours, > anton. > > > > > > > > > > > > > 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 > > -- > 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