So I decided to check the prototype of the object I'm getting from Holder, 
and lo and behold, there's my object.   But now the question remains, how 
am I supposed to figure out how far down the prototype chain I need to go?

Updated code including link to line where I don't know what I'm supposed to 
do:

https://gist.github.com/xaxxon/e0add46f332ab2e2b39c#file-updated-cpp-L34

--Zac


On Tuesday, February 16, 2016 at 5:34:36 AM UTC-8, Zac Hansen wrote:
>
> Just double checked what I was seeing before and I got something wrong.  
>
> When I get the callback when being used as a prototype, the ClassName 
> isn't set to MyClass, it's just [object object].   But I don't understand 
> why.
>
> On Tuesday, February 16, 2016 at 3:05:57 AM UTC-8, Zac Hansen wrote:
>>
>> Here's a reproduction case with pure V8 API code  
>> https://gist.github.com/xaxxon/4bd2abb161ea2253e68d reproduced below
>>
>> output:  
>>
>> In some_function
>>
>> Allocating int at 0x7f9c12700520
>>
>> uncasted internal field: 0x7f9c12700520
>>
>> In some_function
>>
>> Allocating int at 0x7f9c127004b0
>>
>> uncasted internal field: 0x0
>>
>>
>> source:
>>
>> #include "include/libplatform/libplatform.h"
>>> #include "include/v8.h"
>>> class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
>>>  public:
>>>   inline virtual void* Allocate(size_t length) override {
>>>     void* data = AllocateUninitialized(length);
>>>     return data == NULL ? data : memset(data, 0, length);
>>>   }
>>>   inline virtual void* AllocateUninitialized(size_t length) override { 
>>> return malloc(length); }
>>>   inline virtual void Free(void* data, size_t) override { free(data); }
>>> };
>>>
>>>
>>> void MyClass(const v8::FunctionCallbackInfo<v8::Value> & info) {
>>>   printf("In some_function\n");
>>>   auto js_object = info.This();
>>>   int * i = new int();
>>>   printf("Allocating int at %p\n", i);
>>>
>>>   js_object->SetInternalField(0, v8::External::New(info.GetIsolate(),i));
>>> }
>>> void do_something(const v8::FunctionCallbackInfo<v8::Value> & info) {
>>>   auto self = info.Holder();
>>>   auto wrap = v8::Local<v8::External>::Cast(self->GetInternalField(0));
>>>   printf("uncasted internal field: %p\n", wrap->Value());
>>>   
>>> }
>>> int main(int argc, char ** argv)
>>> {
>>>       v8::V8::InitializeICU();
>>>       auto platform = v8::platform::CreateDefaultPlatform();
>>>       v8::V8::InitializePlatform(platform);
>>>       v8::V8::Initialize();
>>>       v8::Isolate::CreateParams create_params;
>>>       create_params.array_buffer_allocator = (v8::ArrayBuffer::Allocator 
>>> *) new ArrayBufferAllocator();
>>>       auto i = v8::Isolate::New(create_params);
>>>       {
>>> v8::Isolate::Scope is(i);
>>> v8::HandleScope hs(i);
>>> auto got = v8::ObjectTemplate::New(i);
>>> auto ft = v8::FunctionTemplate::New(i, MyClass);
>>> ft->InstanceTemplate()->SetInternalFieldCount(1);
>>> got->Set(i, "MyClass", ft);
>>> auto ft2 = v8::FunctionTemplate::New(i, do_something);
>>> ft->InstanceTemplate()->Set(i, "do_something", ft2);
>>> auto c = v8::Context::New(i, nullptr, got);
>>> v8::Context::Scope cs(c);
>>>
>>> auto s = v8::Script::Compile(c, v8::String::NewFromUtf8(i,"new 
>>> MyClass().do_something(); Object.create(new 
>>> MyClass()).do_something();")).ToLocalChecked();
>>> (void)s->Run(c);
>>>       }
>>> }
>>
>>
>> On Tuesday, February 16, 2016 at 2:05:08 AM UTC-8, Zac Hansen wrote:
>>>
>>> I have a functiontemplate for the C++ class MyClass, and its objects 
>>> have a MyClass method mymethod in their prototype.
>>>
>>> I can create that object in javascript and call it and it calls back 
>>> into the mymethod FunctionTemplate callback:
>>>
>>> mc = new MyClass(); mc.mymethod();  <== works fine
>>>
>>>
>>> But if I try to create an object with that as its prototype:
>>>
>>> child = Object.create(new MyClass()); child.mymethod();
>>>
>>>
>>> In the mymethod FunctionTemplate, the object contained in info.Holder() 
>>> (and info.This()) has a .GetInternalField(0) == nullptr;
>>>
>>> I added a ClassName to the MyClass FunctionTemplate constructor and in 
>>> the call to 
>>>
>>> child.mymethod();
>>>
>>>
>>> if I print out *v8::String::Utf8Value(info.Holder()); in the mymethod 
>>> callback that is about to fail, I get "MyClass".
>>>
>>> then I added a data member "int i = rand()" to MyClass and in the 
>>> callback for mymethod() that has a nullptr in its internalfield, if I call 
>>> holder().get(context, "i"), that goes to my c++ getter function and looks 
>>> up the internal field just fine and returns the correct answer.
>>>
>>> I'm exceptionally confused.
>>>
>>> Thank you for any help.
>>>
>>> --Zac
>>>
>>

-- 
-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to