Merge branch 'master' into roller/chromium/master
This commit is contained in:
commit
5d13820441
28 changed files with 226 additions and 103 deletions
|
@ -41,6 +41,8 @@ namespace context_bridge {
|
|||
const char* const kProxyFunctionPrivateKey = "electron_contextBridge_proxy_fn";
|
||||
const char* const kSupportsDynamicPropertiesPrivateKey =
|
||||
"electron_contextBridge_supportsDynamicProperties";
|
||||
const char* const kOriginalFunctionPrivateKey =
|
||||
"electron_contextBridge_original_fn";
|
||||
|
||||
} // namespace context_bridge
|
||||
|
||||
|
@ -179,9 +181,26 @@ v8::MaybeLocal<v8::Value> PassValueToOtherContext(
|
|||
// the global handle at the right time.
|
||||
if (value->IsFunction()) {
|
||||
auto func = v8::Local<v8::Function>::Cast(value);
|
||||
v8::MaybeLocal<v8::Value> maybe_original_fn = GetPrivate(
|
||||
source_context, func, context_bridge::kOriginalFunctionPrivateKey);
|
||||
|
||||
{
|
||||
v8::Context::Scope destination_scope(destination_context);
|
||||
v8::Local<v8::Value> proxy_func;
|
||||
|
||||
// If this function has already been sent over the bridge,
|
||||
// then it is being sent _back_ over the bridge and we can
|
||||
// simply return the original method here for performance reasons
|
||||
|
||||
// For safety reasons we check if the destination context is the
|
||||
// creation context of the original method. If it's not we proceed
|
||||
// with the proxy logic
|
||||
if (maybe_original_fn.ToLocal(&proxy_func) && proxy_func->IsFunction() &&
|
||||
proxy_func.As<v8::Object>()->CreationContext() ==
|
||||
destination_context) {
|
||||
return v8::MaybeLocal<v8::Value>(proxy_func);
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> state =
|
||||
v8::Object::New(destination_context->GetIsolate());
|
||||
SetPrivate(destination_context, state,
|
||||
|
@ -190,10 +209,12 @@ v8::MaybeLocal<v8::Value> PassValueToOtherContext(
|
|||
context_bridge::kSupportsDynamicPropertiesPrivateKey,
|
||||
gin::ConvertToV8(destination_context->GetIsolate(),
|
||||
support_dynamic_properties));
|
||||
v8::Local<v8::Value> proxy_func;
|
||||
|
||||
if (!v8::Function::New(destination_context, ProxyFunctionWrapper, state)
|
||||
.ToLocal(&proxy_func))
|
||||
return v8::MaybeLocal<v8::Value>();
|
||||
SetPrivate(destination_context, proxy_func.As<v8::Object>(),
|
||||
context_bridge::kOriginalFunctionPrivateKey, func);
|
||||
object_cache->CacheProxiedObject(value, proxy_func);
|
||||
return v8::MaybeLocal<v8::Value>(proxy_func);
|
||||
}
|
||||
|
@ -408,21 +429,31 @@ void ProxyFunctionWrapper(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
|||
|
||||
v8::MaybeLocal<v8::Value> maybe_return_value;
|
||||
bool did_error = false;
|
||||
std::string error_message;
|
||||
v8::Local<v8::Value> error_message;
|
||||
{
|
||||
v8::TryCatch try_catch(args.isolate());
|
||||
maybe_return_value = func->Call(func_owning_context, func,
|
||||
proxied_args.size(), proxied_args.data());
|
||||
if (try_catch.HasCaught()) {
|
||||
did_error = true;
|
||||
auto message = try_catch.Message();
|
||||
v8::Local<v8::Value> exception = try_catch.Exception();
|
||||
|
||||
if (message.IsEmpty() ||
|
||||
!gin::ConvertFromV8(args.isolate(), message->Get(),
|
||||
&error_message)) {
|
||||
error_message =
|
||||
"An unknown exception occurred in the isolated context, an error "
|
||||
"occurred but a valid exception was not thrown.";
|
||||
const char* err_msg =
|
||||
"An unknown exception occurred in the isolated context, an error "
|
||||
"occurred but a valid exception was not thrown.";
|
||||
|
||||
if (!exception->IsNull() && exception->IsObject()) {
|
||||
v8::MaybeLocal<v8::Value> maybe_message =
|
||||
exception.As<v8::Object>()->Get(
|
||||
func_owning_context,
|
||||
gin::ConvertToV8(args.isolate(), "message"));
|
||||
|
||||
if (!maybe_message.ToLocal(&error_message) ||
|
||||
!error_message->IsString()) {
|
||||
error_message = gin::StringToV8(args.isolate(), err_msg);
|
||||
}
|
||||
} else {
|
||||
error_message = gin::StringToV8(args.isolate(), err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +461,7 @@ void ProxyFunctionWrapper(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
|||
if (did_error) {
|
||||
v8::Context::Scope calling_context_scope(calling_context);
|
||||
args.isolate()->ThrowException(
|
||||
v8::Exception::Error(gin::StringToV8(args.isolate(), error_message)));
|
||||
v8::Exception::Error(error_message.As<v8::String>()));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
|
|||
|
||||
void Completed(
|
||||
const blink::WebVector<v8::Local<v8::Value>>& result) override {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Isolate* isolate = promise_.isolate();
|
||||
if (!result.empty()) {
|
||||
if (!result[0].IsEmpty()) {
|
||||
v8::Local<v8::Value> value = result[0];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue