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.
