in libcef/renderer/v8_impl.cc [2360:2444]
CefRefPtr<CefV8Value> CefV8ValueImpl::ExecuteFunctionWithContext(
CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments) {
CEF_V8_REQUIRE_OBJECT_RETURN(nullptr);
v8::Isolate* isolate = handle_->isolate();
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Value> value = handle_->GetNewV8Handle(false);
if (!value->IsFunction()) {
NOTREACHED() << "V8 value is not a function";
return nullptr;
}
if (context.get() && !context->IsValid()) {
NOTREACHED() << "invalid V8 context parameter";
return nullptr;
}
if (object.get() && (!object->IsValid() || !object->IsObject())) {
NOTREACHED() << "invalid V8 object parameter";
return nullptr;
}
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 nullptr;
}
}
}
v8::Local<v8::Context> context_local;
if (context.get()) {
CefV8ContextImpl* context_impl =
static_cast<CefV8ContextImpl*>(context.get());
context_local = context_impl->GetV8Context();
} else {
context_local = isolate->GetCurrentContext();
}
v8::Context::Scope context_scope(context_local);
v8::Local<v8::Object> obj = value->ToObject(context_local).ToLocalChecked();
v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(obj);
v8::Local<v8::Object> recv;
// Default to the global object if no object was provided.
if (object.get()) {
CefV8ValueImpl* recv_impl = static_cast<CefV8ValueImpl*>(object.get());
recv = v8::Local<v8::Object>::Cast(recv_impl->GetV8Value(true));
} else {
recv = context_local->Global();
}
v8::Local<v8::Value>* argv = nullptr;
if (argc > 0) {
argv = new v8::Local<v8::Value>[argc];
for (int i = 0; i < argc; ++i) {
argv[i] =
static_cast<CefV8ValueImpl*>(arguments[i].get())->GetV8Value(true);
}
}
CefRefPtr<CefV8Value> retval;
{
v8::TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
v8::MaybeLocal<v8::Value> func_rv = blink_glue::CallV8Function(
context_local, func, recv, argc, argv, handle_->isolate());
if (!HasCaught(context_local, try_catch) && !func_rv.IsEmpty()) {
retval =
new CefV8ValueImpl(isolate, context_local, func_rv.ToLocalChecked());
}
}
if (argv)
delete[] argv;
return retval;
}