diff --git a/cef1/cef_paths.gypi b/cef1/cef_paths.gypi index e719e56dd..7cc04e958 100644 --- a/cef1/cef_paths.gypi +++ b/cef1/cef_paths.gypi @@ -184,6 +184,10 @@ 'libcef_dll/cpptoc/v8exception_cpptoc.h', 'libcef_dll/ctocpp/v8handler_ctocpp.cc', 'libcef_dll/ctocpp/v8handler_ctocpp.h', + 'libcef_dll/cpptoc/v8stack_frame_cpptoc.cc', + 'libcef_dll/cpptoc/v8stack_frame_cpptoc.h', + 'libcef_dll/cpptoc/v8stack_trace_cpptoc.cc', + 'libcef_dll/cpptoc/v8stack_trace_cpptoc.h', 'libcef_dll/cpptoc/v8value_cpptoc.cc', 'libcef_dll/cpptoc/v8value_cpptoc.h', 'libcef_dll/cpptoc/web_plugin_info_cpptoc.cc', @@ -292,6 +296,10 @@ 'libcef_dll/ctocpp/v8exception_ctocpp.h', 'libcef_dll/cpptoc/v8handler_cpptoc.cc', 'libcef_dll/cpptoc/v8handler_cpptoc.h', + 'libcef_dll/ctocpp/v8stack_frame_ctocpp.cc', + 'libcef_dll/ctocpp/v8stack_frame_ctocpp.h', + 'libcef_dll/ctocpp/v8stack_trace_ctocpp.cc', + 'libcef_dll/ctocpp/v8stack_trace_ctocpp.h', 'libcef_dll/ctocpp/v8value_ctocpp.cc', 'libcef_dll/ctocpp/v8value_ctocpp.h', 'libcef_dll/ctocpp/web_plugin_info_ctocpp.cc', diff --git a/cef1/include/capi/cef_v8_capi.h b/cef1/include/capi/cef_v8_capi.h index c0facab62..8c4c23db3 100644 --- a/cef1/include/capi/cef_v8_capi.h +++ b/cef1/include/capi/cef_v8_capi.h @@ -698,6 +698,92 @@ CEF_EXPORT cef_v8value_t* cef_v8value_create_function(const cef_string_t* name, cef_v8handler_t* handler); +/// +// Structure representing a V8 stack trace. The functions of this structure may +// only be called on the UI thread. +/// +typedef struct _cef_v8stack_trace_t { + /// + // Base structure. + /// + cef_base_t base; + + /// + // Returns the number of stack frames. + /// + int (CEF_CALLBACK *get_frame_count)(struct _cef_v8stack_trace_t* self); + + /// + // Returns the stack frame at the specified 0-based index. + /// + struct _cef_v8stack_frame_t* (CEF_CALLBACK *get_frame)( + struct _cef_v8stack_trace_t* self, int index); +} cef_v8stack_trace_t; + + +/// +// Returns the stack trace for the currently active context. |frame_limit| is +// the maximum number of frames that will be captured. +/// +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 +// only be called on the UI thread. +/// +typedef struct _cef_v8stack_frame_t { + /// + // Base structure. + /// + cef_base_t base; + + /// + // Returns the name of the resource script that contains the function. + /// + // The resulting string must be freed by calling cef_string_userfree_free(). + cef_string_userfree_t (CEF_CALLBACK *get_script_name)( + struct _cef_v8stack_frame_t* self); + + /// + // Returns the name of the resource script that contains the function or the + // sourceURL value if the script name is undefined and its source ends with a + // "//@ sourceURL=..." string. + /// + // The resulting string must be freed by calling cef_string_userfree_free(). + cef_string_userfree_t (CEF_CALLBACK *get_script_name_or_source_url)( + struct _cef_v8stack_frame_t* self); + + /// + // Returns the name of the function. + /// + // The resulting string must be freed by calling cef_string_userfree_free(). + cef_string_userfree_t (CEF_CALLBACK *get_function_name)( + struct _cef_v8stack_frame_t* self); + + /// + // Returns the 1-based line number for the function call or 0 if unknown. + /// + int (CEF_CALLBACK *get_line_number)(struct _cef_v8stack_frame_t* self); + + /// + // Returns the 1-based column offset on the line for the function call or 0 if + // unknown. + /// + int (CEF_CALLBACK *get_column)(struct _cef_v8stack_frame_t* self); + + /// + // Returns true (1) if the function was compiled using eval(). + /// + int (CEF_CALLBACK *is_eval)(struct _cef_v8stack_frame_t* self); + + /// + // Returns true (1) if the function was called as a constructor via "new". + /// + int (CEF_CALLBACK *is_constructor)(struct _cef_v8stack_frame_t* self); +} cef_v8stack_frame_t; + + #ifdef __cplusplus } #endif diff --git a/cef1/include/cef_v8.h b/cef1/include/cef_v8.h index 9f6e198ec..70dd729f6 100644 --- a/cef1/include/cef_v8.h +++ b/cef1/include/cef_v8.h @@ -46,6 +46,7 @@ class CefV8Exception; class CefV8Handler; +class CefV8StackFrame; class CefV8Value; @@ -739,4 +740,84 @@ class CefV8Value : public virtual CefBase { const CefV8ValueList& arguments) =0; }; +/// +// Class representing a V8 stack trace. The methods of this class may only be +// called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefV8StackTrace : public virtual CefBase { + public: + /// + // Returns the stack trace for the currently active context. |frame_limit| is + // the maximum number of frames that will be captured. + /// + /*--cef()--*/ + static CefRefPtr GetCurrent(int frame_limit); + + /// + // Returns the number of stack frames. + /// + /*--cef()--*/ + virtual int GetFrameCount() =0; + + /// + // Returns the stack frame at the specified 0-based index. + /// + /*--cef()--*/ + virtual CefRefPtr GetFrame(int index) =0; +}; + +/// +// Class representing a V8 stack frame. The methods of this class may only be +// called on the UI thread. +/// +/*--cef(source=library)--*/ +class CefV8StackFrame : public virtual CefBase { + public: + /// + // Returns the name of the resource script that contains the function. + /// + /*--cef()--*/ + virtual CefString GetScriptName() =0; + + /// + // Returns the name of the resource script that contains the function or the + // sourceURL value if the script name is undefined and its source ends with + // a "//@ sourceURL=..." string. + /// + /*--cef()--*/ + virtual CefString GetScriptNameOrSourceURL() =0; + + /// + // Returns the name of the function. + /// + /*--cef()--*/ + virtual CefString GetFunctionName() =0; + + /// + // Returns the 1-based line number for the function call or 0 if unknown. + /// + /*--cef()--*/ + virtual int GetLineNumber() =0; + + /// + // Returns the 1-based column offset on the line for the function call or 0 if + // unknown. + /// + /*--cef()--*/ + virtual int GetColumn() =0; + + /// + // Returns true if the function was compiled using eval(). + /// + /*--cef()--*/ + virtual bool IsEval() =0; + + /// + // Returns true if the function was called as a constructor via "new". + /// + /*--cef()--*/ + virtual bool IsConstructor() =0; +}; + #endif // CEF_INCLUDE_CEF_V8_H_ diff --git a/cef1/libcef/v8_impl.cc b/cef1/libcef/v8_impl.cc index e2cdf6d26..064c53407 100644 --- a/cef1/libcef/v8_impl.cc +++ b/cef1/libcef/v8_impl.cc @@ -184,16 +184,19 @@ v8::Handle GetV8String(const CefString& str) { #if defined(CEF_STRING_TYPE_UTF16) void v8impl_string_dtor(char16* str) { - delete [] str; + delete [] str; } #elif defined(CEF_STRING_TYPE_UTF8) void v8impl_string_dtor(char* str) { - delete [] str; + delete [] str; } #endif // Convert a v8::String to CefString. void GetCefString(v8::Handle str, CefString& out) { + if (str.IsEmpty()) + return; + #if defined(CEF_STRING_TYPE_WIDE) // Allocate enough space for a worst-case conversion. int len = str->Utf8Length(); @@ -431,7 +434,7 @@ bool CefRegisterExtension(const CefString& extension_name, } -// CefV8Context implementation. +// CefV8Context // static CefRefPtr CefV8Context::GetCurrentContext() { @@ -465,7 +468,7 @@ bool CefV8Context::InContext() { } -// CefV8ContextImpl implementation. +// CefV8ContextImpl #define CEF_V8_REQUIRE_OBJECT_RETURN(ret) \ if (!GetHandle()->IsObject()) { \ @@ -486,11 +489,11 @@ bool CefV8Context::InContext() { } CefV8ContextImpl::CefV8ContextImpl(v8::Handle context) + : handle_(new Handle(context)) #ifndef NDEBUG - : enter_count_(0) + , enter_count_(0) #endif { // NOLINT(whitespace/braces) - v8_context_ = new CefV8ContextHandle(context); } CefV8ContextImpl::~CefV8ContextImpl() { @@ -527,13 +530,13 @@ CefRefPtr CefV8ContextImpl::GetGlobal() { CEF_REQUIRE_UI_THREAD(NULL); v8::HandleScope handle_scope; - v8::Context::Scope context_scope(v8_context_->GetHandle()); - return new CefV8ValueImpl(v8_context_->GetHandle()->Global()); + v8::Context::Scope context_scope(GetHandle()); + return new CefV8ValueImpl(GetHandle()->Global()); } bool CefV8ContextImpl::Enter() { CEF_REQUIRE_UI_THREAD(false); - v8_context_->GetHandle()->Enter(); + GetHandle()->Enter(); #ifndef NDEBUG ++enter_count_; #endif @@ -543,7 +546,7 @@ bool CefV8ContextImpl::Enter() { bool CefV8ContextImpl::Exit() { CEF_REQUIRE_UI_THREAD(false); DLOG_ASSERT(enter_count_ > 0); - v8_context_->GetHandle()->Exit(); + GetHandle()->Exit(); #ifndef NDEBUG --enter_count_; #endif @@ -576,8 +579,8 @@ bool CefV8ContextImpl::Eval(const CefString& code, } v8::HandleScope handle_scope; - v8::Context::Scope context_scope(v8_context_->GetHandle()); - v8::Local obj = v8_context_->GetHandle()->Global(); + v8::Context::Scope context_scope(GetHandle()); + v8::Local obj = GetHandle()->Global(); // Retrieve the eval function. v8::Local val = obj->Get(v8::String::New("eval")); @@ -611,28 +614,26 @@ bool CefV8ContextImpl::Eval(const CefString& code, } v8::Local CefV8ContextImpl::GetContext() { - return v8::Local::New(v8_context_->GetHandle()); + return v8::Local::New(GetHandle()); } WebKit::WebFrame* CefV8ContextImpl::GetWebFrame() { v8::HandleScope handle_scope; - v8::Context::Scope context_scope(v8_context_->GetHandle()); + v8::Context::Scope context_scope(GetHandle()); WebKit::WebFrame* frame = WebKit::WebFrame::frameForCurrentContext(); return frame; } -// CefV8ValueHandle +// CefV8ValueImpl::Handle -// Custom destructor for a v8 value handle which gets called only on the UI -// thread. -CefV8ValueHandle::~CefV8ValueHandle() { +CefV8ValueImpl::Handle::~Handle() { if (tracker_) { TrackAdd(tracker_); - v8_handle_.MakeWeak(tracker_, TrackDestructor); + handle_.MakeWeak(tracker_, TrackDestructor); } else { - v8_handle_.Dispose(); - v8_handle_.Clear(); + handle_.Dispose(); + handle_.Clear(); } tracker_ = NULL; } @@ -814,8 +815,8 @@ CefRefPtr CefV8Value::CreateFunction( CefV8ValueImpl::CefV8ValueImpl(v8::Handle value, CefTrackNode* tracker) - : rethrow_exceptions_(false) { - v8_value_ = new CefV8ValueHandle(value, tracker); + : handle_(new Handle(value, tracker)), + rethrow_exceptions_(false) { } CefV8ValueImpl::~CefV8ValueImpl() { @@ -968,7 +969,7 @@ CefRefPtr CefV8ValueImpl::GetException() { } bool CefV8ValueImpl::ClearException() { - CEF_REQUIRE_UI_THREAD(NULL); + CEF_REQUIRE_UI_THREAD(NULL); CEF_V8_REQUIRE_OBJECT_RETURN(NULL); last_exception_ = NULL; @@ -1370,3 +1371,105 @@ bool CefV8ValueImpl::HasCaught(v8::TryCatch& try_catch) { return false; } } + + +// CefV8StackTrace + +// static +CefRefPtr CefV8StackTrace::GetCurrent(int frame_limit) { + CEF_REQUIRE_VALID_CONTEXT(NULL); + CEF_REQUIRE_UI_THREAD(NULL); + + v8::Handle stackTrace = + v8::StackTrace::CurrentStackTrace( + frame_limit, v8::StackTrace::kDetailed); + if (stackTrace.IsEmpty()) + return NULL; + return new CefV8StackTraceImpl(stackTrace); +} + + +// CefV8StackTraceImpl + +CefV8StackTraceImpl::CefV8StackTraceImpl(v8::Handle handle) + : handle_(new Handle(handle)) { +} + +CefV8StackTraceImpl::~CefV8StackTraceImpl() { +} + +int CefV8StackTraceImpl::GetFrameCount() { + CEF_REQUIRE_UI_THREAD(0); + v8::HandleScope handle_scope; + return GetHandle()->GetFrameCount(); +} + +CefRefPtr CefV8StackTraceImpl::GetFrame(int index) { + CEF_REQUIRE_UI_THREAD(NULL); + v8::HandleScope handle_scope; + v8::Handle stackFrame = GetHandle()->GetFrame(index); + if (stackFrame.IsEmpty()) + return NULL; + return new CefV8StackFrameImpl(stackFrame); +} + + +// CefV8StackFrameImpl + +CefV8StackFrameImpl::CefV8StackFrameImpl(v8::Handle handle) + : handle_(new Handle(handle)) { +} + +CefV8StackFrameImpl::~CefV8StackFrameImpl() { +} + +CefString CefV8StackFrameImpl::GetScriptName() { + CefString rv; + CEF_REQUIRE_UI_THREAD(rv); + v8::HandleScope handle_scope; + GetCefString(v8::Handle::Cast(GetHandle()->GetScriptName()), rv); + return rv; +} + +CefString CefV8StackFrameImpl::GetScriptNameOrSourceURL() { + CefString rv; + CEF_REQUIRE_UI_THREAD(rv); + v8::HandleScope handle_scope; + GetCefString( + v8::Handle::Cast(GetHandle()->GetScriptNameOrSourceURL()), + rv); + return rv; +} + +CefString CefV8StackFrameImpl::GetFunctionName() { + CefString rv; + CEF_REQUIRE_UI_THREAD(rv); + v8::HandleScope handle_scope; + GetCefString( + v8::Handle::Cast(GetHandle()->GetFunctionName()), rv); + return rv; +} + +int CefV8StackFrameImpl::GetLineNumber() { + CEF_REQUIRE_UI_THREAD(0); + v8::HandleScope handle_scope; + return GetHandle()->GetLineNumber(); +} + +int CefV8StackFrameImpl::GetColumn() { + CEF_REQUIRE_UI_THREAD(0); + v8::HandleScope handle_scope; + return GetHandle()->GetColumn(); +} + +bool CefV8StackFrameImpl::IsEval() { + CEF_REQUIRE_UI_THREAD(false); + v8::HandleScope handle_scope; + return GetHandle()->IsEval(); +} + +bool CefV8StackFrameImpl::IsConstructor() { + CEF_REQUIRE_UI_THREAD(false); + v8::HandleScope handle_scope; + return GetHandle()->IsConstructor(); +} diff --git a/cef1/libcef/v8_impl.h b/cef1/libcef/v8_impl.h index ca42909c9..11dfc7d25 100644 --- a/cef1/libcef/v8_impl.h +++ b/cef1/libcef/v8_impl.h @@ -21,43 +21,37 @@ class WebFrame; // Template for V8 Handle types. This class is used to ensure that V8 objects // are only released on the UI thread. -template -class CefReleaseV8HandleOnUIThread - : public base::RefCountedThreadSafe, - CefThread::DeleteOnUIThread> { +template +class CefV8Handle : + public base::RefCountedThreadSafe, + CefThread::DeleteOnUIThread> { public: typedef v8::Handle handleType; typedef v8::Persistent persistentType; - typedef CefReleaseV8HandleOnUIThread superType; - explicit CefReleaseV8HandleOnUIThread(handleType v) { - v8_handle_ = persistentType::New(v); + CefV8Handle(handleType v) + : handle_(persistentType::New(v)) { } - virtual ~CefReleaseV8HandleOnUIThread() { + ~CefV8Handle() { + handle_.Dispose(); + handle_.Clear(); } - handleType GetHandle() { - return v8_handle_; - } + handleType GetHandle() { return handle_; } - persistentType v8_handle_; + protected: + persistentType handle_; + + DISALLOW_COPY_AND_ASSIGN(CefV8Handle); }; -// Special class for a v8::Context to ensure that it is deleted from the UI -// thread. -class CefV8ContextHandle : public CefReleaseV8HandleOnUIThread { - public: - explicit CefV8ContextHandle(handleType context) - : superType(context) { - } - - // Context handles are disposed rather than makeweak. - ~CefV8ContextHandle() { - v8_handle_.Dispose(); - v8_handle_.Clear(); - } +// Specialization for v8::Value with empty implementation to avoid incorrect +// usage. +template <> +class CefV8Handle { }; + class CefV8ContextImpl : public CefV8Context { public: explicit CefV8ContextImpl(v8::Handle context); @@ -76,8 +70,11 @@ class CefV8ContextImpl : public CefV8Context { v8::Local GetContext(); WebKit::WebFrame* GetWebFrame(); + v8::Handle GetHandle() { return handle_->GetHandle(); } + protected: - scoped_refptr v8_context_; + typedef CefV8Handle Handle; + scoped_refptr handle_; #ifndef NDEBUG // Used in debug builds to catch missing Exits in destructor. @@ -85,29 +82,7 @@ class CefV8ContextImpl : public CefV8Context { #endif IMPLEMENT_REFCOUNTING(CefV8ContextImpl); -}; - -// Special class for a v8::Value to ensure that it is deleted from the UI -// thread. -class CefV8ValueHandle: public CefReleaseV8HandleOnUIThread { - public: - CefV8ValueHandle(handleType value, CefTrackNode* tracker) - : superType(value), - tracker_(tracker) { - } - // Destructor implementation is provided in v8_impl.cc. - ~CefV8ValueHandle(); - - CefTrackNode* GetTracker() { - return tracker_; - } - - private: - // For Object and Function types, we need to hold on to a reference to their - // internal data or function handler objects that are reference counted. - CefTrackNode* tracker_; - - DISALLOW_COPY_AND_ASSIGN(CefV8ValueHandle); + DISALLOW_COPY_AND_ASSIGN(CefV8ContextImpl); }; class CefV8ValueImpl : public CefV8Value { @@ -166,16 +141,37 @@ class CefV8ValueImpl : public CefV8Value { CefRefPtr object, const CefV8ValueList& arguments) OVERRIDE; - inline v8::Handle GetHandle() { - DCHECK(v8_value_.get()); - return v8_value_->GetHandle(); - } + v8::Handle GetHandle() { return handle_->GetHandle(); } protected: // Test for and record any exception. bool HasCaught(v8::TryCatch& try_catch); - scoped_refptr v8_value_; + class Handle : + public base::RefCountedThreadSafe { + public: + typedef v8::Handle handleType; + typedef v8::Persistent persistentType; + + Handle(handleType v, CefTrackNode* tracker) + : handle_(persistentType::New(v)), + tracker_(tracker) { + } + ~Handle(); + + handleType GetHandle() { return handle_; } + + private: + persistentType handle_; + + // For Object and Function types, we need to hold on to a reference to their + // internal data or function handler objects that are reference counted. + CefTrackNode* tracker_; + + DISALLOW_COPY_AND_ASSIGN(Handle); + }; + scoped_refptr handle_; + CefRefPtr last_exception_; bool rethrow_exceptions_; @@ -183,4 +179,45 @@ class CefV8ValueImpl : public CefV8Value { DISALLOW_COPY_AND_ASSIGN(CefV8ValueImpl); }; +class CefV8StackTraceImpl : public CefV8StackTrace { + public: + explicit CefV8StackTraceImpl(v8::Handle handle); + virtual ~CefV8StackTraceImpl(); + + virtual int GetFrameCount() OVERRIDE; + virtual CefRefPtr GetFrame(int index) OVERRIDE; + + v8::Handle GetHandle() { return handle_->GetHandle(); } + + protected: + typedef CefV8Handle Handle; + scoped_refptr handle_; + + IMPLEMENT_REFCOUNTING(CefV8StackTraceImpl); + DISALLOW_COPY_AND_ASSIGN(CefV8StackTraceImpl); +}; + +class CefV8StackFrameImpl : public CefV8StackFrame { + public: + explicit CefV8StackFrameImpl(v8::Handle handle); + virtual ~CefV8StackFrameImpl(); + + virtual CefString GetScriptName() OVERRIDE; + virtual CefString GetScriptNameOrSourceURL() OVERRIDE; + virtual CefString GetFunctionName() OVERRIDE; + virtual int GetLineNumber() OVERRIDE; + virtual int GetColumn() OVERRIDE; + virtual bool IsEval() OVERRIDE; + virtual bool IsConstructor() OVERRIDE; + + v8::Handle GetHandle() { return handle_->GetHandle(); } + + protected: + typedef CefV8Handle Handle; + scoped_refptr handle_; + + IMPLEMENT_REFCOUNTING(CefV8StackFrameImpl); + DISALLOW_COPY_AND_ASSIGN(CefV8StackFrameImpl); +}; + #endif // CEF_LIBCEF_V8_IMPL_H_ diff --git a/cef1/libcef_dll/cpptoc/v8stack_frame_cpptoc.cc b/cef1/libcef_dll/cpptoc/v8stack_frame_cpptoc.cc new file mode 100644 index 000000000..3da6bc6c8 --- /dev/null +++ b/cef1/libcef_dll/cpptoc/v8stack_frame_cpptoc.cc @@ -0,0 +1,142 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/cpptoc/v8stack_frame_cpptoc.h" + + +// MEMBER FUNCTIONS - Body may be edited by hand. + +cef_string_userfree_t CEF_CALLBACK v8stack_frame_get_script_name( + struct _cef_v8stack_frame_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefString _retval = CefV8StackFrameCppToC::Get(self)->GetScriptName(); + + // Return type: string + return _retval.DetachToUserFree(); +} + +cef_string_userfree_t CEF_CALLBACK v8stack_frame_get_script_name_or_source_url( + struct _cef_v8stack_frame_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefString _retval = CefV8StackFrameCppToC::Get( + self)->GetScriptNameOrSourceURL(); + + // Return type: string + return _retval.DetachToUserFree(); +} + +cef_string_userfree_t CEF_CALLBACK v8stack_frame_get_function_name( + struct _cef_v8stack_frame_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefString _retval = CefV8StackFrameCppToC::Get(self)->GetFunctionName(); + + // Return type: string + return _retval.DetachToUserFree(); +} + +int CEF_CALLBACK v8stack_frame_get_line_number( + struct _cef_v8stack_frame_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + int _retval = CefV8StackFrameCppToC::Get(self)->GetLineNumber(); + + // Return type: simple + return _retval; +} + +int CEF_CALLBACK v8stack_frame_get_column(struct _cef_v8stack_frame_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + int _retval = CefV8StackFrameCppToC::Get(self)->GetColumn(); + + // Return type: simple + return _retval; +} + +int CEF_CALLBACK v8stack_frame_is_eval(struct _cef_v8stack_frame_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefV8StackFrameCppToC::Get(self)->IsEval(); + + // Return type: bool + return _retval; +} + +int CEF_CALLBACK v8stack_frame_is_constructor( + struct _cef_v8stack_frame_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + bool _retval = CefV8StackFrameCppToC::Get(self)->IsConstructor(); + + // Return type: bool + return _retval; +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefV8StackFrameCppToC::CefV8StackFrameCppToC(CefV8StackFrame* cls) + : CefCppToC( + cls) { + struct_.struct_.get_script_name = v8stack_frame_get_script_name; + struct_.struct_.get_script_name_or_source_url = + v8stack_frame_get_script_name_or_source_url; + struct_.struct_.get_function_name = v8stack_frame_get_function_name; + struct_.struct_.get_line_number = v8stack_frame_get_line_number; + struct_.struct_.get_column = v8stack_frame_get_column; + struct_.struct_.is_eval = v8stack_frame_is_eval; + struct_.struct_.is_constructor = v8stack_frame_is_constructor; +} + +#ifndef NDEBUG +template<> long CefCppToC::DebugObjCt = 0; +#endif + diff --git a/cef1/libcef_dll/cpptoc/v8stack_frame_cpptoc.h b/cef1/libcef_dll/cpptoc/v8stack_frame_cpptoc.h new file mode 100644 index 000000000..d5ee79a23 --- /dev/null +++ b/cef1/libcef_dll/cpptoc/v8stack_frame_cpptoc.h @@ -0,0 +1,37 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#ifndef CEF_LIBCEF_DLL_CPPTOC_V8STACK_FRAME_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_V8STACK_FRAME_CPPTOC_H_ +#pragma once + +#ifndef BUILDING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed DLL-side only") +#else // BUILDING_CEF_SHARED + +#include "include/cef_v8.h" +#include "include/capi/cef_v8_capi.h" +#include "libcef_dll/cpptoc/cpptoc.h" + +// Wrap a C++ class with a C structure. +// This class may be instantiated and accessed DLL-side only. +class CefV8StackFrameCppToC + : public CefCppToC { + public: + explicit CefV8StackFrameCppToC(CefV8StackFrame* cls); + virtual ~CefV8StackFrameCppToC() {} +}; + +#endif // BUILDING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CPPTOC_V8STACK_FRAME_CPPTOC_H_ + diff --git a/cef1/libcef_dll/cpptoc/v8stack_trace_cpptoc.cc b/cef1/libcef_dll/cpptoc/v8stack_trace_cpptoc.cc new file mode 100644 index 000000000..c7c884c5a --- /dev/null +++ b/cef1/libcef_dll/cpptoc/v8stack_trace_cpptoc.cc @@ -0,0 +1,79 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/cpptoc/v8stack_frame_cpptoc.h" +#include "libcef_dll/cpptoc/v8stack_trace_cpptoc.h" + + +// GLOBAL FUNCTIONS - Body may be edited by hand. + +CEF_EXPORT cef_v8stack_trace_t* cef_v8stack_trace_get_current(int frame_limit) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + CefRefPtr _retval = CefV8StackTrace::GetCurrent( + frame_limit); + + // Return type: refptr_same + return CefV8StackTraceCppToC::Wrap(_retval); +} + + +// MEMBER FUNCTIONS - Body may be edited by hand. + +int CEF_CALLBACK v8stack_trace_get_frame_count( + struct _cef_v8stack_trace_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + int _retval = CefV8StackTraceCppToC::Get(self)->GetFrameCount(); + + // Return type: simple + return _retval; +} + +struct _cef_v8stack_frame_t* CEF_CALLBACK v8stack_trace_get_frame( + struct _cef_v8stack_trace_t* self, int index) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = CefV8StackTraceCppToC::Get( + self)->GetFrame( + index); + + // Return type: refptr_same + return CefV8StackFrameCppToC::Wrap(_retval); +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefV8StackTraceCppToC::CefV8StackTraceCppToC(CefV8StackTrace* cls) + : CefCppToC( + cls) { + struct_.struct_.get_frame_count = v8stack_trace_get_frame_count; + struct_.struct_.get_frame = v8stack_trace_get_frame; +} + +#ifndef NDEBUG +template<> long CefCppToC::DebugObjCt = 0; +#endif + diff --git a/cef1/libcef_dll/cpptoc/v8stack_trace_cpptoc.h b/cef1/libcef_dll/cpptoc/v8stack_trace_cpptoc.h new file mode 100644 index 000000000..b2b65352f --- /dev/null +++ b/cef1/libcef_dll/cpptoc/v8stack_trace_cpptoc.h @@ -0,0 +1,37 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#ifndef CEF_LIBCEF_DLL_CPPTOC_V8STACK_TRACE_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_V8STACK_TRACE_CPPTOC_H_ +#pragma once + +#ifndef BUILDING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed DLL-side only") +#else // BUILDING_CEF_SHARED + +#include "include/cef_v8.h" +#include "include/capi/cef_v8_capi.h" +#include "libcef_dll/cpptoc/cpptoc.h" + +// Wrap a C++ class with a C structure. +// This class may be instantiated and accessed DLL-side only. +class CefV8StackTraceCppToC + : public CefCppToC { + public: + explicit CefV8StackTraceCppToC(CefV8StackTrace* cls); + virtual ~CefV8StackTraceCppToC() {} +}; + +#endif // BUILDING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CPPTOC_V8STACK_TRACE_CPPTOC_H_ + diff --git a/cef1/libcef_dll/ctocpp/v8stack_frame_ctocpp.cc b/cef1/libcef_dll/ctocpp/v8stack_frame_ctocpp.cc new file mode 100644 index 000000000..8d685df90 --- /dev/null +++ b/cef1/libcef_dll/ctocpp/v8stack_frame_ctocpp.cc @@ -0,0 +1,121 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/ctocpp/v8stack_frame_ctocpp.h" + + +// VIRTUAL METHODS - Body may be edited by hand. + +CefString CefV8StackFrameCToCpp::GetScriptName() { + if (CEF_MEMBER_MISSING(struct_, get_script_name)) + return CefString(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_string_userfree_t _retval = struct_->get_script_name(struct_); + + // Return type: string + CefString _retvalStr; + _retvalStr.AttachToUserFree(_retval); + return _retvalStr; +} + +CefString CefV8StackFrameCToCpp::GetScriptNameOrSourceURL() { + if (CEF_MEMBER_MISSING(struct_, get_script_name_or_source_url)) + return CefString(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_string_userfree_t _retval = struct_->get_script_name_or_source_url( + struct_); + + // Return type: string + CefString _retvalStr; + _retvalStr.AttachToUserFree(_retval); + return _retvalStr; +} + +CefString CefV8StackFrameCToCpp::GetFunctionName() { + if (CEF_MEMBER_MISSING(struct_, get_function_name)) + return CefString(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_string_userfree_t _retval = struct_->get_function_name(struct_); + + // Return type: string + CefString _retvalStr; + _retvalStr.AttachToUserFree(_retval); + return _retvalStr; +} + +int CefV8StackFrameCToCpp::GetLineNumber() { + if (CEF_MEMBER_MISSING(struct_, get_line_number)) + return 0; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->get_line_number(struct_); + + // Return type: simple + return _retval; +} + +int CefV8StackFrameCToCpp::GetColumn() { + if (CEF_MEMBER_MISSING(struct_, get_column)) + return 0; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->get_column(struct_); + + // Return type: simple + return _retval; +} + +bool CefV8StackFrameCToCpp::IsEval() { + if (CEF_MEMBER_MISSING(struct_, is_eval)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->is_eval(struct_); + + // Return type: bool + return _retval?true:false; +} + +bool CefV8StackFrameCToCpp::IsConstructor() { + if (CEF_MEMBER_MISSING(struct_, is_constructor)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->is_constructor(struct_); + + // Return type: bool + return _retval?true:false; +} + + +#ifndef NDEBUG +template<> long CefCToCpp::DebugObjCt = 0; +#endif + diff --git a/cef1/libcef_dll/ctocpp/v8stack_frame_ctocpp.h b/cef1/libcef_dll/ctocpp/v8stack_frame_ctocpp.h new file mode 100644 index 000000000..6a6a32999 --- /dev/null +++ b/cef1/libcef_dll/ctocpp/v8stack_frame_ctocpp.h @@ -0,0 +1,48 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#ifndef CEF_LIBCEF_DLL_CTOCPP_V8STACK_FRAME_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_V8STACK_FRAME_CTOCPP_H_ +#pragma once + +#ifndef USING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed wrapper-side only") +#else // USING_CEF_SHARED + +#include "include/cef_v8.h" +#include "include/capi/cef_v8_capi.h" +#include "libcef_dll/ctocpp/ctocpp.h" + +// Wrap a C structure with a C++ class. +// This class may be instantiated and accessed wrapper-side only. +class CefV8StackFrameCToCpp + : public CefCToCpp { + public: + explicit CefV8StackFrameCToCpp(cef_v8stack_frame_t* str) + : CefCToCpp( + str) {} + virtual ~CefV8StackFrameCToCpp() {} + + // CefV8StackFrame methods + virtual CefString GetScriptName() OVERRIDE; + virtual CefString GetScriptNameOrSourceURL() OVERRIDE; + virtual CefString GetFunctionName() OVERRIDE; + virtual int GetLineNumber() OVERRIDE; + virtual int GetColumn() OVERRIDE; + virtual bool IsEval() OVERRIDE; + virtual bool IsConstructor() OVERRIDE; +}; + +#endif // USING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CTOCPP_V8STACK_FRAME_CTOCPP_H_ + diff --git a/cef1/libcef_dll/ctocpp/v8stack_trace_ctocpp.cc b/cef1/libcef_dll/ctocpp/v8stack_trace_ctocpp.cc new file mode 100644 index 000000000..a569e3948 --- /dev/null +++ b/cef1/libcef_dll/ctocpp/v8stack_trace_ctocpp.cc @@ -0,0 +1,65 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/ctocpp/v8stack_frame_ctocpp.h" +#include "libcef_dll/ctocpp/v8stack_trace_ctocpp.h" + + +// STATIC METHODS - Body may be edited by hand. + +CefRefPtr CefV8StackTrace::GetCurrent(int frame_limit) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_v8stack_trace_t* _retval = cef_v8stack_trace_get_current( + frame_limit); + + // Return type: refptr_same + return CefV8StackTraceCToCpp::Wrap(_retval); +} + + +// VIRTUAL METHODS - Body may be edited by hand. + +int CefV8StackTraceCToCpp::GetFrameCount() { + if (CEF_MEMBER_MISSING(struct_, get_frame_count)) + return 0; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = struct_->get_frame_count(struct_); + + // Return type: simple + return _retval; +} + +CefRefPtr CefV8StackTraceCToCpp::GetFrame(int index) { + if (CEF_MEMBER_MISSING(struct_, get_frame)) + return NULL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_v8stack_frame_t* _retval = struct_->get_frame(struct_, + index); + + // Return type: refptr_same + return CefV8StackFrameCToCpp::Wrap(_retval); +} + + +#ifndef NDEBUG +template<> long CefCToCpp::DebugObjCt = 0; +#endif + diff --git a/cef1/libcef_dll/ctocpp/v8stack_trace_ctocpp.h b/cef1/libcef_dll/ctocpp/v8stack_trace_ctocpp.h new file mode 100644 index 000000000..05ac92a90 --- /dev/null +++ b/cef1/libcef_dll/ctocpp/v8stack_trace_ctocpp.h @@ -0,0 +1,43 @@ +// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#ifndef CEF_LIBCEF_DLL_CTOCPP_V8STACK_TRACE_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_V8STACK_TRACE_CTOCPP_H_ +#pragma once + +#ifndef USING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed wrapper-side only") +#else // USING_CEF_SHARED + +#include "include/cef_v8.h" +#include "include/capi/cef_v8_capi.h" +#include "libcef_dll/ctocpp/ctocpp.h" + +// Wrap a C structure with a C++ class. +// This class may be instantiated and accessed wrapper-side only. +class CefV8StackTraceCToCpp + : public CefCToCpp { + public: + explicit CefV8StackTraceCToCpp(cef_v8stack_trace_t* str) + : CefCToCpp( + str) {} + virtual ~CefV8StackTraceCToCpp() {} + + // CefV8StackTrace methods + virtual int GetFrameCount() OVERRIDE; + virtual CefRefPtr GetFrame(int index) OVERRIDE; +}; + +#endif // USING_CEF_SHARED +#endif // CEF_LIBCEF_DLL_CTOCPP_V8STACK_TRACE_CTOCPP_H_ + diff --git a/cef1/libcef_dll/libcef_dll.cc b/cef1/libcef_dll/libcef_dll.cc index 9df6cc97c..f04f6fabb 100644 --- a/cef1/libcef_dll/libcef_dll.cc +++ b/cef1/libcef_dll/libcef_dll.cc @@ -40,6 +40,8 @@ #include "libcef_dll/cpptoc/stream_writer_cpptoc.h" #include "libcef_dll/cpptoc/v8context_cpptoc.h" #include "libcef_dll/cpptoc/v8exception_cpptoc.h" +#include "libcef_dll/cpptoc/v8stack_frame_cpptoc.h" +#include "libcef_dll/cpptoc/v8stack_trace_cpptoc.h" #include "libcef_dll/cpptoc/v8value_cpptoc.h" #include "libcef_dll/cpptoc/web_plugin_info_cpptoc.h" #include "libcef_dll/cpptoc/web_urlrequest_cpptoc.h" @@ -154,6 +156,8 @@ CEF_EXPORT void cef_shutdown() { DCHECK_EQ(CefV8ContextHandlerCToCpp::DebugObjCt, 0); DCHECK_EQ(CefV8ExceptionCppToC::DebugObjCt, 0); DCHECK_EQ(CefV8HandlerCToCpp::DebugObjCt, 0); + DCHECK_EQ(CefV8StackFrameCppToC::DebugObjCt, 0); + DCHECK_EQ(CefV8StackTraceCppToC::DebugObjCt, 0); DCHECK_EQ(CefV8ValueCppToC::DebugObjCt, 0); DCHECK_EQ(CefWebPluginInfoCppToC::DebugObjCt, 0); DCHECK_EQ(CefWebURLRequestClientCToCpp::DebugObjCt, 0); diff --git a/cef1/libcef_dll/wrapper/libcef_dll_wrapper.cc b/cef1/libcef_dll/wrapper/libcef_dll_wrapper.cc index 1909a902d..14496bfff 100644 --- a/cef1/libcef_dll/wrapper/libcef_dll_wrapper.cc +++ b/cef1/libcef_dll/wrapper/libcef_dll_wrapper.cc @@ -71,6 +71,8 @@ #include "libcef_dll/ctocpp/stream_writer_ctocpp.h" #include "libcef_dll/ctocpp/v8context_ctocpp.h" #include "libcef_dll/ctocpp/v8exception_ctocpp.h" +#include "libcef_dll/ctocpp/v8stack_frame_ctocpp.h" +#include "libcef_dll/ctocpp/v8stack_trace_ctocpp.h" #include "libcef_dll/ctocpp/v8value_ctocpp.h" #include "libcef_dll/ctocpp/web_plugin_info_ctocpp.h" #include "libcef_dll/ctocpp/web_urlrequest_ctocpp.h" @@ -156,6 +158,8 @@ CEF_GLOBAL void CefShutdown() { DCHECK_EQ(CefV8ContextHandlerCppToC::DebugObjCt, 0); DCHECK_EQ(CefV8ExceptionCToCpp::DebugObjCt, 0); DCHECK_EQ(CefV8HandlerCppToC::DebugObjCt, 0); + DCHECK_EQ(CefV8StackFrameCToCpp::DebugObjCt, 0); + DCHECK_EQ(CefV8StackTraceCToCpp::DebugObjCt, 0); DCHECK_EQ(CefV8ValueCToCpp::DebugObjCt, 0); DCHECK_EQ(CefWebPluginInfoCToCpp::DebugObjCt, 0); DCHECK_EQ(CefWebURLRequestCToCpp::DebugObjCt, 0); diff --git a/cef1/tests/unittests/v8_unittest.cc b/cef1/tests/unittests/v8_unittest.cc index 2ae369877..b881d266d 100644 --- a/cef1/tests/unittests/v8_unittest.cc +++ b/cef1/tests/unittests/v8_unittest.cc @@ -54,6 +54,7 @@ enum V8TestMode { V8TEST_CONTEXT_EVAL_EXCEPTION, V8TEST_CONTEXT_ENTERED, V8TEST_BINDING, + V8TEST_STACK_TRACE, }; @@ -176,6 +177,9 @@ class V8TestHandler : public TestHandler { case V8TEST_BINDING: RunBindingTest(); break; + case V8TEST_STACK_TRACE: + RunStackTraceTest(); + break; default: ADD_FAILURE(); DestroyTest(); @@ -1398,6 +1402,90 @@ class V8TestHandler : public TestHandler { DestroyTest(); } + void RunStackTraceTest() { + CefRefPtr context = GetContext(); + + static const char* kFuncName = "myfunc"; + + class Handler : public CefV8Handler { + public: + Handler() {} + virtual bool Execute(const CefString& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + CefString& exception) OVERRIDE { + EXPECT_STREQ(kFuncName, name.ToString().c_str()); + + stack_trace_ = CefV8StackTrace::GetCurrent(10); + + retval = CefV8Value::CreateInt(3); + got_execute_.yes(); + return true; + } + + TrackCallback got_execute_; + CefRefPtr stack_trace_; + + IMPLEMENT_REFCOUNTING(Handler); + }; + + // Enter the V8 context. + EXPECT_TRUE(context->Enter()); + + Handler* handler = new Handler; + CefRefPtr handlerPtr(handler); + + CefRefPtr func = + CefV8Value::CreateFunction(kFuncName, handler); + EXPECT_TRUE(func.get()); + CefRefPtr obj = context->GetGlobal(); + EXPECT_TRUE(obj.get()); + obj->SetValue(kFuncName, func, V8_PROPERTY_ATTRIBUTE_NONE); + + CefRefPtr retval; + CefRefPtr exception; + + EXPECT_TRUE(context->Eval( + "function jsfunc() { return window.myfunc(); }\n" + "jsfunc();", + retval, exception)); + EXPECT_TRUE(retval.get()); + EXPECT_TRUE(retval->IsInt()); + EXPECT_EQ(3, retval->GetIntValue()); + EXPECT_FALSE(exception.get()); + + EXPECT_TRUE(handler->stack_trace_.get()); + EXPECT_EQ(2, handler->stack_trace_->GetFrameCount()); + + CefRefPtr frame; + + frame = handler->stack_trace_->GetFrame(0); + EXPECT_TRUE(frame->GetScriptName().empty()); + EXPECT_TRUE(frame->GetScriptNameOrSourceURL().empty()); + EXPECT_STREQ("jsfunc", frame->GetFunctionName().ToString().c_str()); + EXPECT_EQ(1, frame->GetLineNumber()); + EXPECT_EQ(35, frame->GetColumn()); + EXPECT_TRUE(frame.get()); + EXPECT_TRUE(frame->IsEval()); + EXPECT_FALSE(frame->IsConstructor()); + + frame = handler->stack_trace_->GetFrame(1); + EXPECT_TRUE(frame->GetScriptName().empty()); + EXPECT_TRUE(frame->GetScriptNameOrSourceURL().empty()); + EXPECT_TRUE(frame->GetFunctionName().empty()); + EXPECT_EQ(2, frame->GetLineNumber()); + EXPECT_EQ(1, frame->GetColumn()); + EXPECT_TRUE(frame.get()); + EXPECT_TRUE(frame->IsEval()); + EXPECT_FALSE(frame->IsConstructor()); + + // Exit the V8 context. + EXPECT_TRUE(context->Exit()); + + DestroyTest(); + } + virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) OVERRIDE { @@ -1521,6 +1609,7 @@ V8_TEST(ContextEval, V8TEST_CONTEXT_EVAL); V8_TEST(ContextEvalException, V8TEST_CONTEXT_EVAL_EXCEPTION); V8_TEST_EX(ContextEntered, V8TEST_CONTEXT_ENTERED, NULL); V8_TEST_EX(Binding, V8TEST_BINDING, kV8BindingTestUrl); +V8_TEST(StackTrace, V8TEST_STACK_TRACE); namespace {