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.