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 }