Allow creation of V8 wrapper objects on any thread with a V8 isolate (issue #451).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@967 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2012-12-30 21:16:59 +00:00
parent e33ea0aff4
commit e574751caa
4 changed files with 213 additions and 169 deletions

View File

@ -105,8 +105,10 @@ CEF_EXPORT int cef_register_extension(const cef_string_t* extension_name,
const cef_string_t* javascript_code, struct _cef_v8handler_t* handler); const cef_string_t* javascript_code, struct _cef_v8handler_t* handler);
/// ///
// Structure that encapsulates a V8 context handle. The functions of this // Structure representing a V8 context handle. Static functions may only be
// structure may only be called on the render process main thread. // called on a render process thread that has entered a V8 isolate (usually the
// render process main thread). Non-static functions may only be called on the
// thread that initially returned the handle.
/// ///
typedef struct _cef_v8context_t { typedef struct _cef_v8context_t {
/// ///
@ -115,8 +117,9 @@ typedef struct _cef_v8context_t {
cef_base_t base; cef_base_t base;
/// ///
// Returns true (1) if this object is valid. Do not call any other functions // Returns true (1) if the underlying handle is valid and it can be accessed
// if this function returns false (0). // on the current thread. Do not call any other functions if this function
// returns false (0).
/// ///
int (CEF_CALLBACK *is_valid)(struct _cef_v8context_t* self); int (CEF_CALLBACK *is_valid)(struct _cef_v8context_t* self);
@ -190,8 +193,8 @@ CEF_EXPORT int cef_v8context_in_context();
/// ///
// Structure that should be implemented to handle V8 function calls. The // Structure that should be implemented to handle V8 function calls. The
// functions of this structure will always be called on the render process main // functions of this structure will only be called on a render process thread
// thread. // that the handler was registered on.
/// ///
typedef struct _cef_v8handler_t { typedef struct _cef_v8handler_t {
/// ///
@ -216,8 +219,8 @@ typedef struct _cef_v8handler_t {
/// ///
// Structure that should be implemented to handle V8 accessor calls. Accessor // Structure that should be implemented to handle V8 accessor calls. Accessor
// identifiers are registered by calling cef_v8value_t::set_value_byaccessor(). // identifiers are registered by calling cef_v8value_t::set_value_byaccessor().
// The functions of this structure will always be called on the render process // The functions of this structure will only be called on a render process
// main thread. // thread that the accessor was registered on.
/// ///
typedef struct _cef_v8accessor_t { typedef struct _cef_v8accessor_t {
/// ///
@ -250,7 +253,8 @@ typedef struct _cef_v8accessor_t {
/// ///
// Structure representing a V8 exception. // Structure representing a V8 exception. The functions of this structure may be
// called on any render process thread.
/// ///
typedef struct _cef_v8exception_t { typedef struct _cef_v8exception_t {
/// ///
@ -313,8 +317,10 @@ typedef struct _cef_v8exception_t {
/// ///
// Structure representing a V8 value. The functions of this structure may only // Structure representing a V8 value handle. Static functions may only be called
// be called on the render process main thread. // on a render process thread that has entered a V8 isolate (usually the render
// process main thread). Non-static functions may only be called on the thread
// that initially returned the handle.
/// ///
typedef struct _cef_v8value_t { typedef struct _cef_v8value_t {
/// ///
@ -323,8 +329,9 @@ typedef struct _cef_v8value_t {
cef_base_t base; cef_base_t base;
/// ///
// Returns true (1) if this object is valid. Do not call any other functions // Returns true (1) if the underlying handle is valid and it can be accessed
// if this function returns false (0). // on the current thread. Do not call any other functions if this function
// returns false (0).
/// ///
int (CEF_CALLBACK *is_valid)(struct _cef_v8value_t* self); int (CEF_CALLBACK *is_valid)(struct _cef_v8value_t* self);
@ -713,8 +720,10 @@ CEF_EXPORT cef_v8value_t* cef_v8value_create_function(const cef_string_t* name,
/// ///
// Structure representing a V8 stack trace. The functions of this structure may // Structure representing a V8 stack trace handle. Static functions may only be
// only be called on the render process main thread. // called on a render process thread that has entered a V8 isolate (usually the
// render process main thread). Non-static functions may only be called on the
// thread that initially returned the handle.
/// ///
typedef struct _cef_v8stack_trace_t { typedef struct _cef_v8stack_trace_t {
/// ///
@ -723,8 +732,9 @@ typedef struct _cef_v8stack_trace_t {
cef_base_t base; cef_base_t base;
/// ///
// Returns true (1) if this object is valid. Do not call any other functions // Returns true (1) if the underlying handle is valid and it can be accessed
// if this function returns false (0). // on the current thread. Do not call any other functions if this function
// returns false (0).
/// ///
int (CEF_CALLBACK *is_valid)(struct _cef_v8stack_trace_t* self); int (CEF_CALLBACK *is_valid)(struct _cef_v8stack_trace_t* self);
@ -749,8 +759,10 @@ CEF_EXPORT cef_v8stack_trace_t* cef_v8stack_trace_get_current(int frame_limit);
/// ///
// Structure representing a V8 stack frame. The functions of this structure may // Structure representing a V8 stack frame handle. Static functions may only be
// only be called on the render process main thread. // called on a render process thread that has entered a V8 isolate (usually the
// render process main thread). Non-static functions may only be called on the
// thread that initially returned the handle.
/// ///
typedef struct _cef_v8stack_frame_t { typedef struct _cef_v8stack_frame_t {
/// ///
@ -759,8 +771,9 @@ typedef struct _cef_v8stack_frame_t {
cef_base_t base; cef_base_t base;
/// ///
// Returns true (1) if this object is valid. Do not call any other functions // Returns true (1) if the underlying handle is valid and it can be accessed
// if this function returns false (0). // on the current thread. Do not call any other functions if this function
// returns false (0).
/// ///
int (CEF_CALLBACK *is_valid)(struct _cef_v8stack_frame_t* self); int (CEF_CALLBACK *is_valid)(struct _cef_v8stack_frame_t* self);

View File

@ -116,8 +116,10 @@ bool CefRegisterExtension(const CefString& extension_name,
/// ///
// Class that encapsulates a V8 context handle. The methods of this class may // Class representing a V8 context handle. Static methods may only be called
// only be called on the render process main thread. // on a render process thread that has entered a V8 isolate (usually the render
// process main thread). Non-static methods may only be called on the thread
// that initially returned the handle.
/// ///
/*--cef(source=library)--*/ /*--cef(source=library)--*/
class CefV8Context : public virtual CefBase { class CefV8Context : public virtual CefBase {
@ -141,8 +143,9 @@ class CefV8Context : public virtual CefBase {
static bool InContext(); static bool InContext();
/// ///
// Returns true if this object is valid. Do not call any other methods if this // Returns true if the underlying handle is valid and it can be accessed on
// method returns false. // the current thread. Do not call any other methods if this method returns
// false.
/// ///
/*--cef()--*/ /*--cef()--*/
virtual bool IsValid() =0; virtual bool IsValid() =0;
@ -207,7 +210,8 @@ typedef std::vector<CefRefPtr<CefV8Value> > CefV8ValueList;
/// ///
// Interface that should be implemented to handle V8 function calls. The methods // Interface that should be implemented to handle V8 function calls. The methods
// of this class will always be called on the render process main thread. // of this class will only be called on a render process thread that the handler
// was registered on.
/// ///
/*--cef(source=client)--*/ /*--cef(source=client)--*/
class CefV8Handler : public virtual CefBase { class CefV8Handler : public virtual CefBase {
@ -230,7 +234,8 @@ class CefV8Handler : public virtual CefBase {
/// ///
// Interface that should be implemented to handle V8 accessor calls. Accessor // Interface that should be implemented to handle V8 accessor calls. Accessor
// identifiers are registered by calling CefV8Value::SetValue(). The methods // identifiers are registered by calling CefV8Value::SetValue(). The methods
// of this class will always be called on the render process main thread. // of this class will only be called on a render process thread that the
// accessor was registered on.
/// ///
/*--cef(source=client)--*/ /*--cef(source=client)--*/
class CefV8Accessor : public virtual CefBase { class CefV8Accessor : public virtual CefBase {
@ -263,7 +268,8 @@ class CefV8Accessor : public virtual CefBase {
}; };
/// ///
// Class representing a V8 exception. // Class representing a V8 exception. The methods of this class may be called on
// any render process thread.
/// ///
/*--cef(source=library)--*/ /*--cef(source=library)--*/
class CefV8Exception : public virtual CefBase { class CefV8Exception : public virtual CefBase {
@ -324,8 +330,10 @@ class CefV8Exception : public virtual CefBase {
}; };
/// ///
// Class representing a V8 value. The methods of this class may only be called // Class representing a V8 value handle. Static methods may only be called on a
// on the render process main thread. // render process thread that has entered a V8 isolate (usually the render
// process main thread). Non-static methods may only be called on the thread
// that initially returned the handle.
/// ///
/*--cef(source=library)--*/ /*--cef(source=library)--*/
class CefV8Value : public virtual CefBase { class CefV8Value : public virtual CefBase {
@ -415,8 +423,9 @@ class CefV8Value : public virtual CefBase {
CefRefPtr<CefV8Handler> handler); CefRefPtr<CefV8Handler> handler);
/// ///
// Returns true if this object is valid. Do not call any other methods if this // Returns true if the underlying handle is valid and it can be accessed on
// method returns false. // the current thread. Do not call any other methods if this method returns
// false.
/// ///
/*--cef()--*/ /*--cef()--*/
virtual bool IsValid() =0; virtual bool IsValid() =0;
@ -755,8 +764,10 @@ class CefV8Value : public virtual CefBase {
}; };
/// ///
// Class representing a V8 stack trace. The methods of this class may only be // Class representing a V8 stack trace handle. Static methods may only be called
// called on the render process main thread. // on a render process thread that has entered a V8 isolate (usually the render
// process main thread). Non-static methods may only be called on the thread
// that initially returned the handle.
/// ///
/*--cef(source=library)--*/ /*--cef(source=library)--*/
class CefV8StackTrace : public virtual CefBase { class CefV8StackTrace : public virtual CefBase {
@ -769,8 +780,9 @@ class CefV8StackTrace : public virtual CefBase {
static CefRefPtr<CefV8StackTrace> GetCurrent(int frame_limit); static CefRefPtr<CefV8StackTrace> GetCurrent(int frame_limit);
/// ///
// Returns true if this object is valid. Do not call any other methods if this // Returns true if the underlying handle is valid and it can be accessed on
// method returns false. // the current thread. Do not call any other methods if this method returns
// false.
/// ///
/*--cef()--*/ /*--cef()--*/
virtual bool IsValid() =0; virtual bool IsValid() =0;
@ -789,15 +801,18 @@ class CefV8StackTrace : public virtual CefBase {
}; };
/// ///
// Class representing a V8 stack frame. The methods of this class may only be // Class representing a V8 stack frame handle. Static methods may only be called
// called on the render process main thread. // on a render process thread that has entered a V8 isolate (usually the render
// process main thread). Non-static methods may only be called on the thread
// that initially returned the handle.
/// ///
/*--cef(source=library)--*/ /*--cef(source=library)--*/
class CefV8StackFrame : public virtual CefBase { class CefV8StackFrame : public virtual CefBase {
public: public:
/// ///
// Returns true if this object is valid. Do not call any other methods if this // Returns true if the underlying handle is valid and it can be accessed on
// method returns false. // the current thread. Do not call any other methods if this method returns
// false.
/// ///
/*--cef()--*/ /*--cef()--*/
virtual bool IsValid() =0; virtual bool IsValid() =0;

View File

@ -403,7 +403,7 @@ v8::Handle<v8::Value> FunctionCallbackImpl(const v8::Arguments& args) {
return v8::ThrowException(v8::Exception::Error(GetV8String(exception))); return v8::ThrowException(v8::Exception::Error(GetV8String(exception)));
} else { } else {
CefV8ValueImpl* rv = static_cast<CefV8ValueImpl*>(retval.get()); CefV8ValueImpl* rv = static_cast<CefV8ValueImpl*>(retval.get());
if (rv) if (rv && rv->IsValid())
return rv->GetHandle(true); return rv->GetHandle(true);
} }
} }
@ -437,7 +437,7 @@ v8::Handle<v8::Value> AccessorGetterCallbackImpl(v8::Local<v8::String> property,
v8::Exception::Error(GetV8String(exception))); v8::Exception::Error(GetV8String(exception)));
} else { } else {
CefV8ValueImpl* rv = static_cast<CefV8ValueImpl*>(retval.get()); CefV8ValueImpl* rv = static_cast<CefV8ValueImpl*>(retval.get());
if (rv) if (rv && rv->IsValid())
return rv->GetHandle(true); return rv->GetHandle(true);
} }
} }
@ -577,52 +577,36 @@ bool CefRegisterExtension(const CefString& extension_name,
} }
// CefV8HandleBase // Helper macros
CefV8HandleBase::CefV8HandleBase(v8::Handle<v8::Context> context) { #define CEF_V8_HAS_ISOLATE() (!!v8::Isolate::GetCurrent())
context_state_ = g_v8_tracker.Pointer()->GetContextState(context); #define CEF_V8_REQUIRE_ISOLATE_RETURN(var) \
} if (!CEF_V8_HAS_ISOLATE()) { \
NOTREACHED() << "V8 isolate is not valid"; \
return var; \
// CefV8Context
// static
CefRefPtr<CefV8Context> CefV8Context::GetCurrentContext() {
CefRefPtr<CefV8Context> context;
CEF_REQUIRE_RT_RETURN(context);
if (v8::Context::InContext()) {
v8::HandleScope handle_scope;
context = new CefV8ContextImpl(v8::Context::GetCurrent());
} }
return context;
}
// static #define CEF_V8_CURRENTLY_ON_MLT() (handle_->BelongsToCurrentThread())
CefRefPtr<CefV8Context> CefV8Context::GetEnteredContext() { #define CEF_V8_REQUIRE_MLT_RETURN(var) \
CefRefPtr<CefV8Context> context; CEF_V8_REQUIRE_ISOLATE_RETURN(var); \
CEF_REQUIRE_RT_RETURN(context); if (!CEF_V8_CURRENTLY_ON_MLT()) { \
if (v8::Context::InContext()) { NOTREACHED() << "called on incorrect thread"; \
v8::HandleScope handle_scope; return var; \
context = new CefV8ContextImpl(v8::Context::GetEntered());
} }
return context;
}
// static
bool CefV8Context::InContext() {
CEF_REQUIRE_RT_RETURN(false);
return v8::Context::InContext();
}
// CefV8ContextImpl
#define CEF_V8_HANDLE_IS_VALID() (handle_->IsValid())
#define CEF_V8_REQUIRE_VALID_RETURN(ret) \ #define CEF_V8_REQUIRE_VALID_RETURN(ret) \
if (!handle_->IsValid()) { \ CEF_V8_REQUIRE_MLT_RETURN(ret); \
if (!CEF_V8_HANDLE_IS_VALID()) { \
NOTREACHED() << "V8 handle is not valid"; \ NOTREACHED() << "V8 handle is not valid"; \
return ret; \ return ret; \
} }
#define CEF_V8_IS_VALID() \
(CEF_V8_HAS_ISOLATE() && \
CEF_V8_CURRENTLY_ON_MLT() && \
CEF_V8_HANDLE_IS_VALID())
#define CEF_V8_REQUIRE_OBJECT_RETURN(ret) \ #define CEF_V8_REQUIRE_OBJECT_RETURN(ret) \
CEF_V8_REQUIRE_VALID_RETURN(ret); \ CEF_V8_REQUIRE_VALID_RETURN(ret); \
if (!GetHandle(false)->IsObject()) { \ if (!GetHandle(false)->IsObject()) { \
@ -644,6 +628,57 @@ bool CefV8Context::InContext() {
return ret; \ return ret; \
} }
// CefV8HandleBase
CefV8HandleBase::~CefV8HandleBase() {
DCHECK(BelongsToCurrentThread());
}
bool CefV8HandleBase::BelongsToCurrentThread() const {
return message_loop_proxy_->BelongsToCurrentThread();
}
CefV8HandleBase::CefV8HandleBase(v8::Handle<v8::Context> context)
: message_loop_proxy_(base::MessageLoopProxy::current()) {
DCHECK(message_loop_proxy_.get());
context_state_ = g_v8_tracker.Pointer()->GetContextState(context);
}
// CefV8Context
// static
CefRefPtr<CefV8Context> CefV8Context::GetCurrentContext() {
CefRefPtr<CefV8Context> context;
CEF_V8_REQUIRE_ISOLATE_RETURN(context);
if (v8::Context::InContext()) {
v8::HandleScope handle_scope;
context = new CefV8ContextImpl(v8::Context::GetCurrent());
}
return context;
}
// static
CefRefPtr<CefV8Context> CefV8Context::GetEnteredContext() {
CefRefPtr<CefV8Context> context;
CEF_V8_REQUIRE_ISOLATE_RETURN(context);
if (v8::Context::InContext()) {
v8::HandleScope handle_scope;
context = new CefV8ContextImpl(v8::Context::GetEntered());
}
return context;
}
// static
bool CefV8Context::InContext() {
CEF_V8_REQUIRE_ISOLATE_RETURN(false);
return v8::Context::InContext();
}
// CefV8ContextImpl
CefV8ContextImpl::CefV8ContextImpl(v8::Handle<v8::Context> context) CefV8ContextImpl::CefV8ContextImpl(v8::Handle<v8::Context> context)
: handle_(new Handle(context, context)) : handle_(new Handle(context, context))
#ifndef NDEBUG #ifndef NDEBUG
@ -657,13 +692,11 @@ CefV8ContextImpl::~CefV8ContextImpl() {
} }
bool CefV8ContextImpl::IsValid() { bool CefV8ContextImpl::IsValid() {
CEF_REQUIRE_RT_RETURN(false); return CEF_V8_IS_VALID();
return handle_->IsValid();
} }
CefRefPtr<CefBrowser> CefV8ContextImpl::GetBrowser() { CefRefPtr<CefBrowser> CefV8ContextImpl::GetBrowser() {
CefRefPtr<CefBrowser> browser; CefRefPtr<CefBrowser> browser;
CEF_REQUIRE_RT_RETURN(browser);
CEF_V8_REQUIRE_VALID_RETURN(browser); CEF_V8_REQUIRE_VALID_RETURN(browser);
WebKit::WebFrame* webframe = GetWebFrame(); WebKit::WebFrame* webframe = GetWebFrame();
@ -675,7 +708,6 @@ CefRefPtr<CefBrowser> CefV8ContextImpl::GetBrowser() {
CefRefPtr<CefFrame> CefV8ContextImpl::GetFrame() { CefRefPtr<CefFrame> CefV8ContextImpl::GetFrame() {
CefRefPtr<CefFrame> frame; CefRefPtr<CefFrame> frame;
CEF_REQUIRE_RT_RETURN(frame);
CEF_V8_REQUIRE_VALID_RETURN(frame); CEF_V8_REQUIRE_VALID_RETURN(frame);
WebKit::WebFrame* webframe = GetWebFrame(); WebKit::WebFrame* webframe = GetWebFrame();
@ -689,7 +721,6 @@ CefRefPtr<CefFrame> CefV8ContextImpl::GetFrame() {
} }
CefRefPtr<CefV8Value> CefV8ContextImpl::GetGlobal() { CefRefPtr<CefV8Value> CefV8ContextImpl::GetGlobal() {
CEF_REQUIRE_RT_RETURN(NULL);
CEF_V8_REQUIRE_VALID_RETURN(NULL); CEF_V8_REQUIRE_VALID_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -698,7 +729,6 @@ CefRefPtr<CefV8Value> CefV8ContextImpl::GetGlobal() {
} }
bool CefV8ContextImpl::Enter() { bool CefV8ContextImpl::Enter() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
WebCore::V8PerIsolateData::current()->incrementRecursionLevel(); WebCore::V8PerIsolateData::current()->incrementRecursionLevel();
@ -710,7 +740,6 @@ bool CefV8ContextImpl::Enter() {
} }
bool CefV8ContextImpl::Exit() { bool CefV8ContextImpl::Exit() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
DLOG_ASSERT(enter_count_ > 0); DLOG_ASSERT(enter_count_ > 0);
@ -723,7 +752,6 @@ bool CefV8ContextImpl::Exit() {
} }
bool CefV8ContextImpl::IsSame(CefRefPtr<CefV8Context> that) { bool CefV8ContextImpl::IsSame(CefRefPtr<CefV8Context> that) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -732,7 +760,7 @@ bool CefV8ContextImpl::IsSame(CefRefPtr<CefV8Context> that) {
v8::Local<v8::Context> thisHandle = GetContext(); v8::Local<v8::Context> thisHandle = GetContext();
CefV8ContextImpl* impl = static_cast<CefV8ContextImpl*>(that.get()); CefV8ContextImpl* impl = static_cast<CefV8ContextImpl*>(that.get());
if (impl) if (impl && impl->IsValid())
thatHandle = impl->GetContext(); thatHandle = impl->GetContext();
return (thisHandle == thatHandle); return (thisHandle == thatHandle);
@ -741,7 +769,6 @@ bool CefV8ContextImpl::IsSame(CefRefPtr<CefV8Context> that) {
bool CefV8ContextImpl::Eval(const CefString& code, bool CefV8ContextImpl::Eval(const CefString& code,
CefRefPtr<CefV8Value>& retval, CefRefPtr<CefV8Value>& retval,
CefRefPtr<CefV8Exception>& exception) { CefRefPtr<CefV8Exception>& exception) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
if (code.empty()) { if (code.empty()) {
@ -825,49 +852,49 @@ CefV8ValueImpl::Handle::~Handle() {
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateUndefined() { CefRefPtr<CefV8Value> CefV8Value::CreateUndefined() {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return new CefV8ValueImpl(v8::Undefined()); return new CefV8ValueImpl(v8::Undefined());
} }
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateNull() { CefRefPtr<CefV8Value> CefV8Value::CreateNull() {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return new CefV8ValueImpl(v8::Null()); return new CefV8ValueImpl(v8::Null());
} }
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateBool(bool value) { CefRefPtr<CefV8Value> CefV8Value::CreateBool(bool value) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return new CefV8ValueImpl(v8::Boolean::New(value)); return new CefV8ValueImpl(v8::Boolean::New(value));
} }
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateInt(int32 value) { CefRefPtr<CefV8Value> CefV8Value::CreateInt(int32 value) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return new CefV8ValueImpl(v8::Int32::New(value)); return new CefV8ValueImpl(v8::Int32::New(value));
} }
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateUInt(uint32 value) { CefRefPtr<CefV8Value> CefV8Value::CreateUInt(uint32 value) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return new CefV8ValueImpl(v8::Int32::NewFromUnsigned(value)); return new CefV8ValueImpl(v8::Int32::NewFromUnsigned(value));
} }
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateDouble(double value) { CefRefPtr<CefV8Value> CefV8Value::CreateDouble(double value) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return new CefV8ValueImpl(v8::Number::New(value)); return new CefV8ValueImpl(v8::Number::New(value));
} }
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateDate(const CefTime& date) { CefRefPtr<CefV8Value> CefV8Value::CreateDate(const CefTime& date) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
// Convert from seconds to milliseconds. // Convert from seconds to milliseconds.
return new CefV8ValueImpl(v8::Date::New(date.GetDoubleT() * 1000)); return new CefV8ValueImpl(v8::Date::New(date.GetDoubleT() * 1000));
@ -875,7 +902,7 @@ CefRefPtr<CefV8Value> CefV8Value::CreateDate(const CefTime& date) {
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateString(const CefString& value) { CefRefPtr<CefV8Value> CefV8Value::CreateString(const CefString& value) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return new CefV8ValueImpl(GetV8String(value)); return new CefV8ValueImpl(GetV8String(value));
} }
@ -883,7 +910,7 @@ CefRefPtr<CefV8Value> CefV8Value::CreateString(const CefString& value) {
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateObject( CefRefPtr<CefV8Value> CefV8Value::CreateObject(
CefRefPtr<CefV8Accessor> accessor) { CefRefPtr<CefV8Accessor> accessor) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -909,7 +936,7 @@ CefRefPtr<CefV8Value> CefV8Value::CreateObject(
// static // static
CefRefPtr<CefV8Value> CefV8Value::CreateArray(int length) { CefRefPtr<CefV8Value> CefV8Value::CreateArray(int length) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -936,7 +963,7 @@ CefRefPtr<CefV8Value> CefV8Value::CreateArray(int length) {
CefRefPtr<CefV8Value> CefV8Value::CreateFunction( CefRefPtr<CefV8Value> CefV8Value::CreateFunction(
const CefString& name, const CefString& name,
CefRefPtr<CefV8Handler> handler) { CefRefPtr<CefV8Handler> handler) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
if (!handler.get()) { if (!handler.get()) {
NOTREACHED() << "invalid parameter"; NOTREACHED() << "invalid parameter";
@ -995,79 +1022,66 @@ CefV8ValueImpl::~CefV8ValueImpl() {
bool CefV8ValueImpl::IsValid() { bool CefV8ValueImpl::IsValid() {
CEF_REQUIRE_RT_RETURN(false); return CEF_V8_IS_VALID();
return handle_->IsValid();
} }
bool CefV8ValueImpl::IsUndefined() { bool CefV8ValueImpl::IsUndefined() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsUndefined(); return GetHandle(false)->IsUndefined();
} }
bool CefV8ValueImpl::IsNull() { bool CefV8ValueImpl::IsNull() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsNull(); return GetHandle(false)->IsNull();
} }
bool CefV8ValueImpl::IsBool() { bool CefV8ValueImpl::IsBool() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return (GetHandle(false)->IsBoolean() || GetHandle(false)->IsTrue() || return (GetHandle(false)->IsBoolean() || GetHandle(false)->IsTrue() ||
GetHandle(false)->IsFalse()); GetHandle(false)->IsFalse());
} }
bool CefV8ValueImpl::IsInt() { bool CefV8ValueImpl::IsInt() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsInt32(); return GetHandle(false)->IsInt32();
} }
bool CefV8ValueImpl::IsUInt() { bool CefV8ValueImpl::IsUInt() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsUint32(); return GetHandle(false)->IsUint32();
} }
bool CefV8ValueImpl::IsDouble() { bool CefV8ValueImpl::IsDouble() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsNumber(); return GetHandle(false)->IsNumber();
} }
bool CefV8ValueImpl::IsDate() { bool CefV8ValueImpl::IsDate() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsDate(); return GetHandle(false)->IsDate();
} }
bool CefV8ValueImpl::IsString() { bool CefV8ValueImpl::IsString() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsString(); return GetHandle(false)->IsString();
} }
bool CefV8ValueImpl::IsObject() { bool CefV8ValueImpl::IsObject() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsObject(); return GetHandle(false)->IsObject();
} }
bool CefV8ValueImpl::IsArray() { bool CefV8ValueImpl::IsArray() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsArray(); return GetHandle(false)->IsArray();
} }
bool CefV8ValueImpl::IsFunction() { bool CefV8ValueImpl::IsFunction() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
return GetHandle(false)->IsFunction(); return GetHandle(false)->IsFunction();
} }
bool CefV8ValueImpl::IsSame(CefRefPtr<CefV8Value> that) { bool CefV8ValueImpl::IsSame(CefRefPtr<CefV8Value> that) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1076,14 +1090,13 @@ bool CefV8ValueImpl::IsSame(CefRefPtr<CefV8Value> that) {
v8::Handle<v8::Value> thisHandle = GetHandle(false); v8::Handle<v8::Value> thisHandle = GetHandle(false);
CefV8ValueImpl* impl = static_cast<CefV8ValueImpl*>(that.get()); CefV8ValueImpl* impl = static_cast<CefV8ValueImpl*>(that.get());
if (impl) if (impl && impl->IsValid())
thatHandle = impl->GetHandle(false); thatHandle = impl->GetHandle(false);
return (thisHandle == thatHandle); return (thisHandle == thatHandle);
} }
bool CefV8ValueImpl::GetBoolValue() { bool CefV8ValueImpl::GetBoolValue() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
if (GetHandle(false)->IsTrue()) { if (GetHandle(false)->IsTrue()) {
return true; return true;
@ -1097,7 +1110,6 @@ bool CefV8ValueImpl::GetBoolValue() {
} }
int32 CefV8ValueImpl::GetIntValue() { int32 CefV8ValueImpl::GetIntValue() {
CEF_REQUIRE_RT_RETURN(0);
CEF_V8_REQUIRE_VALID_RETURN(0); CEF_V8_REQUIRE_VALID_RETURN(0);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Local<v8::Int32> val = GetHandle(false)->ToInt32(); v8::Local<v8::Int32> val = GetHandle(false)->ToInt32();
@ -1105,7 +1117,6 @@ int32 CefV8ValueImpl::GetIntValue() {
} }
uint32 CefV8ValueImpl::GetUIntValue() { uint32 CefV8ValueImpl::GetUIntValue() {
CEF_REQUIRE_RT_RETURN(0);
CEF_V8_REQUIRE_VALID_RETURN(0); CEF_V8_REQUIRE_VALID_RETURN(0);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Local<v8::Uint32> val = GetHandle(false)->ToUint32(); v8::Local<v8::Uint32> val = GetHandle(false)->ToUint32();
@ -1113,7 +1124,6 @@ uint32 CefV8ValueImpl::GetUIntValue() {
} }
double CefV8ValueImpl::GetDoubleValue() { double CefV8ValueImpl::GetDoubleValue() {
CEF_REQUIRE_RT_RETURN(0.);
CEF_V8_REQUIRE_VALID_RETURN(0.); CEF_V8_REQUIRE_VALID_RETURN(0.);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Local<v8::Number> val = GetHandle(false)->ToNumber(); v8::Local<v8::Number> val = GetHandle(false)->ToNumber();
@ -1121,7 +1131,6 @@ double CefV8ValueImpl::GetDoubleValue() {
} }
CefTime CefV8ValueImpl::GetDateValue() { CefTime CefV8ValueImpl::GetDateValue() {
CEF_REQUIRE_RT_RETURN(CefTime(0.));
CEF_V8_REQUIRE_VALID_RETURN(CefTime(0.)); CEF_V8_REQUIRE_VALID_RETURN(CefTime(0.));
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Local<v8::Number> val = GetHandle(false)->ToNumber(); v8::Local<v8::Number> val = GetHandle(false)->ToNumber();
@ -1131,7 +1140,6 @@ CefTime CefV8ValueImpl::GetDateValue() {
CefString CefV8ValueImpl::GetStringValue() { CefString CefV8ValueImpl::GetStringValue() {
CefString rv; CefString rv;
CEF_REQUIRE_RT_RETURN(rv);
CEF_V8_REQUIRE_VALID_RETURN(rv); CEF_V8_REQUIRE_VALID_RETURN(rv);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
GetCefString(GetHandle(false)->ToString(), rv); GetCefString(GetHandle(false)->ToString(), rv);
@ -1139,7 +1147,6 @@ CefString CefV8ValueImpl::GetStringValue() {
} }
bool CefV8ValueImpl::IsUserCreated() { bool CefV8ValueImpl::IsUserCreated() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1150,21 +1157,18 @@ bool CefV8ValueImpl::IsUserCreated() {
} }
bool CefV8ValueImpl::HasException() { bool CefV8ValueImpl::HasException() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
return (last_exception_.get() != NULL); return (last_exception_.get() != NULL);
} }
CefRefPtr<CefV8Exception> CefV8ValueImpl::GetException() { CefRefPtr<CefV8Exception> CefV8ValueImpl::GetException() {
CEF_REQUIRE_RT_RETURN(NULL);
CEF_V8_REQUIRE_OBJECT_RETURN(NULL); CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
return last_exception_; return last_exception_;
} }
bool CefV8ValueImpl::ClearException() { bool CefV8ValueImpl::ClearException() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
last_exception_ = NULL; last_exception_ = NULL;
@ -1172,14 +1176,12 @@ bool CefV8ValueImpl::ClearException() {
} }
bool CefV8ValueImpl::WillRethrowExceptions() { bool CefV8ValueImpl::WillRethrowExceptions() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
return rethrow_exceptions_; return rethrow_exceptions_;
} }
bool CefV8ValueImpl::SetRethrowExceptions(bool rethrow) { bool CefV8ValueImpl::SetRethrowExceptions(bool rethrow) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
rethrow_exceptions_ = rethrow; rethrow_exceptions_ = rethrow;
@ -1187,7 +1189,6 @@ bool CefV8ValueImpl::SetRethrowExceptions(bool rethrow) {
} }
bool CefV8ValueImpl::HasValue(const CefString& key) { bool CefV8ValueImpl::HasValue(const CefString& key) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1196,7 +1197,6 @@ bool CefV8ValueImpl::HasValue(const CefString& key) {
} }
bool CefV8ValueImpl::HasValue(int index) { bool CefV8ValueImpl::HasValue(int index) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (index < 0) { if (index < 0) {
@ -1210,7 +1210,6 @@ bool CefV8ValueImpl::HasValue(int index) {
} }
bool CefV8ValueImpl::DeleteValue(const CefString& key) { bool CefV8ValueImpl::DeleteValue(const CefString& key) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1223,7 +1222,6 @@ bool CefV8ValueImpl::DeleteValue(const CefString& key) {
} }
bool CefV8ValueImpl::DeleteValue(int index) { bool CefV8ValueImpl::DeleteValue(int index) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (index < 0) { if (index < 0) {
@ -1241,7 +1239,6 @@ bool CefV8ValueImpl::DeleteValue(int index) {
} }
CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(const CefString& key) { CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(const CefString& key) {
CEF_REQUIRE_RT_RETURN(NULL);
CEF_V8_REQUIRE_OBJECT_RETURN(NULL); CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1256,7 +1253,6 @@ CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(const CefString& key) {
} }
CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(int index) { CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(int index) {
CEF_REQUIRE_RT_RETURN(NULL);
CEF_V8_REQUIRE_OBJECT_RETURN(NULL); CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
if (index < 0) { if (index < 0) {
@ -1278,11 +1274,10 @@ CefRefPtr<CefV8Value> CefV8ValueImpl::GetValue(int index) {
bool CefV8ValueImpl::SetValue(const CefString& key, bool CefV8ValueImpl::SetValue(const CefString& key,
CefRefPtr<CefV8Value> value, CefRefPtr<CefV8Value> value,
PropertyAttribute attribute) { PropertyAttribute attribute) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
CefV8ValueImpl* impl = static_cast<CefV8ValueImpl*>(value.get()); CefV8ValueImpl* impl = static_cast<CefV8ValueImpl*>(value.get());
if (impl) { if (impl && impl->IsValid()) {
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle(false)->ToObject(); v8::Local<v8::Object> obj = GetHandle(false)->ToObject();
@ -1298,7 +1293,6 @@ bool CefV8ValueImpl::SetValue(const CefString& key,
} }
bool CefV8ValueImpl::SetValue(int index, CefRefPtr<CefV8Value> value) { bool CefV8ValueImpl::SetValue(int index, CefRefPtr<CefV8Value> value) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
if (index < 0) { if (index < 0) {
@ -1307,7 +1301,7 @@ bool CefV8ValueImpl::SetValue(int index, CefRefPtr<CefV8Value> value) {
} }
CefV8ValueImpl* impl = static_cast<CefV8ValueImpl*>(value.get()); CefV8ValueImpl* impl = static_cast<CefV8ValueImpl*>(value.get());
if (impl) { if (impl && impl->IsValid()) {
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Local<v8::Object> obj = GetHandle(false)->ToObject(); v8::Local<v8::Object> obj = GetHandle(false)->ToObject();
@ -1323,7 +1317,6 @@ bool CefV8ValueImpl::SetValue(int index, CefRefPtr<CefV8Value> value) {
bool CefV8ValueImpl::SetValue(const CefString& key, AccessControl settings, bool CefV8ValueImpl::SetValue(const CefString& key, AccessControl settings,
PropertyAttribute attribute) { PropertyAttribute attribute) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1352,7 +1345,6 @@ bool CefV8ValueImpl::SetValue(const CefString& key, AccessControl settings,
} }
bool CefV8ValueImpl::GetKeys(std::vector<CefString>& keys) { bool CefV8ValueImpl::GetKeys(std::vector<CefString>& keys) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1369,7 +1361,6 @@ bool CefV8ValueImpl::GetKeys(std::vector<CefString>& keys) {
} }
bool CefV8ValueImpl::SetUserData(CefRefPtr<CefBase> user_data) { bool CefV8ValueImpl::SetUserData(CefRefPtr<CefBase> user_data) {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_OBJECT_RETURN(false); CEF_V8_REQUIRE_OBJECT_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1385,7 +1376,6 @@ bool CefV8ValueImpl::SetUserData(CefRefPtr<CefBase> user_data) {
} }
CefRefPtr<CefBase> CefV8ValueImpl::GetUserData() { CefRefPtr<CefBase> CefV8ValueImpl::GetUserData() {
CEF_REQUIRE_RT_RETURN(NULL);
CEF_V8_REQUIRE_OBJECT_RETURN(NULL); CEF_V8_REQUIRE_OBJECT_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1399,7 +1389,6 @@ CefRefPtr<CefBase> CefV8ValueImpl::GetUserData() {
} }
int CefV8ValueImpl::GetExternallyAllocatedMemory() { int CefV8ValueImpl::GetExternallyAllocatedMemory() {
CEF_REQUIRE_RT_RETURN(0);
CEF_V8_REQUIRE_OBJECT_RETURN(0); CEF_V8_REQUIRE_OBJECT_RETURN(0);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1413,7 +1402,6 @@ int CefV8ValueImpl::GetExternallyAllocatedMemory() {
} }
int CefV8ValueImpl::AdjustExternallyAllocatedMemory(int change_in_bytes) { int CefV8ValueImpl::AdjustExternallyAllocatedMemory(int change_in_bytes) {
CEF_REQUIRE_RT_RETURN(0);
CEF_V8_REQUIRE_OBJECT_RETURN(0); CEF_V8_REQUIRE_OBJECT_RETURN(0);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1427,7 +1415,6 @@ int CefV8ValueImpl::AdjustExternallyAllocatedMemory(int change_in_bytes) {
} }
int CefV8ValueImpl::GetArrayLength() { int CefV8ValueImpl::GetArrayLength() {
CEF_REQUIRE_RT_RETURN(0);
CEF_V8_REQUIRE_ARRAY_RETURN(0); CEF_V8_REQUIRE_ARRAY_RETURN(0);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1438,7 +1425,6 @@ int CefV8ValueImpl::GetArrayLength() {
CefString CefV8ValueImpl::GetFunctionName() { CefString CefV8ValueImpl::GetFunctionName() {
CefString rv; CefString rv;
CEF_REQUIRE_RT_RETURN(rv);
CEF_V8_REQUIRE_FUNCTION_RETURN(rv); CEF_V8_REQUIRE_FUNCTION_RETURN(rv);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1449,7 +1435,6 @@ CefString CefV8ValueImpl::GetFunctionName() {
} }
CefRefPtr<CefV8Handler> CefV8ValueImpl::GetFunctionHandler() { CefRefPtr<CefV8Handler> CefV8ValueImpl::GetFunctionHandler() {
CEF_REQUIRE_RT_RETURN(NULL);
CEF_V8_REQUIRE_FUNCTION_RETURN(NULL); CEF_V8_REQUIRE_FUNCTION_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
@ -1474,9 +1459,27 @@ CefRefPtr<CefV8Value> CefV8ValueImpl::ExecuteFunctionWithContext(
CefRefPtr<CefV8Context> context, CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Value> object, CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments) { const CefV8ValueList& arguments) {
CEF_REQUIRE_RT_RETURN(NULL);
CEF_V8_REQUIRE_FUNCTION_RETURN(NULL); CEF_V8_REQUIRE_FUNCTION_RETURN(NULL);
if (context.get() && !context->IsValid()) {
NOTREACHED() << "invalid V8 context parameter";
return NULL;
}
if (object.get() && (!object->IsValid() || !object->IsObject())) {
NOTREACHED() << "invalid V8 object parameter";
return NULL;
}
int argc = arguments.size();
if (argc > 0) {
for (int i = 0; i < argc; ++i) {
if (!arguments[i].get() || !arguments[i]->IsValid()) {
NOTREACHED() << "invalid V8 arguments parameter";
return NULL;
}
}
}
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Local<v8::Context> context_local; v8::Local<v8::Context> context_local;
@ -1494,15 +1497,14 @@ CefRefPtr<CefV8Value> CefV8ValueImpl::ExecuteFunctionWithContext(
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(obj); v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(obj);
v8::Handle<v8::Object> recv; v8::Handle<v8::Object> recv;
// Default to the global object if no object or a non-object was provided. // Default to the global object if no object was provided.
if (object.get() && object->IsObject()) { if (object.get()) {
CefV8ValueImpl* recv_impl = static_cast<CefV8ValueImpl*>(object.get()); CefV8ValueImpl* recv_impl = static_cast<CefV8ValueImpl*>(object.get());
recv = v8::Handle<v8::Object>::Cast(recv_impl->GetHandle(true)); recv = v8::Handle<v8::Object>::Cast(recv_impl->GetHandle(true));
} else { } else {
recv = context_local->Global(); recv = context_local->Global();
} }
int argc = arguments.size();
v8::Handle<v8::Value> *argv = NULL; v8::Handle<v8::Value> *argv = NULL;
if (argc > 0) { if (argc > 0) {
argv = new v8::Handle<v8::Value>[argc]; argv = new v8::Handle<v8::Value>[argc];
@ -1556,7 +1558,7 @@ bool CefV8ValueImpl::HasCaught(v8::TryCatch& try_catch) {
// static // static
CefRefPtr<CefV8StackTrace> CefV8StackTrace::GetCurrent(int frame_limit) { CefRefPtr<CefV8StackTrace> CefV8StackTrace::GetCurrent(int frame_limit) {
CEF_REQUIRE_RT_RETURN(NULL); CEF_V8_REQUIRE_ISOLATE_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Handle<v8::StackTrace> stackTrace = v8::Handle<v8::StackTrace> stackTrace =
@ -1578,19 +1580,16 @@ CefV8StackTraceImpl::~CefV8StackTraceImpl() {
} }
bool CefV8StackTraceImpl::IsValid() { bool CefV8StackTraceImpl::IsValid() {
CEF_REQUIRE_RT_RETURN(false); return CEF_V8_IS_VALID();
return handle_->IsValid();
} }
int CefV8StackTraceImpl::GetFrameCount() { int CefV8StackTraceImpl::GetFrameCount() {
CEF_REQUIRE_RT_RETURN(0);
CEF_V8_REQUIRE_VALID_RETURN(0); CEF_V8_REQUIRE_VALID_RETURN(0);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return GetHandle()->GetFrameCount(); return GetHandle()->GetFrameCount();
} }
CefRefPtr<CefV8StackFrame> CefV8StackTraceImpl::GetFrame(int index) { CefRefPtr<CefV8StackFrame> CefV8StackTraceImpl::GetFrame(int index) {
CEF_REQUIRE_RT_RETURN(NULL);
CEF_V8_REQUIRE_VALID_RETURN(NULL); CEF_V8_REQUIRE_VALID_RETURN(NULL);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::Handle<v8::StackFrame> stackFrame = GetHandle()->GetFrame(index); v8::Handle<v8::StackFrame> stackFrame = GetHandle()->GetFrame(index);
@ -1610,13 +1609,11 @@ CefV8StackFrameImpl::~CefV8StackFrameImpl() {
} }
bool CefV8StackFrameImpl::IsValid() { bool CefV8StackFrameImpl::IsValid() {
CEF_REQUIRE_RT_RETURN(false); return CEF_V8_IS_VALID();
return handle_->IsValid();
} }
CefString CefV8StackFrameImpl::GetScriptName() { CefString CefV8StackFrameImpl::GetScriptName() {
CefString rv; CefString rv;
CEF_REQUIRE_RT_RETURN(rv);
CEF_V8_REQUIRE_VALID_RETURN(rv); CEF_V8_REQUIRE_VALID_RETURN(rv);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
GetCefString(v8::Handle<v8::String>::Cast(GetHandle()->GetScriptName()), rv); GetCefString(v8::Handle<v8::String>::Cast(GetHandle()->GetScriptName()), rv);
@ -1625,7 +1622,6 @@ CefString CefV8StackFrameImpl::GetScriptName() {
CefString CefV8StackFrameImpl::GetScriptNameOrSourceURL() { CefString CefV8StackFrameImpl::GetScriptNameOrSourceURL() {
CefString rv; CefString rv;
CEF_REQUIRE_RT_RETURN(rv);
CEF_V8_REQUIRE_VALID_RETURN(rv); CEF_V8_REQUIRE_VALID_RETURN(rv);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
GetCefString( GetCefString(
@ -1636,7 +1632,6 @@ CefString CefV8StackFrameImpl::GetScriptNameOrSourceURL() {
CefString CefV8StackFrameImpl::GetFunctionName() { CefString CefV8StackFrameImpl::GetFunctionName() {
CefString rv; CefString rv;
CEF_REQUIRE_RT_RETURN(rv);
CEF_V8_REQUIRE_VALID_RETURN(rv); CEF_V8_REQUIRE_VALID_RETURN(rv);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
GetCefString( GetCefString(
@ -1645,28 +1640,24 @@ CefString CefV8StackFrameImpl::GetFunctionName() {
} }
int CefV8StackFrameImpl::GetLineNumber() { int CefV8StackFrameImpl::GetLineNumber() {
CEF_REQUIRE_RT_RETURN(0);
CEF_V8_REQUIRE_VALID_RETURN(0); CEF_V8_REQUIRE_VALID_RETURN(0);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return GetHandle()->GetLineNumber(); return GetHandle()->GetLineNumber();
} }
int CefV8StackFrameImpl::GetColumn() { int CefV8StackFrameImpl::GetColumn() {
CEF_REQUIRE_RT_RETURN(0);
CEF_V8_REQUIRE_VALID_RETURN(0); CEF_V8_REQUIRE_VALID_RETURN(0);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return GetHandle()->GetColumn(); return GetHandle()->GetColumn();
} }
bool CefV8StackFrameImpl::IsEval() { bool CefV8StackFrameImpl::IsEval() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return GetHandle()->IsEval(); return GetHandle()->IsEval();
} }
bool CefV8StackFrameImpl::IsConstructor() { bool CefV8StackFrameImpl::IsConstructor() {
CEF_REQUIRE_RT_RETURN(false);
CEF_V8_REQUIRE_VALID_RETURN(false); CEF_V8_REQUIRE_VALID_RETURN(false);
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
return GetHandle()->IsConstructor(); return GetHandle()->IsConstructor();
@ -1674,8 +1665,6 @@ bool CefV8StackFrameImpl::IsConstructor() {
void CefV8MessageHandler(v8::Handle<v8::Message> message, void CefV8MessageHandler(v8::Handle<v8::Message> message,
v8::Handle<v8::Value> data) { v8::Handle<v8::Value> data) {
CEF_REQUIRE_RT_RETURN(void());
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext(); CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
CefRefPtr<CefBrowser> browser = context->GetBrowser(); CefRefPtr<CefBrowser> browser = context->GetBrowser();
CefRefPtr<CefFrame> frame = context->GetFrame(); CefRefPtr<CefFrame> frame = context->GetFrame();

View File

@ -10,10 +10,12 @@
#include "include/cef_v8.h" #include "include/cef_v8.h"
#include "libcef/common/tracker.h" #include "libcef/common/tracker.h"
#include "libcef/renderer/thread_util.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/message_loop_proxy.h"
class CefTrackNode; class CefTrackNode;
@ -52,25 +54,50 @@ class CefV8ContextState : public base::RefCounted<CefV8ContextState> {
CefTrackManager track_manager_; CefTrackManager track_manager_;
}; };
// Use this template in conjuction with RefCountedThreadSafe to ensure that a
// V8 object is deleted on the correct thread.
struct CefV8DeleteOnMessageLoopThread {
template<typename T>
static void Destruct(const T* x) {
if (x->message_loop_proxy_->BelongsToCurrentThread()) {
delete x;
} else {
if (!x->message_loop_proxy_->DeleteSoon(FROM_HERE, x)) {
#if defined(UNIT_TEST)
// Only logged under unit testing because leaks at shutdown
// are acceptable under normal circumstances.
LOG(ERROR) << "DeleteSoon failed on thread " << thread;
#endif // UNIT_TEST
}
}
}
};
// Base class for V8 Handle types. // Base class for V8 Handle types.
class CefV8HandleBase : class CefV8HandleBase :
public base::RefCountedThreadSafe<CefV8HandleBase, public base::RefCountedThreadSafe<CefV8HandleBase,
CefDeleteOnRenderThread> { CefV8DeleteOnMessageLoopThread> {
public: public:
virtual ~CefV8HandleBase() {} virtual ~CefV8HandleBase();
// Returns true if there is no underlying context or if the underlying context // Returns true if there is no underlying context or if the underlying context
// is valid. // is valid.
bool IsValid() { bool IsValid() const {
return (!context_state_.get() || context_state_->IsValid()); return (!context_state_.get() || context_state_->IsValid());
} }
bool BelongsToCurrentThread() const;
protected: protected:
// |context| is the context that owns this handle. If empty the current // |context| is the context that owns this handle. If empty the current
// context will be used. // context will be used.
explicit CefV8HandleBase(v8::Handle<v8::Context> context); explicit CefV8HandleBase(v8::Handle<v8::Context> context);
protected: protected:
friend struct CefV8DeleteOnMessageLoopThread;
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
scoped_refptr<CefV8ContextState> context_state_; scoped_refptr<CefV8ContextState> context_state_;
}; };