Context issue when calling ExecuteFunction asynchronously

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Context issue when calling ExecuteFunction asynchronously

Postby gusverdun » Thu Feb 10, 2011 5:01 pm

I have a CefV8Handler object that I call from JS and pass in a callback function. The handler does some work and responds asynchronously by calling ExecuteFunction on that callback object. (Note: this is called outside the scope of Execute or HandleJSBinding).

I crash if try to change document.location or an exception occurs during in the callback.

firstwindow calls v8::Context::GetEntered() which returns a null pointer for the context. Is there a way to ensure this gets set when I callback into JS?

Here is the call stack at the point of the crash:

> libcef.dll!v8::internal::Handle<v8::internal::Object>::operator*() Line 49 + 0x5 bytes C++
libcef.dll!v8::internal::Handle<v8::internal::Context>::cast<v8::internal::Object>(v8::internal::Handle<v8::internal::Object> that={...}) Line 80 + 0x8 bytes C++
libcef.dll!v8::Context::Global() Line 3489 + 0x18 bytes C++
libcef.dll!WebCore::V8Proxy::retrieveWindow(v8::Handle<v8::Context> context={...}) Line 530 + 0x13 bytes C++
libcef.dll!WebCore::State<WebCore::V8Binding>::firstWindow() Line 60 + 0x1a bytes C++
libcef.dll!WebCore::V8DOMWindowShell::setLocation(WebCore::DOMWindow * window=0x0033b4e8, const WTF::String & locationString={...}) Line 594 + 0xa bytes C++
libcef.dll!WebCore::V8Document::locationAccessorSetter(v8::Local<v8::String> name={...}, v8::Local<v8::Value> value={...}, const v8::AccessorInfo & info={...}) Line 53 + 0x20 bytes C++
libcef.dll!v8::internal::JSObject::SetPropertyWithCallback(v8::internal::Object * structure=0x02f94b99, v8::internal::String * name=0x02b9ac4d, v8::internal::Object * value=0x0704abb5, v8::internal::JSObject * holder=0x0703e3d1) Line 1640 + 0x35 bytes C++
libcef.dll!v8::internal::JSObject::SetProperty(v8::internal::LookupResult * result=0x0023e500, v8::internal::String * name=0x02b9ac4d, v8::internal::Object * value=0x0704abb5, PropertyAttributes attributes=NONE) Line 1948 + 0x22 bytes C++
libcef.dll!v8::internal::JSObject::SetProperty(v8::internal::String * name=0x02b9ac4d, v8::internal::Object * value=0x0704abb5, PropertyAttributes attributes=NONE) Line 1599 C++
libcef.dll!v8::internal::StoreIC::Store(v8::internal::InlineCacheState state=UNINITIALIZED, v8::internal::Handle<v8::internal::Object> object={...}, v8::internal::Handle<v8::internal::String> name={...}, v8::internal::Handle<v8::internal::Object> value={...}) Line 1392 C++
libcef.dll!v8::internal::StoreIC_Miss(v8::internal::Arguments args={...}) Line 1710 + 0x3f bytes C++
24bf028e()
libcef.dll!v8::internal::Invoke(bool construct=false, v8::internal::Handle<v8::internal::JSFunction> func={...}, v8::internal::Handle<v8::internal::Object> receiver={...}, int argc=3, v8::internal::Object * * * args=0x00351360, bool * has_pending_exception=0x0023e7cf) Line 97 + 0x19 bytes C++
libcef.dll!v8::internal::Execution::Call(v8::internal::Handle<v8::internal::JSFunction> func={...}, v8::internal::Handle<v8::internal::Object> receiver={...}, int argc=3, v8::internal::Object * * * args=0x00351360, bool * pending_exception=0x0023e7cf) Line 123 + 0x1f bytes C++
libcef.dll!v8::Function::Call(v8::Handle<v8::Object> recv={...}, int argc=3, v8::Handle<v8::Value> * argv=0x00351360) Line 2901 + 0x1d bytes C++
libcef.dll!CefV8ValueImpl::ExecuteFunction(CefRefPtr<CefV8Value> object={...}, const std::vector<CefRefPtr<CefV8Value>,std::allocator<CefRefPtr<CefV8Value> > > & arguments=[3]({ptr_=0x003c8390 },{ptr_=0x06636b28 },{ptr_=0x00351290 }), CefRefPtr<CefV8Value> & retval={...}, CefStringBase<CefStringTraitsUTF16> & exception={...}) Line 686 C++
libcef.dll!v8value_execute_function(_cef_v8value_t * self=0x003c402c, _cef_v8value_t * object=0x066374e4, unsigned int argumentCount=3, _cef_v8value_t * const * arguments=0x00283520, _cef_v8value_t * * retval=0x0023eb00, _cef_string_utf16_t * exception=0x00282e40) Line 390 + 0x4b bytes C++

1. What am I doing wrong? :)
2. What is the proper "object" I should pass in to the ExecuteFunction call? I tried using the object I got from the HandleJSBinding call and just an empty object I created at the time I was in the Execute callback and both had the same results.
gusverdun
Techie
 
Posts: 25
Joined: Tue Jan 11, 2011 9:08 am

Re: Context issue when calling ExecuteFunction asynchronously

Postby magreenblatt » Thu Feb 10, 2011 5:45 pm

You cannot access V8 objects outside of scope. Use CefFrame::ExecuteJavaScript instead to execute your asynchronous callback.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Context issue when calling ExecuteFunction asynchronously

Postby gusverdun » Fri Feb 11, 2011 12:09 pm

It would be very powerful if we could invoke a v8::Function at any time. This is done often in many of the web APIs of Chrome and Node.js is a master at asynchronous-callbacks into V8.

Perhaps at a simple level (and I have to admit my v8-fu is lacking, but growing), would it be enough if we expand CefV8Value / CefV8Handler to store and use the v8::Handle<v8::Context> that it is in when it got called into a CefV8Handler and attach it to any function object as a Cef::Context property? The ExecuteFunction method can then set the context from that property when the function is invoked.

This, I assume, would solve the problem for simple function callback objects, for an object that has functions, we would need to think of something else to avoid attaching the Cef::Context property on every object.

Perhaps, we can create a CefV8Context object that is passed in to the CefV8Handler so that clients can get the context for all the objects received in that call. With that we could add a CefV8Value::ExecuteFunctionWithContext method that can make user of the CefV8Context.

I'd be happy to try this out. Thoughts?

Thanks,

Gus
gusverdun
Techie
 
Posts: 25
Joined: Tue Jan 11, 2011 9:08 am

Re: Context issue when calling ExecuteFunction asynchronously

Postby magreenblatt » Fri Feb 11, 2011 5:46 pm

If you can make it work I have no immediate objections.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: Context issue when calling ExecuteFunction asynchronously

Postby gusverdun » Mon Feb 14, 2011 3:44 pm

I opened an issue and submitted a patch to fix this. :)

http://code.google.com/p/chromiumembedded/issues/detail?id=188

Thanks,

Gus
gusverdun
Techie
 
Posts: 25
Joined: Tue Jan 11, 2011 9:08 am


Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 53 guests