| Index: third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
|
| diff --git a/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp b/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
|
| index 9a3dabcbff7b81727e33907ca7147941bd8686e8..a1e9d5405b3878e428ac3bfb941fef4ca34a521b 100644
|
| --- a/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
|
| +++ b/third_party/WebKit/Source/web/SuspendableScriptExecutor.cpp
|
| @@ -6,6 +6,7 @@
|
|
|
| #include "bindings/core/v8/ScriptController.h"
|
| #include "bindings/core/v8/ScriptSourceCode.h"
|
| +#include "bindings/core/v8/V8PersistentValueVector.h"
|
| #include "core/dom/Document.h"
|
| #include "core/frame/LocalFrame.h"
|
| #include "platform/UserGestureIndicator.h"
|
| @@ -16,28 +17,118 @@
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +class WebScriptExecutor : public SuspendableScriptExecutor::Executor {
|
| +public:
|
| + WebScriptExecutor(const HeapVector<ScriptSourceCode>& sources, int worldID, int extensionGroup, bool userGesture);
|
| +
|
| + Vector<v8::Local<v8::Value>> execute(LocalFrame*) override;
|
| +
|
| + void trace(Visitor*) override;
|
| +
|
| +private:
|
| + HeapVector<ScriptSourceCode> m_sources;
|
| + int m_worldID;
|
| + int m_extensionGroup;
|
| + bool m_userGesture;
|
| +};
|
| +
|
| +WebScriptExecutor::WebScriptExecutor(const HeapVector<ScriptSourceCode>& sources, int worldID, int extensionGroup, bool userGesture)
|
| + : m_sources(sources)
|
| + , m_worldID(worldID)
|
| + , m_extensionGroup(extensionGroup)
|
| + , m_userGesture(userGesture)
|
| +{
|
| +}
|
| +
|
| +Vector<v8::Local<v8::Value>> WebScriptExecutor::execute(LocalFrame* frame)
|
| +{
|
| + std::unique_ptr<UserGestureIndicator> indicator;
|
| + if (m_userGesture)
|
| + indicator = wrapUnique(new UserGestureIndicator(DefinitelyProcessingNewUserGesture));
|
| +
|
| + Vector<v8::Local<v8::Value>> results;
|
| + if (m_worldID) {
|
| + frame->script().executeScriptInIsolatedWorld(m_worldID, m_sources, m_extensionGroup, &results);
|
| + } else {
|
| + v8::Local<v8::Value> scriptValue = frame->script().executeScriptInMainWorldAndReturnValue(m_sources.first());
|
| + results.append(scriptValue);
|
| + }
|
| +
|
| + return results;
|
| +}
|
| +
|
| +void WebScriptExecutor::trace(Visitor* visitor)
|
| +{
|
| + visitor->trace(m_sources);
|
| + SuspendableScriptExecutor::Executor::trace(visitor);
|
| +}
|
| +
|
| +class V8FunctionExecutor : public SuspendableScriptExecutor::Executor {
|
| +public:
|
| + V8FunctionExecutor(v8::Isolate*, v8::Local<v8::Function>, v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> argv[]);
|
| +
|
| + Vector<v8::Local<v8::Value>> execute(LocalFrame*) override;
|
| +
|
| +private:
|
| + ScopedPersistent<v8::Function> m_function;
|
| + ScopedPersistent<v8::Value> m_receiver;
|
| + V8PersistentValueVector<v8::Value> m_args;
|
| +};
|
| +
|
| +V8FunctionExecutor::V8FunctionExecutor(v8::Isolate* isolate, v8::Local<v8::Function> function, v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> argv[])
|
| + : m_function(isolate, function)
|
| + , m_receiver(isolate, receiver)
|
| + , m_args(isolate)
|
| +{
|
| + m_args.ReserveCapacity(argc);
|
| + for (int i = 0; i < argc; ++i)
|
| + m_args.Append(argv[i]);
|
| +}
|
| +
|
| +Vector<v8::Local<v8::Value>> V8FunctionExecutor::execute(LocalFrame* frame)
|
| +{
|
| + v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| + Vector<v8::Local<v8::Value>> results;
|
| + v8::Local<v8::Value> singleResult;
|
| + size_t numArgs = m_args.Size();
|
| + v8::Local<v8::Value> args[numArgs];
|
| + for (size_t i = 0; i < numArgs; ++i)
|
| + args[i] = m_args.Get(i);
|
| + if (V8ScriptRunner::callFunction(m_function.newLocal(isolate), frame->document(), m_receiver.newLocal(isolate), numArgs, static_cast<v8::Local<v8::Value>*>(args), toIsolate(frame)).ToLocal(&singleResult))
|
| + results.append(singleResult);
|
| + return results;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| void SuspendableScriptExecutor::createAndRun(LocalFrame* frame, int worldID, const HeapVector<ScriptSourceCode>& sources, int extensionGroup, bool userGesture, WebScriptExecutionCallback* callback)
|
| {
|
| - SuspendableScriptExecutor* executor = new SuspendableScriptExecutor(frame, worldID, sources, extensionGroup, userGesture, callback);
|
| + SuspendableScriptExecutor* executor = new SuspendableScriptExecutor(frame, callback, std::unique_ptr<WebScriptExecutor>(new WebScriptExecutor(sources, worldID, extensionGroup, userGesture)));
|
| + executor->run();
|
| +}
|
| +
|
| +void SuspendableScriptExecutor::createAndRun(LocalFrame* frame, v8::Isolate* isolate, v8::Local<v8::Function> function, v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> argv[], WebScriptExecutionCallback* callback)
|
| +{
|
| + SuspendableScriptExecutor* executor = new SuspendableScriptExecutor(frame, callback, std::unique_ptr<V8FunctionExecutor>(new V8FunctionExecutor(isolate, function, receiver, argc, argv)));
|
| executor->run();
|
| }
|
|
|
| void SuspendableScriptExecutor::contextDestroyed()
|
| {
|
| SuspendableTimer::contextDestroyed();
|
| - m_callback->completed(Vector<v8::Local<v8::Value>>());
|
| + if (m_callback)
|
| + m_callback->completed(Vector<v8::Local<v8::Value>>());
|
| dispose();
|
| }
|
|
|
| -SuspendableScriptExecutor::SuspendableScriptExecutor(LocalFrame* frame, int worldID, const HeapVector<ScriptSourceCode>& sources, int extensionGroup, bool userGesture, WebScriptExecutionCallback* callback)
|
| +SuspendableScriptExecutor::SuspendableScriptExecutor(LocalFrame* frame, WebScriptExecutionCallback* callback, std::unique_ptr<Executor> executor)
|
| : SuspendableTimer(frame->document())
|
| , m_frame(frame)
|
| - , m_sources(sources)
|
| , m_callback(callback)
|
| , m_keepAlive(this)
|
| - , m_worldID(worldID)
|
| - , m_extensionGroup(extensionGroup)
|
| - , m_userGesture(userGesture)
|
| + , m_executor(std::move(executor))
|
| {
|
| }
|
|
|
| @@ -65,27 +156,16 @@ void SuspendableScriptExecutor::run()
|
|
|
| void SuspendableScriptExecutor::executeAndDestroySelf()
|
| {
|
| - // after calling the destructor of object - object will be unsubscribed from
|
| - // resumed and contextDestroyed LifecycleObserver methods
|
| - std::unique_ptr<UserGestureIndicator> indicator;
|
| - if (m_userGesture)
|
| - indicator = wrapUnique(new UserGestureIndicator(DefinitelyProcessingNewUserGesture));
|
| -
|
| v8::HandleScope scope(v8::Isolate::GetCurrent());
|
| - Vector<v8::Local<v8::Value>> results;
|
| - if (m_worldID) {
|
| - m_frame->script().executeScriptInIsolatedWorld(m_worldID, m_sources, m_extensionGroup, &results);
|
| - } else {
|
| - v8::Local<v8::Value> scriptValue = m_frame->script().executeScriptInMainWorldAndReturnValue(m_sources.first());
|
| - results.append(scriptValue);
|
| - }
|
| + Vector<v8::Local<v8::Value>> results = m_executor->execute(m_frame);
|
|
|
| // The script may have removed the frame, in which case contextDestroyed()
|
| // will have handled the disposal/callback.
|
| if (!m_frame->client())
|
| return;
|
|
|
| - m_callback->completed(results);
|
| + if (m_callback)
|
| + m_callback->completed(results);
|
| dispose();
|
| }
|
|
|
| @@ -100,7 +180,6 @@ void SuspendableScriptExecutor::dispose()
|
| DEFINE_TRACE(SuspendableScriptExecutor)
|
| {
|
| visitor->trace(m_frame);
|
| - visitor->trace(m_sources);
|
| SuspendableTimer::trace(visitor);
|
| }
|
|
|
|
|