On Tue, May 17, 2016 at 12:22 AM, Ryan Ingram <[email protected]> wrote:
> What am I doing wrong here?  Does FunctionTemplate only support primitives
> for callback data?  (Its type should suggest that, if so...)
>
> I'm trying to register native functions to be called back in my embedder,
> but my function callback data is getting corrupted.  I tried saving off the
> data passed to FunctionTemplate::New and I'm not getting the same data in my
> callback!
>
> Here's a code snippet:
>
> v8::Persistent<v8::Value> gDebugData;
>
> void RegisterTestFunction( v8::Handle<v8::String> name, v8::Isolate*
> isolate, v8::Context* context )
> {
>     v8::Local<v8::Object> data = v8::Object::New(isolate); // In the actual
> code this is SomeFunctionTemplate->InstanceTemplate()->NewInstance()
>     gDebugData.Reset(isolate, data); // save off pointer for debugging
>
>     v8::Local<v8::FunctionTemplate> template =
> FunctionTemplate::New(isolate, &TestFunctionCallback, data);
>     context->Enter();
>     context->Global()->Set( name, template->GetFunction() );
>     context->Exit();
> }
>
> void TestFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>
> &arguments)
> {
>     v8::Isolate* isolate = arguments.GetIsolate();
>
>     // Let's get our context
>     v8::Local<v8::Value> dataValue = arguments.Data();
>     assert( dataValue->IsObject() ); // Fails??
>
>     // Hmm, let's look at our original context variable...
>     v8::Local<v8::Value> expectedDataValue = v8::Local<v8::Value>::New(
> isolate, gDebugData );
>     assert( dataValue == expectedDataValue ); // Also fails...
>
>     assert( expectedDataValue->IsObject() ); // The original pointer is
> still valid...
>
>     // Lets find out what we are getting passed
>     v8::TryCatch tryCatch;
>
>     // This function crashes...
>     v8::Local<v8::String> whatIsIt = dataValue->ToString();
>
>     if(tryCatch.HasCaught() { tryCatch.ReThrow(); return; }
> }
>
> Crash callstack:
>   3eb50f46()
>   3eb483e1()
>   3eb2fa55()
>   3eb2b8ea()
>   v8.dll!v8::internal::Invoke(bool is_construct,
> v8::internal::Handle<v8::internal::JSFunction> function,
> v8::internal::Handle<v8::internal::Object> receiver, int argc,
> v8::internal::Handle<v8::internal::Object> * args)  Line 108 C++
>   v8.dll!v8::internal::Execution::Call(v8::internal::Isolate * isolate,
> v8::internal::Handle<v8::internal::Object> callable,
> v8::internal::Handle<v8::internal::Object> receiver, int argc,
> v8::internal::Handle<v8::internal::Object> * argv, bool convert_receiver)
> Line 157 + 0x13 bytes C++
>   v8.dll!v8::internal::Execution::ToString(v8::internal::Isolate * isolate,
> v8::internal::Handle<v8::internal::Object> obj)  Line 517 + 0x95 bytes C++
>   v8.dll!v8::Value::ToString()  Line 2594 + 0x9 bytes C++
>
> If I use "expectedDataValue" in my callback, everything works as desired.
> But that's not getting passed through to the FunctionCallbackInfo.
>
> I am on a relatively old version of v8 (3.30).  Is there a way to tell what
> is inside of dataValue's handle more safely?  In the debugger it has a
> pointer value, although it doesn't look particularly valid...
>
> dataValue
>     v8::Handle<v8::Value> {val_=0x0023d608 }
> expectedDataValue
>     v8::Handle<v8::Value> {val_=0x128daab0 }
> gDebugData
>     v8::PersistentBase<v8::Value> {val_=0x128d6a90 }

I see you've logged [0].  I can't comment on V8 3.30 (too old) but
newer versions forbid anything that is not a primitive or a template
through a run-time check.

It makes sense in a way because objects are owned by their creating
context while templates are context-independent.

[0] https://bugs.chromium.org/p/v8/issues/detail?id=1503#c4

-- 
-- 
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