| 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..65cdc4e106e7188bffac7e4d55538fad40e6eb10 100644
|
| --- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
|
| +++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
|
| @@ -37,6 +37,7 @@
|
| #include "platform/v8_inspector/V8ConsoleMessage.h"
|
| #include "platform/v8_inspector/V8DebuggerImpl.h"
|
| #include "platform/v8_inspector/V8InspectorSessionImpl.h"
|
| +#include "platform/v8_inspector/V8StackTraceImpl.h"
|
| #include "platform/v8_inspector/V8StringUtil.h"
|
| #include "platform/v8_inspector/public/V8DebuggerClient.h"
|
|
|
| @@ -57,6 +58,119 @@ static bool hasInternalError(ErrorString* errorString, bool hasError)
|
| return hasError;
|
| }
|
|
|
| +namespace {
|
| +
|
| +class ProtocolPromiseHandler {
|
| +public:
|
| + static void add(V8DebuggerImpl* debugger, int contextGroupId, const String16& promiseObjectId, std::unique_ptr<protocol::Runtime::Backend::AwaitPromiseCallback> callback, bool returnByValue, bool generatePreview)
|
| + {
|
| + ErrorString errorString;
|
| + InjectedScript::ObjectScope scope(&errorString, debugger, contextGroupId, promiseObjectId);
|
| + if (!scope.initialize()) {
|
| + callback->sendFailure(errorString);
|
| + return;
|
| + }
|
| + if (!scope.object()->IsPromise()) {
|
| + callback->sendFailure("Could not find promise with given id");
|
| + return;
|
| + }
|
| +
|
| + protocol::Runtime::Backend::AwaitPromiseCallback* rawCallback = callback.get();
|
| + ProtocolPromiseHandler* handler = new ProtocolPromiseHandler(debugger, contextGroupId, promiseObjectId, std::move(callback), returnByValue, generatePreview);
|
| + v8::Local<v8::Value> wrapper = handler->m_wrapper.Get(debugger->isolate());
|
| + v8::Local<v8::Promise> promise = v8::Local<v8::Promise>::Cast(scope.object());
|
| +
|
| + v8::Local<v8::Function> thenCallbackFunction = v8::Function::New(scope.context(), thenCallback, wrapper, 0, v8::ConstructorBehavior::kThrow).ToLocalChecked();
|
| + if (promise->Then(scope.context(), thenCallbackFunction).IsEmpty()) {
|
| + rawCallback->sendFailure("Internal error");
|
| + return;
|
| + }
|
| + v8::Local<v8::Function> catchCallbackFunction = v8::Function::New(scope.context(), catchCallback, wrapper, 0, v8::ConstructorBehavior::kThrow).ToLocalChecked();
|
| + if (promise->Catch(scope.context(), catchCallbackFunction).IsEmpty()) {
|
| + rawCallback->sendFailure("Internal error");
|
| + return;
|
| + }
|
| + }
|
| +
|
| +private:
|
| + static void thenCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
|
| + {
|
| + ProtocolPromiseHandler* handler = static_cast<ProtocolPromiseHandler*>(info.Data().As<v8::External>()->Value());
|
| + DCHECK(handler);
|
| + v8::Local<v8::Value> value = info.Length() > 0 ? info[0] : v8::Local<v8::Value>::Cast(v8::Undefined(info.GetIsolate()));
|
| + handler->m_callback->sendSuccess(handler->wrapObject(value), Maybe<bool>(), Maybe<protocol::Runtime::ExceptionDetails>());
|
| + }
|
| +
|
| + static void catchCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
|
| + {
|
| + ProtocolPromiseHandler* handler = static_cast<ProtocolPromiseHandler*>(info.Data().As<v8::External>()->Value());
|
| + DCHECK(handler);
|
| + v8::Local<v8::Value> value = info.Length() > 0 ? info[0] : v8::Local<v8::Value>::Cast(v8::Undefined(info.GetIsolate()));
|
| +
|
| + std::unique_ptr<protocol::Runtime::ExceptionDetails> exceptionDetails;
|
| + std::unique_ptr<V8StackTraceImpl> stack = handler->m_debugger->captureStackTraceImpl(true);
|
| + if (stack) {
|
| + exceptionDetails = protocol::Runtime::ExceptionDetails::create()
|
| + .setText("Promise was rejected")
|
| + .setLineNumber(!stack->isEmpty() ? stack->topLineNumber() : 0)
|
| + .setColumnNumber(!stack->isEmpty() ? stack->topColumnNumber() : 0)
|
| + .setScriptId(!stack->isEmpty() ? stack->topScriptId() : String16())
|
| + .setStackTrace(stack->buildInspectorObjectImpl())
|
| + .build();
|
| + }
|
| + handler->m_callback->sendSuccess(handler->wrapObject(value), true, std::move(exceptionDetails));
|
| + }
|
| +
|
| + ProtocolPromiseHandler(V8DebuggerImpl* debugger, int contextGroupId, const String16& promiseObjectId, std::unique_ptr<V8RuntimeAgentImpl::AwaitPromiseCallback> callback, bool returnByValue, bool generatePreview)
|
| + : m_debugger(debugger)
|
| + , m_contextGroupId(contextGroupId)
|
| + , m_promiseObjectId(promiseObjectId)
|
| + , m_callback(std::move(callback))
|
| + , m_returnByValue(returnByValue)
|
| + , m_generatePreview(generatePreview)
|
| + , m_wrapper(debugger->isolate(), v8::External::New(debugger->isolate(), this))
|
| + {
|
| + m_wrapper.SetWeak(this, cleanup, v8::WeakCallbackType::kParameter);
|
| + }
|
| +
|
| + static void cleanup(const v8::WeakCallbackInfo<ProtocolPromiseHandler>& data)
|
| + {
|
| + if (!data.GetParameter()->m_wrapper.IsEmpty()) {
|
| + data.GetParameter()->m_wrapper.Reset();
|
| + data.SetSecondPassCallback(cleanup);
|
| + } else {
|
| + data.GetParameter()->m_callback->sendFailure("Promise was collected");
|
| + delete data.GetParameter();
|
| + }
|
| + }
|
| +
|
| + 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::AwaitPromiseCallback> m_callback;
|
| + bool m_returnByValue;
|
| + bool m_generatePreview;
|
| + v8::Global<v8::External> m_wrapper;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| V8RuntimeAgentImpl::V8RuntimeAgentImpl(V8InspectorSessionImpl* session, protocol::FrontendChannel* FrontendChannel, protocol::DictionaryValue* state)
|
| : m_session(session)
|
| , m_state(state)
|
| @@ -136,6 +250,15 @@ void V8RuntimeAgentImpl::evaluate(
|
| exceptionDetails);
|
| }
|
|
|
| +void V8RuntimeAgentImpl::awaitPromise(ErrorString* errorString,
|
| + const String16& promiseObjectId,
|
| + const Maybe<bool>& returnByValue,
|
| + const Maybe<bool>& generatePreview,
|
| + std::unique_ptr<AwaitPromiseCallback> callback)
|
| +{
|
| + ProtocolPromiseHandler::add(m_debugger, m_session->contextGroupId(), promiseObjectId, std::move(callback), returnByValue.fromMaybe(false), generatePreview.fromMaybe(false));
|
| +}
|
| +
|
| void V8RuntimeAgentImpl::callFunctionOn(ErrorString* errorString,
|
| const String16& objectId,
|
| const String16& expression,
|
|
|