Add support for native creation and resolution of Promises (fixes issue #3305)
This commit is contained in:
parent
60ee4a34aa
commit
fa643b269e
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=98f6d1c93609958fa457c15d7f6fef56fac7e3f6$
|
||||
// $hash=b8af0d090bcb54f99d98804f7e3aaa0eab24449a$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_V8_CAPI_H_
|
||||
|
@ -454,6 +454,11 @@ typedef struct _cef_v8value_t {
|
|||
///
|
||||
int(CEF_CALLBACK* is_function)(struct _cef_v8value_t* self);
|
||||
|
||||
///
|
||||
/// True if the value type is a Promise.
|
||||
///
|
||||
int(CEF_CALLBACK* is_promise)(struct _cef_v8value_t* self);
|
||||
|
||||
///
|
||||
/// Returns true (1) if this object is pointing to the same handle as |that|
|
||||
/// object.
|
||||
|
@ -718,6 +723,27 @@ typedef struct _cef_v8value_t {
|
|||
struct _cef_v8value_t* object,
|
||||
size_t argumentsCount,
|
||||
struct _cef_v8value_t* const* arguments);
|
||||
|
||||
///
|
||||
/// Resolve the Promise using the current V8 context. This function should
|
||||
/// only be called from within the scope of a cef_v8handler_t or
|
||||
/// cef_v8accessor_t callback, or in combination with calling enter() and
|
||||
/// exit() on a stored cef_v8context_t reference. |arg| is the argument passed
|
||||
/// to the resolved promise. Returns true (1) on success. Returns false (0) if
|
||||
/// this function is called incorrectly or an exception is thrown.
|
||||
///
|
||||
int(CEF_CALLBACK* resolve_promise)(struct _cef_v8value_t* self,
|
||||
struct _cef_v8value_t* arg);
|
||||
|
||||
///
|
||||
/// Reject the Promise using the current V8 context. This function should only
|
||||
/// be called from within the scope of a cef_v8handler_t or cef_v8accessor_t
|
||||
/// callback, or in combination with calling enter() and exit() on a stored
|
||||
/// cef_v8context_t reference. Returns true (1) on success. Returns false (0)
|
||||
/// if this function is called incorrectly or an exception is thrown.
|
||||
///
|
||||
int(CEF_CALLBACK* reject_promise)(struct _cef_v8value_t* self,
|
||||
const cef_string_t* errorMsg);
|
||||
} cef_v8value_t;
|
||||
|
||||
///
|
||||
|
@ -808,6 +834,14 @@ CEF_EXPORT cef_v8value_t* cef_v8value_create_array_buffer(
|
|||
CEF_EXPORT cef_v8value_t* cef_v8value_create_function(const cef_string_t* name,
|
||||
cef_v8handler_t* handler);
|
||||
|
||||
///
|
||||
/// Create a new cef_v8value_t object of type Promise. This function should only
|
||||
/// be called from within the scope of a cef_render_process_handler_t,
|
||||
/// cef_v8handler_t or cef_v8accessor_t callback, or in combination with calling
|
||||
/// enter() and exit() on a stored cef_v8context_t reference.
|
||||
///
|
||||
CEF_EXPORT cef_v8value_t* cef_v8value_create_promise(void);
|
||||
|
||||
///
|
||||
/// Structure representing a V8 stack trace handle. V8 handles can only be
|
||||
/// accessed from the thread on which they are created. Valid threads for
|
||||
|
|
|
@ -42,13 +42,13 @@
|
|||
// way that may cause binary incompatibility with other builds. The universal
|
||||
// hash value will change if any platform is affected whereas the platform hash
|
||||
// values will change only if that particular platform is affected.
|
||||
#define CEF_API_HASH_UNIVERSAL "c06406b23dc4a845177dcd306541ce527d061364"
|
||||
#define CEF_API_HASH_UNIVERSAL "dfec58669a2c79108d61246f4e523570c3a21f63"
|
||||
#if defined(OS_WIN)
|
||||
#define CEF_API_HASH_PLATFORM "edd206c50f636a935872c9cc251ccb9448b9050e"
|
||||
#define CEF_API_HASH_PLATFORM "bd5a6f54227d8bd35d33580342cd78f81d0cee2e"
|
||||
#elif defined(OS_MAC)
|
||||
#define CEF_API_HASH_PLATFORM "a74e6429302d2d947cc614688e83cd3b29e74c17"
|
||||
#define CEF_API_HASH_PLATFORM "11902ab39267c1048acfa5c41053c6cfe0bd6227"
|
||||
#elif defined(OS_LINUX)
|
||||
#define CEF_API_HASH_PLATFORM "e119b68ec7e406ca74ddea5e244af7150eef7118"
|
||||
#define CEF_API_HASH_PLATFORM "213fb79db129c756661e7cfbe6749c15276bbebf"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -536,6 +536,15 @@ class CefV8Value : public virtual CefBaseRefCounted {
|
|||
static CefRefPtr<CefV8Value> CreateFunction(const CefString& name,
|
||||
CefRefPtr<CefV8Handler> handler);
|
||||
|
||||
///
|
||||
/// Create a new CefV8Value object of type Promise. This method should only be
|
||||
/// called from within the scope of a CefRenderProcessHandler, CefV8Handler or
|
||||
/// CefV8Accessor callback, or in combination with calling Enter() and Exit()
|
||||
/// on a stored CefV8Context reference.
|
||||
///
|
||||
/*--cef()--*/
|
||||
static CefRefPtr<CefV8Value> CreatePromise();
|
||||
|
||||
///
|
||||
/// Returns true if the underlying handle is valid and it can be accessed on
|
||||
/// the current thread. Do not call any other methods if this method returns
|
||||
|
@ -616,6 +625,12 @@ class CefV8Value : public virtual CefBaseRefCounted {
|
|||
/*--cef()--*/
|
||||
virtual bool IsFunction() = 0;
|
||||
|
||||
///
|
||||
/// True if the value type is a Promise.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool IsPromise() = 0;
|
||||
|
||||
///
|
||||
/// Returns true if this object is pointing to the same handle as |that|
|
||||
/// object.
|
||||
|
@ -893,6 +908,29 @@ class CefV8Value : public virtual CefBaseRefCounted {
|
|||
CefRefPtr<CefV8Context> context,
|
||||
CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments) = 0;
|
||||
|
||||
// PROMISE METHODS - These methods are only available on Promises.
|
||||
|
||||
///
|
||||
/// Resolve the Promise using the current V8 context. This method should only
|
||||
/// be called from within the scope of a CefV8Handler or CefV8Accessor
|
||||
/// callback, or in combination with calling Enter() and Exit() on a stored
|
||||
/// CefV8Context reference. |arg| is the argument passed to the resolved
|
||||
/// promise. Returns true on success. Returns false if this method is called
|
||||
/// incorrectly or an exception is thrown.
|
||||
///
|
||||
/*--cef(optional_param=arg)--*/
|
||||
virtual bool ResolvePromise(CefRefPtr<CefV8Value> arg) = 0;
|
||||
|
||||
///
|
||||
/// Reject the Promise using the current V8 context. This method should only
|
||||
/// be called from within the scope of a CefV8Handler or CefV8Accessor
|
||||
/// callback, or in combination with calling Enter() and Exit() on a stored
|
||||
/// CefV8Context reference. Returns true on success. Returns false if this
|
||||
/// method is called incorrectly or an exception is thrown.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool RejectPromise(const CefString& errorMsg) = 0;
|
||||
};
|
||||
|
||||
///
|
||||
|
|
|
@ -1480,6 +1480,33 @@ CefRefPtr<CefV8Value> CefV8Value::CreateFunction(
|
|||
return impl.get();
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefV8Value> CefV8Value::CreatePromise() {
|
||||
CEF_V8_REQUIRE_ISOLATE_RETURN(nullptr);
|
||||
v8::Isolate* isolate = GetIsolateManager()->isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
if (context.IsEmpty()) {
|
||||
NOTREACHED() << "not currently in a V8 context";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
v8::Local<v8::Promise::Resolver> promise_resolver =
|
||||
v8::Promise::Resolver::New(context).ToLocalChecked();
|
||||
|
||||
// Create a tracker object that will cause the user data reference to be
|
||||
// released when the V8 object is destroyed.
|
||||
V8TrackObject* tracker = new V8TrackObject(isolate);
|
||||
|
||||
// Attach the tracker object.
|
||||
tracker->AttachTo(context, promise_resolver);
|
||||
|
||||
CefRefPtr<CefV8ValueImpl> impl = new CefV8ValueImpl(isolate);
|
||||
impl->InitObject(promise_resolver, tracker);
|
||||
return impl.get();
|
||||
}
|
||||
|
||||
// CefV8ValueImpl
|
||||
|
||||
CefV8ValueImpl::CefV8ValueImpl(v8::Isolate* isolate)
|
||||
|
@ -1713,6 +1740,16 @@ bool CefV8ValueImpl::IsFunction() {
|
|||
}
|
||||
}
|
||||
|
||||
bool CefV8ValueImpl::IsPromise() {
|
||||
CEF_V8_REQUIRE_MLT_RETURN(false);
|
||||
if (type_ == TYPE_OBJECT) {
|
||||
v8::HandleScope handle_scope(handle_->isolate());
|
||||
return handle_->GetNewV8Handle(false)->IsPromise();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CefV8ValueImpl::IsSame(CefRefPtr<CefV8Value> that) {
|
||||
CEF_V8_REQUIRE_MLT_RETURN(false);
|
||||
|
||||
|
@ -2444,6 +2481,75 @@ CefRefPtr<CefV8Value> CefV8ValueImpl::ExecuteFunctionWithContext(
|
|||
return retval;
|
||||
}
|
||||
|
||||
bool CefV8ValueImpl::ResolvePromise(CefRefPtr<CefV8Value> arg) {
|
||||
CEF_V8_REQUIRE_OBJECT_RETURN(false);
|
||||
|
||||
v8::Isolate* isolate = handle_->isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Value> value = handle_->GetNewV8Handle(false);
|
||||
if (!value->IsPromise()) {
|
||||
NOTREACHED() << "V8 value is not a Promise";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arg.get() && !arg->IsValid()) {
|
||||
NOTREACHED() << "invalid V8 arg parameter";
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> context_local = isolate->GetCurrentContext();
|
||||
|
||||
v8::Context::Scope context_scope(context_local);
|
||||
|
||||
v8::Local<v8::Object> obj = value->ToObject(context_local).ToLocalChecked();
|
||||
v8::Local<v8::Promise::Resolver> promise =
|
||||
v8::Local<v8::Promise::Resolver>::Cast(obj);
|
||||
|
||||
v8::TryCatch try_catch(isolate);
|
||||
try_catch.SetVerbose(true);
|
||||
|
||||
if (arg.get()) {
|
||||
promise
|
||||
->Resolve(context_local,
|
||||
static_cast<CefV8ValueImpl*>(arg.get())->GetV8Value(true))
|
||||
.ToChecked();
|
||||
} else {
|
||||
promise->Resolve(context_local, v8::Undefined(isolate)).ToChecked();
|
||||
}
|
||||
|
||||
return !HasCaught(context_local, try_catch);
|
||||
}
|
||||
|
||||
bool CefV8ValueImpl::RejectPromise(const CefString& errorMsg) {
|
||||
CEF_V8_REQUIRE_OBJECT_RETURN(false);
|
||||
|
||||
v8::Isolate* isolate = handle_->isolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Value> value = handle_->GetNewV8Handle(false);
|
||||
if (!value->IsPromise()) {
|
||||
NOTREACHED() << "V8 value is not a Promise";
|
||||
return false;
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> context_local = isolate->GetCurrentContext();
|
||||
|
||||
v8::Context::Scope context_scope(context_local);
|
||||
|
||||
v8::Local<v8::Object> obj = value->ToObject(context_local).ToLocalChecked();
|
||||
v8::Local<v8::Promise::Resolver> promise =
|
||||
v8::Local<v8::Promise::Resolver>::Cast(obj);
|
||||
|
||||
v8::TryCatch try_catch(isolate);
|
||||
try_catch.SetVerbose(true);
|
||||
|
||||
promise
|
||||
->Reject(context_local,
|
||||
v8::Exception::Error(GetV8String(isolate, errorMsg)))
|
||||
.ToChecked();
|
||||
|
||||
return !HasCaught(context_local, try_catch);
|
||||
}
|
||||
|
||||
bool CefV8ValueImpl::HasCaught(v8::Local<v8::Context> context,
|
||||
v8::TryCatch& try_catch) {
|
||||
if (try_catch.HasCaught()) {
|
||||
|
|
|
@ -237,6 +237,7 @@ class CefV8ValueImpl : public CefV8Value {
|
|||
bool IsArray() override;
|
||||
bool IsArrayBuffer() override;
|
||||
bool IsFunction() override;
|
||||
bool IsPromise() override;
|
||||
bool IsSame(CefRefPtr<CefV8Value> value) override;
|
||||
bool GetBoolValue() override;
|
||||
int32 GetIntValue() override;
|
||||
|
@ -282,6 +283,9 @@ class CefV8ValueImpl : public CefV8Value {
|
|||
CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments) override;
|
||||
|
||||
bool ResolvePromise(CefRefPtr<CefV8Value> arg) override;
|
||||
bool RejectPromise(const CefString& errorMsg) override;
|
||||
|
||||
private:
|
||||
// Test for and record any exception.
|
||||
bool HasCaught(v8::Local<v8::Context> context, v8::TryCatch& try_catch);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=46a80d60441e386e6a8999ecb5fd338f3f6b4319$
|
||||
// $hash=5dd413b62070b7d80292faf8396d3b795dd4035e$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/v8value_cpptoc.h"
|
||||
|
@ -178,6 +178,16 @@ CEF_EXPORT cef_v8value_t* cef_v8value_create_function(
|
|||
return CefV8ValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
CEF_EXPORT cef_v8value_t* cef_v8value_create_promise() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
CefRefPtr<CefV8Value> _retval = CefV8Value::CreatePromise();
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefV8ValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// MEMBER FUNCTIONS - Body may be edited by hand.
|
||||
|
@ -364,6 +374,20 @@ int CEF_CALLBACK v8value_is_function(struct _cef_v8value_t* self) {
|
|||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK v8value_is_promise(struct _cef_v8value_t* self) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval = CefV8ValueCppToC::Get(self)->IsPromise();
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK v8value_is_same(struct _cef_v8value_t* self,
|
||||
struct _cef_v8value_t* that) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
@ -974,6 +998,43 @@ v8value_execute_function_with_context(struct _cef_v8value_t* self,
|
|||
return CefV8ValueCppToC::Wrap(_retval);
|
||||
}
|
||||
|
||||
int CEF_CALLBACK v8value_resolve_promise(struct _cef_v8value_t* self,
|
||||
struct _cef_v8value_t* arg) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
// Unverified params: arg
|
||||
|
||||
// Execute
|
||||
bool _retval = CefV8ValueCppToC::Get(self)->ResolvePromise(
|
||||
CefV8ValueCppToC::Unwrap(arg));
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK v8value_reject_promise(struct _cef_v8value_t* self,
|
||||
const cef_string_t* errorMsg) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self)
|
||||
return 0;
|
||||
// Verify param: errorMsg; type: string_byref_const
|
||||
DCHECK(errorMsg);
|
||||
if (!errorMsg)
|
||||
return 0;
|
||||
|
||||
// Execute
|
||||
bool _retval =
|
||||
CefV8ValueCppToC::Get(self)->RejectPromise(CefString(errorMsg));
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
@ -992,6 +1053,7 @@ CefV8ValueCppToC::CefV8ValueCppToC() {
|
|||
GetStruct()->is_array = v8value_is_array;
|
||||
GetStruct()->is_array_buffer = v8value_is_array_buffer;
|
||||
GetStruct()->is_function = v8value_is_function;
|
||||
GetStruct()->is_promise = v8value_is_promise;
|
||||
GetStruct()->is_same = v8value_is_same;
|
||||
GetStruct()->get_bool_value = v8value_get_bool_value;
|
||||
GetStruct()->get_int_value = v8value_get_int_value;
|
||||
|
@ -1030,6 +1092,8 @@ CefV8ValueCppToC::CefV8ValueCppToC() {
|
|||
GetStruct()->execute_function = v8value_execute_function;
|
||||
GetStruct()->execute_function_with_context =
|
||||
v8value_execute_function_with_context;
|
||||
GetStruct()->resolve_promise = v8value_resolve_promise;
|
||||
GetStruct()->reject_promise = v8value_reject_promise;
|
||||
}
|
||||
|
||||
// DESTRUCTOR - Do not edit by hand.
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=1dd04012b442aa3ceae8d56653dc499aed1e181f$
|
||||
// $hash=17fe0420a1c56309ff2156c9d7f7a4def484bd15$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/v8value_ctocpp.h"
|
||||
|
@ -188,6 +188,16 @@ CefRefPtr<CefV8Value> CefV8Value::CreateFunction(
|
|||
return CefV8ValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") CefRefPtr<CefV8Value> CefV8Value::CreatePromise() {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
cef_v8value_t* _retval = cef_v8value_create_promise();
|
||||
|
||||
// Return type: refptr_same
|
||||
return CefV8ValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
// VIRTUAL METHODS - Body may be edited by hand.
|
||||
|
||||
NO_SANITIZE("cfi-icall") bool CefV8ValueCToCpp::IsValid() {
|
||||
|
@ -372,6 +382,20 @@ NO_SANITIZE("cfi-icall") bool CefV8ValueCToCpp::IsFunction() {
|
|||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") bool CefV8ValueCToCpp::IsPromise() {
|
||||
cef_v8value_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, is_promise))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->is_promise(_struct);
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefV8ValueCToCpp::IsSame(CefRefPtr<CefV8Value> that) {
|
||||
cef_v8value_t* _struct = GetStruct();
|
||||
|
@ -988,6 +1012,44 @@ CefRefPtr<CefV8Value> CefV8ValueCToCpp::ExecuteFunctionWithContext(
|
|||
return CefV8ValueCToCpp::Wrap(_retval);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefV8ValueCToCpp::ResolvePromise(CefRefPtr<CefV8Value> arg) {
|
||||
cef_v8value_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, resolve_promise))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Unverified params: arg
|
||||
|
||||
// Execute
|
||||
int _retval =
|
||||
_struct->resolve_promise(_struct, CefV8ValueCToCpp::Unwrap(arg));
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefV8ValueCToCpp::RejectPromise(const CefString& errorMsg) {
|
||||
cef_v8value_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, reject_promise))
|
||||
return false;
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: errorMsg; type: string_byref_const
|
||||
DCHECK(!errorMsg.empty());
|
||||
if (errorMsg.empty())
|
||||
return false;
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->reject_promise(_struct, errorMsg.GetStruct());
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
// CONSTRUCTOR - Do not edit by hand.
|
||||
|
||||
CefV8ValueCToCpp::CefV8ValueCToCpp() {}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=012bb9108d28ddefb6ebc58963be24469b79146f$
|
||||
// $hash=ee45dceec69f21be7a17e0c10ed15b29f28e63ec$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_V8VALUE_CTOCPP_H_
|
||||
|
@ -47,6 +47,7 @@ class CefV8ValueCToCpp
|
|||
bool IsArray() override;
|
||||
bool IsArrayBuffer() override;
|
||||
bool IsFunction() override;
|
||||
bool IsPromise() override;
|
||||
bool IsSame(CefRefPtr<CefV8Value> that) override;
|
||||
bool GetBoolValue() override;
|
||||
int32 GetIntValue() override;
|
||||
|
@ -91,6 +92,8 @@ class CefV8ValueCToCpp
|
|||
CefRefPtr<CefV8Context> context,
|
||||
CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments) override;
|
||||
bool ResolvePromise(CefRefPtr<CefV8Value> arg) override;
|
||||
bool RejectPromise(const CefString& errorMsg) override;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_DLL_CTOCPP_V8VALUE_CTOCPP_H_
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=6c8f094d04b36c879f379e87ebf45dc4698eb41e$
|
||||
// $hash=a753ff43760df4f3c1126d248b4128ca14a8cd68$
|
||||
//
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
@ -204,6 +204,7 @@ struct libcef_pointers {
|
|||
decltype(&cef_v8value_create_array) cef_v8value_create_array;
|
||||
decltype(&cef_v8value_create_array_buffer) cef_v8value_create_array_buffer;
|
||||
decltype(&cef_v8value_create_function) cef_v8value_create_function;
|
||||
decltype(&cef_v8value_create_promise) cef_v8value_create_promise;
|
||||
decltype(&cef_v8stack_trace_get_current) cef_v8stack_trace_get_current;
|
||||
decltype(&cef_value_create) cef_value_create;
|
||||
decltype(&cef_binary_value_create) cef_binary_value_create;
|
||||
|
@ -420,6 +421,7 @@ int libcef_init_pointers(const char* path) {
|
|||
INIT_ENTRY(cef_v8value_create_array);
|
||||
INIT_ENTRY(cef_v8value_create_array_buffer);
|
||||
INIT_ENTRY(cef_v8value_create_function);
|
||||
INIT_ENTRY(cef_v8value_create_promise);
|
||||
INIT_ENTRY(cef_v8stack_trace_get_current);
|
||||
INIT_ENTRY(cef_value_create);
|
||||
INIT_ENTRY(cef_binary_value_create);
|
||||
|
@ -1114,6 +1116,10 @@ struct _cef_v8value_t* cef_v8value_create_function(
|
|||
return g_libcef_pointers.cef_v8value_create_function(name, handler);
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall") struct _cef_v8value_t* cef_v8value_create_promise() {
|
||||
return g_libcef_pointers.cef_v8value_create_promise();
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
struct _cef_v8stack_trace_t* cef_v8stack_trace_get_current(int frame_limit) {
|
||||
return g_libcef_pointers.cef_v8stack_trace_get_current(frame_limit);
|
||||
|
|
|
@ -84,6 +84,12 @@ enum V8TestMode {
|
|||
V8TEST_FUNCTION_HANDLER_NO_OBJECT,
|
||||
V8TEST_FUNCTION_HANDLER_WITH_CONTEXT,
|
||||
V8TEST_FUNCTION_HANDLER_EMPTY_STRING,
|
||||
V8TEST_PROMISE_CREATE,
|
||||
V8TEST_PROMISE_RESOLVE,
|
||||
V8TEST_PROMISE_RESOLVE_NO_ARGUMENT,
|
||||
V8TEST_PROMISE_RESOLVE_HANDLER,
|
||||
V8TEST_PROMISE_REJECT,
|
||||
V8TEST_PROMISE_REJECT_HANDLER,
|
||||
V8TEST_CONTEXT_EVAL,
|
||||
V8TEST_CONTEXT_EVAL_EXCEPTION,
|
||||
V8TEST_CONTEXT_EVAL_CSP_BYPASS_UNSAFE_EVAL,
|
||||
|
@ -214,6 +220,24 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
case V8TEST_FUNCTION_HANDLER_EMPTY_STRING:
|
||||
RunFunctionHandlerEmptyStringTest();
|
||||
break;
|
||||
case V8TEST_PROMISE_CREATE:
|
||||
RunPromiseCreateTest();
|
||||
break;
|
||||
case V8TEST_PROMISE_RESOLVE:
|
||||
RunPromiseResolveTest();
|
||||
break;
|
||||
case V8TEST_PROMISE_RESOLVE_NO_ARGUMENT:
|
||||
RunPromiseResolveNoArgumentTest();
|
||||
break;
|
||||
case V8TEST_PROMISE_RESOLVE_HANDLER:
|
||||
RunPromiseResolveHandlerTest();
|
||||
break;
|
||||
case V8TEST_PROMISE_REJECT:
|
||||
RunPromiseRejectTest();
|
||||
break;
|
||||
case V8TEST_PROMISE_REJECT_HANDLER:
|
||||
RunPromiseRejectHandlerTest();
|
||||
break;
|
||||
case V8TEST_CONTEXT_EVAL:
|
||||
RunContextEvalTest();
|
||||
break;
|
||||
|
@ -273,6 +297,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsInt());
|
||||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -293,6 +318,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -315,6 +341,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsFunction());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -337,6 +364,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsFunction());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -357,6 +385,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -396,6 +425,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -416,6 +446,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsInt());
|
||||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -437,6 +468,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsObject());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
@ -466,6 +498,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsInt());
|
||||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -645,6 +678,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsInt());
|
||||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
// Exit the V8 context.
|
||||
|
@ -1900,6 +1934,7 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
EXPECT_FALSE(value->IsInt());
|
||||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsPromise());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
|
@ -2228,6 +2263,248 @@ class V8RendererTest : public ClientAppRenderer::Delegate,
|
|||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunPromiseCreateTest() {
|
||||
CefRefPtr<CefV8Context> context = GetContext();
|
||||
|
||||
// Enter the V8 context.
|
||||
EXPECT_TRUE(context->Enter());
|
||||
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreatePromise();
|
||||
|
||||
// Exit the V8 context.
|
||||
EXPECT_TRUE(context->Exit());
|
||||
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->IsPromise());
|
||||
EXPECT_TRUE(value->IsObject());
|
||||
|
||||
EXPECT_FALSE(value->IsUndefined());
|
||||
EXPECT_FALSE(value->IsArray());
|
||||
EXPECT_FALSE(value->IsBool());
|
||||
EXPECT_FALSE(value->IsDate());
|
||||
EXPECT_FALSE(value->IsDouble());
|
||||
EXPECT_FALSE(value->IsFunction());
|
||||
EXPECT_FALSE(value->IsInt());
|
||||
EXPECT_FALSE(value->IsUInt());
|
||||
EXPECT_FALSE(value->IsNull());
|
||||
EXPECT_FALSE(value->IsString());
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunPromiseResolveTest() {
|
||||
CefRefPtr<CefV8Context> context = GetContext();
|
||||
|
||||
// Enter the V8 context.
|
||||
EXPECT_TRUE(context->Enter());
|
||||
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreatePromise();
|
||||
CefRefPtr<CefV8Value> obj = CefV8Value::CreateObject(nullptr, nullptr);
|
||||
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->ResolvePromise(obj));
|
||||
|
||||
// Exit the V8 context.
|
||||
EXPECT_TRUE(context->Exit());
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunPromiseResolveNoArgumentTest() {
|
||||
CefRefPtr<CefV8Context> context = GetContext();
|
||||
|
||||
// Enter the V8 context.
|
||||
EXPECT_TRUE(context->Enter());
|
||||
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreatePromise();
|
||||
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->ResolvePromise(nullptr));
|
||||
|
||||
// Exit the V8 context.
|
||||
EXPECT_TRUE(context->Exit());
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunPromiseResolveHandlerTest() {
|
||||
CefRefPtr<CefV8Context> context = GetContext();
|
||||
|
||||
static const char* kPromiseName = "myprom";
|
||||
static const char* kResolveName = "myresolve";
|
||||
static const char* kRejectName = "myreject";
|
||||
static const int kVal1 = 32;
|
||||
|
||||
class Handler : public CefV8Handler {
|
||||
public:
|
||||
Handler() {}
|
||||
bool Execute(const CefString& name,
|
||||
CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments,
|
||||
CefRefPtr<CefV8Value>& retval,
|
||||
CefString& exception) override {
|
||||
EXPECT_STREQ(kResolveName, name.ToString().c_str());
|
||||
EXPECT_EQ((size_t)1, arguments.size());
|
||||
EXPECT_TRUE(arguments[0]->IsInt());
|
||||
EXPECT_EQ(kVal1, arguments[0]->GetIntValue());
|
||||
|
||||
got_execute_.yes();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TrackCallback got_execute_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(Handler);
|
||||
};
|
||||
|
||||
// Enter the V8 context.
|
||||
EXPECT_TRUE(context->Enter());
|
||||
|
||||
Handler* resolveHandler = new Handler;
|
||||
Handler* rejectHandler = new Handler;
|
||||
|
||||
CefRefPtr<CefV8Handler> resolveHandlerPtr(resolveHandler);
|
||||
CefRefPtr<CefV8Handler> rejectHandlerPtr(rejectHandler);
|
||||
|
||||
CefRefPtr<CefV8Value> resolveFunc =
|
||||
CefV8Value::CreateFunction(kResolveName, resolveHandler);
|
||||
EXPECT_TRUE(resolveFunc.get());
|
||||
EXPECT_TRUE(context->GetGlobal()->SetValue(kResolveName, resolveFunc,
|
||||
V8_PROPERTY_ATTRIBUTE_NONE));
|
||||
|
||||
CefRefPtr<CefV8Value> rejectFunc =
|
||||
CefV8Value::CreateFunction(kRejectName, rejectHandler);
|
||||
EXPECT_TRUE(rejectFunc.get());
|
||||
EXPECT_TRUE(context->GetGlobal()->SetValue(kRejectName, rejectFunc,
|
||||
V8_PROPERTY_ATTRIBUTE_NONE));
|
||||
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreatePromise();
|
||||
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(context->GetGlobal()->SetValue(kPromiseName, value,
|
||||
V8_PROPERTY_ATTRIBUTE_NONE));
|
||||
|
||||
CefRefPtr<CefV8Value> retval;
|
||||
CefRefPtr<CefV8Exception> exception;
|
||||
|
||||
std::stringstream test;
|
||||
test << "window." << kPromiseName << ".then(" << kResolveName << ").catch("
|
||||
<< kRejectName << ")";
|
||||
|
||||
EXPECT_TRUE(context->Eval(test.str(), CefString(), 0, retval, exception));
|
||||
EXPECT_TRUE(retval.get());
|
||||
EXPECT_TRUE(retval->IsPromise());
|
||||
EXPECT_FALSE(exception.get());
|
||||
|
||||
CefRefPtr<CefV8Value> arg = CefV8Value::CreateInt(kVal1);
|
||||
EXPECT_TRUE(value->ResolvePromise(arg));
|
||||
|
||||
// Exit the V8 context.
|
||||
EXPECT_TRUE(context->Exit());
|
||||
|
||||
EXPECT_TRUE(resolveHandler->got_execute_);
|
||||
EXPECT_FALSE(rejectHandler->got_execute_);
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunPromiseRejectTest() {
|
||||
CefRefPtr<CefV8Context> context = GetContext();
|
||||
|
||||
// Enter the V8 context.
|
||||
EXPECT_TRUE(context->Enter());
|
||||
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreatePromise();
|
||||
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(value->RejectPromise("Error: Unknown"));
|
||||
|
||||
// Exit the V8 context.
|
||||
EXPECT_TRUE(context->Exit());
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunPromiseRejectHandlerTest() {
|
||||
CefRefPtr<CefV8Context> context = GetContext();
|
||||
|
||||
static const char* kPromiseName = "myprom";
|
||||
static const char* kResolveName = "myresolve";
|
||||
static const char* kRejectName = "myreject";
|
||||
|
||||
class Handler : public CefV8Handler {
|
||||
public:
|
||||
Handler() {}
|
||||
bool Execute(const CefString& name,
|
||||
CefRefPtr<CefV8Value> object,
|
||||
const CefV8ValueList& arguments,
|
||||
CefRefPtr<CefV8Value>& retval,
|
||||
CefString& exception) override {
|
||||
EXPECT_STREQ(kRejectName, name.ToString().c_str());
|
||||
EXPECT_EQ((size_t)1, arguments.size());
|
||||
EXPECT_TRUE(arguments[0]->IsObject());
|
||||
|
||||
got_execute_.yes();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TrackCallback got_execute_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(Handler);
|
||||
};
|
||||
|
||||
// Enter the V8 context.
|
||||
EXPECT_TRUE(context->Enter());
|
||||
|
||||
Handler* resolveHandler = new Handler;
|
||||
Handler* rejectHandler = new Handler;
|
||||
|
||||
CefRefPtr<CefV8Handler> resolveHandlerPtr(resolveHandler);
|
||||
CefRefPtr<CefV8Handler> rejectHandlerPtr(rejectHandler);
|
||||
|
||||
CefRefPtr<CefV8Value> resolveFunc =
|
||||
CefV8Value::CreateFunction(kResolveName, resolveHandler);
|
||||
EXPECT_TRUE(resolveFunc.get());
|
||||
EXPECT_TRUE(context->GetGlobal()->SetValue(kResolveName, resolveFunc,
|
||||
V8_PROPERTY_ATTRIBUTE_NONE));
|
||||
|
||||
CefRefPtr<CefV8Value> rejectFunc =
|
||||
CefV8Value::CreateFunction(kRejectName, rejectHandler);
|
||||
EXPECT_TRUE(rejectFunc.get());
|
||||
EXPECT_TRUE(context->GetGlobal()->SetValue(kRejectName, rejectFunc,
|
||||
V8_PROPERTY_ATTRIBUTE_NONE));
|
||||
|
||||
CefRefPtr<CefV8Value> value = CefV8Value::CreatePromise();
|
||||
|
||||
EXPECT_TRUE(value.get());
|
||||
EXPECT_TRUE(context->GetGlobal()->SetValue(kPromiseName, value,
|
||||
V8_PROPERTY_ATTRIBUTE_NONE));
|
||||
|
||||
CefRefPtr<CefV8Value> retval;
|
||||
CefRefPtr<CefV8Exception> exception;
|
||||
|
||||
std::stringstream test;
|
||||
test << "window." << kPromiseName << ".then(" << kResolveName << ").catch("
|
||||
<< kRejectName << ")";
|
||||
|
||||
EXPECT_TRUE(context->Eval(test.str(), CefString(), 0, retval, exception));
|
||||
EXPECT_TRUE(retval.get());
|
||||
EXPECT_TRUE(retval->IsPromise());
|
||||
EXPECT_FALSE(exception.get());
|
||||
|
||||
EXPECT_TRUE(value->RejectPromise("Error: Unknown"));
|
||||
|
||||
// Exit the V8 context.
|
||||
EXPECT_TRUE(context->Exit());
|
||||
|
||||
EXPECT_FALSE(resolveHandler->got_execute_);
|
||||
EXPECT_TRUE(rejectHandler->got_execute_);
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void RunContextEvalTest() {
|
||||
CefRefPtr<CefV8Context> context = GetContext();
|
||||
|
||||
|
@ -3055,6 +3332,12 @@ V8_TEST(FunctionHandlerFail, V8TEST_FUNCTION_HANDLER_FAIL)
|
|||
V8_TEST(FunctionHandlerNoObject, V8TEST_FUNCTION_HANDLER_NO_OBJECT)
|
||||
V8_TEST(FunctionHandlerWithContext, V8TEST_FUNCTION_HANDLER_WITH_CONTEXT)
|
||||
V8_TEST(FunctionHandlerEmptyString, V8TEST_FUNCTION_HANDLER_EMPTY_STRING)
|
||||
V8_TEST(PromiseCreate, V8TEST_PROMISE_CREATE)
|
||||
V8_TEST(PromiseResolve, V8TEST_PROMISE_RESOLVE)
|
||||
V8_TEST(PromiseResolveNoArgument, V8TEST_PROMISE_RESOLVE_NO_ARGUMENT)
|
||||
V8_TEST(PromiseResolveHandler, V8TEST_PROMISE_RESOLVE_HANDLER)
|
||||
V8_TEST(PromiseReject, V8TEST_PROMISE_REJECT)
|
||||
V8_TEST(PromiseRejectHandler, V8TEST_PROMISE_REJECT_HANDLER)
|
||||
V8_TEST(ContextEval, V8TEST_CONTEXT_EVAL)
|
||||
V8_TEST(ContextEvalException, V8TEST_CONTEXT_EVAL_EXCEPTION)
|
||||
V8_TEST_EX(ContextEvalCspBypassUnsafeEval,
|
||||
|
|
Loading…
Reference in New Issue