Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Unified Diff: third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp

Issue 2185233002: [DevTools] Added Runtime.awaitPromise protocol method (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: a Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
index 1f203b094f63583d6ef537fb1f0eac25169c334b..6eb6db0e025fd9fd9be1be34f61c6fc2d4da9dc9 100644
--- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
+++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
@@ -136,6 +136,152 @@ void V8RuntimeAgentImpl::evaluate(
exceptionDetails);
}
+namespace {
+
+class ProtocolPromiseHandler {
dgozman 2016/07/28 20:16:07 Let's move this to separate file.
kozy 2016/07/28 22:54:09 Rewritten.
+ PROTOCOL_DISALLOW_COPY(ProtocolPromiseHandler);
+public:
+ ProtocolPromiseHandler(V8DebuggerImpl* debugger, int contextGroupId, const String16& promiseObjectId, std::unique_ptr<V8RuntimeAgentImpl::PromiseThenCallback> callback, bool returnByValue, bool generatePreview)
dgozman 2016/07/28 20:16:07 protocol::Runtime::Backend::PromiseThenCallback
kozy 2016/07/28 22:54:09 Rewritten.
+ : m_debugger(debugger)
+ , m_contextGroupId(contextGroupId)
+ , m_promiseObjectId(promiseObjectId)
+ , m_callback(std::move(callback))
+ , m_returnByValue(returnByValue)
+ , m_generatePreview(generatePreview)
+ , m_wasCalled(false)
+ {
+ }
+
+ ~ProtocolPromiseHandler()
+ {
+ if (!m_wasCalled)
+ m_callback->sendFailure("Promise was collected");
+ }
+
+ void handleThen(v8::Local<v8::Value> value)
+ {
+ if (m_wasCalled)
+ return;
+ m_wasCalled = true;
+
+ std::unique_ptr<protocol::Runtime::RemoteObject> resolvedValue = wrapObject(value);
+ if (!resolvedValue)
+ return;
+ m_callback->sendSuccess(std::move(resolvedValue), Maybe<protocol::Runtime::RemoteObject>());
+ }
+
+ void handleCatch(v8::Local<v8::Value> value)
+ {
+ if (m_wasCalled)
+ return;
+ m_wasCalled = true;
+
+ std::unique_ptr<protocol::Runtime::RemoteObject> rejectedValue = wrapObject(value);
+ if (!rejectedValue)
+ return;
+ m_callback->sendSuccess(Maybe<protocol::Runtime::RemoteObject>(), std::move(rejectedValue));
+ }
+
+ void sendFailure(const ErrorString& errorString)
+ {
+ if (m_wasCalled)
+ return;
+
+ m_callback->sendFailure(errorString);
+ m_wasCalled = true;
+ }
+
+private:
+ std::unique_ptr<protocol::Runtime::RemoteObject> wrapObject(v8::Local<v8::Value> value)
+ {
+ ErrorString errorString;
+ InjectedScript::ObjectScope scope(&errorString, m_debugger, m_contextGroupId, m_promiseObjectId);
+ if (!scope.initialize()) {
+ m_callback->sendFailure(errorString);
+ return nullptr;
+ }
+ std::unique_ptr<protocol::Runtime::RemoteObject> wrappedValue = scope.injectedScript()->wrapObject(&errorString, value, scope.objectGroupName(), m_returnByValue, m_generatePreview);
+ if (!wrappedValue) {
+ m_callback->sendFailure(errorString);
+ return nullptr;
+ }
+ return wrappedValue;
+ }
+
+ V8DebuggerImpl* m_debugger;
+ int m_contextGroupId;
+ String16 m_promiseObjectId;
+ std::unique_ptr<V8RuntimeAgentImpl::PromiseThenCallback> m_callback;
+ bool m_returnByValue;
+ bool m_generatePreview;
+ bool m_wasCalled;
+};
+
+void thenCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ ProtocolPromiseHandler* handler = static_cast<ProtocolPromiseHandler*>(info.Data().As<v8::External>()->Value());
+ DCHECK(handler);
+ handler->handleThen(info.Length() > 0 ? info[0] : v8::Local<v8::Value>::Cast(v8::Undefined(info.GetIsolate())));
+}
+
+void catchCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ ProtocolPromiseHandler* handler = static_cast<ProtocolPromiseHandler*>(info.Data().As<v8::External>()->Value());
+ DCHECK(handler);
+ handler->handleCatch(info.Length() > 0 ? info[0] : v8::Local<v8::Value>::Cast(v8::Undefined(info.GetIsolate())));
+}
+
+template<typename T>
+void deletePointer(const v8::WeakCallbackInfo<std::pair<v8::Global<v8::External>, T*>>& data)
+{
+ data.GetParameter()->first.Reset();
+ delete data.GetParameter()->second;
+ delete data.GetParameter();
+}
+
+template<typename T>
+v8::Local<v8::External> makeExternal(v8::Isolate* isolate, T* pointer)
+{
+ v8::Local<v8::External> external = v8::External::New(isolate, pointer);
+ v8::Global<v8::External> externalGlobal(isolate, external);
+ std::pair<v8::Global<v8::External>, T*>* data = new std::pair<v8::Global<v8::External>, T*>(externalGlobal.Pass(), pointer);
+ data->first.SetWeak(data, deletePointer, v8::WeakCallbackType::kParameter);
+ return external;
+}
+
+} // namespace
+
+void V8RuntimeAgentImpl::promiseThen(ErrorString* errorString,
+ const String16& promiseObjectId,
+ const Maybe<bool>& returnByValue,
+ const Maybe<bool>& generatePreview,
+ std::unique_ptr<PromiseThenCallback> callback)
+{
+ InjectedScript::ObjectScope scope(errorString, m_debugger, m_session->contextGroupId(), promiseObjectId);
+ if (!scope.initialize())
+ return;
+ v8::Local<v8::Value> value = scope.object();
+ if (!value->IsPromise()) {
+ callback->sendFailure("Could not find promise with given id");
+ return;
+ }
+
+ v8::Local<v8::Promise> promise = value.As<v8::Promise>();
+ ProtocolPromiseHandler* handler = new ProtocolPromiseHandler(m_debugger, m_session->contextGroupId(), promiseObjectId, std::move(callback), returnByValue.fromMaybe(false), generatePreview.fromMaybe(false));
+ v8::Local<v8::External> wrappedCallback = makeExternal(m_debugger->isolate(), handler);
dgozman 2016/07/28 20:16:07 wrappedHandler
kozy 2016/07/28 22:54:09 Rewritten.
+
+ v8::Local<v8::Function> thenCallbackFunction = v8::Function::New(scope.context(), thenCallback, wrappedCallback, 0, v8::ConstructorBehavior::kThrow).ToLocalChecked();
+ if (promise->Then(scope.context(), thenCallbackFunction).IsEmpty()) {
+ handler->sendFailure("Internal error");
+ return;
+ }
+ v8::Local<v8::Function> catchCallbackFunction = v8::Function::New(scope.context(), catchCallback, wrappedCallback, 0, v8::ConstructorBehavior::kThrow).ToLocalChecked();
+ if (promise->Catch(scope.context(), catchCallbackFunction).IsEmpty()) {
+ handler->sendFailure("Internal error");
+ return;
+ }
+}
+
void V8RuntimeAgentImpl::callFunctionOn(ErrorString* errorString,
const String16& objectId,
const String16& expression,

Powered by Google App Engine
This is Rietveld 408576698