Commit d7f82c11 authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

[inspector] migrate Runtime to new style

BUG=none
R=dgozman@chromium.org
CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_precise_blink_rel

Review-Url: https://codereview.chromium.org/2467853003
Cr-Commit-Position: refs/heads/master@{#40744}
parent 5df5a28f
...@@ -259,18 +259,6 @@ InjectedScript.prototype = { ...@@ -259,18 +259,6 @@ InjectedScript.prototype = {
} }
}, },
/**
* @param {!Array<*>} array
* @param {string} groupName
* @param {boolean} forceValueType
* @param {boolean} generatePreview
*/
wrapObjectsInArray: function(array, groupName, forceValueType, generatePreview)
{
for (var i = 0; i < array.length; ++i)
array[i] = this.wrapObject(array[i], groupName, forceValueType, generatePreview);
},
/** /**
* @param {!Object} table * @param {!Object} table
* @param {!Array.<string>|string|boolean} columns * @param {!Array.<string>|string|boolean} columns
......
...@@ -54,11 +54,6 @@ using protocol::Runtime::InternalPropertyDescriptor; ...@@ -54,11 +54,6 @@ using protocol::Runtime::InternalPropertyDescriptor;
using protocol::Runtime::RemoteObject; using protocol::Runtime::RemoteObject;
using protocol::Maybe; using protocol::Maybe;
static bool hasInternalError(ErrorString* errorString, bool hasError) {
if (hasError) *errorString = "Internal error";
return hasError;
}
std::unique_ptr<InjectedScript> InjectedScript::create( std::unique_ptr<InjectedScript> InjectedScript::create(
InspectedContext* inspectedContext) { InspectedContext* inspectedContext) {
v8::Isolate* isolate = inspectedContext->isolate(); v8::Isolate* isolate = inspectedContext->isolate();
...@@ -124,10 +119,9 @@ InjectedScript::InjectedScript( ...@@ -124,10 +119,9 @@ InjectedScript::InjectedScript(
InjectedScript::~InjectedScript() {} InjectedScript::~InjectedScript() {}
void InjectedScript::getProperties( Response InjectedScript::getProperties(
ErrorString* errorString, v8::Local<v8::Object> object, v8::Local<v8::Object> object, const String16& groupName, bool ownProperties,
const String16& groupName, bool ownProperties, bool accessorPropertiesOnly, bool accessorPropertiesOnly, bool generatePreview,
bool generatePreview,
std::unique_ptr<Array<PropertyDescriptor>>* properties, std::unique_ptr<Array<PropertyDescriptor>>* properties,
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
v8::HandleScope handles(m_context->isolate()); v8::HandleScope handles(m_context->isolate());
...@@ -143,21 +137,23 @@ void InjectedScript::getProperties( ...@@ -143,21 +137,23 @@ void InjectedScript::getProperties(
v8::TryCatch tryCatch(m_context->isolate()); v8::TryCatch tryCatch(m_context->isolate());
v8::Local<v8::Value> resultValue = function.callWithoutExceptionHandling(); v8::Local<v8::Value> resultValue = function.callWithoutExceptionHandling();
if (tryCatch.HasCaught()) { if (tryCatch.HasCaught()) {
*exceptionDetails = createExceptionDetails(errorString, tryCatch, groupName, Response response = createExceptionDetails(
generatePreview); tryCatch, groupName, generatePreview, exceptionDetails);
if (!response.isSuccess()) return response;
// FIXME: make properties optional // FIXME: make properties optional
*properties = Array<PropertyDescriptor>::create(); *properties = Array<PropertyDescriptor>::create();
return; return Response::OK();
} }
if (hasInternalError(errorString, resultValue.IsEmpty())) return; if (resultValue.IsEmpty()) return Response::InternalError();
std::unique_ptr<protocol::Value> protocolValue = std::unique_ptr<protocol::Value> protocolValue;
toProtocolValue(errorString, context, resultValue); Response response = toProtocolValue(context, resultValue, &protocolValue);
if (!protocolValue) return; if (!response.isSuccess()) return response;
protocol::ErrorSupport errors(errorString); protocol::ErrorSupport errors;
std::unique_ptr<Array<PropertyDescriptor>> result = std::unique_ptr<Array<PropertyDescriptor>> result =
Array<PropertyDescriptor>::parse(protocolValue.get(), &errors); Array<PropertyDescriptor>::parse(protocolValue.get(), &errors);
if (!hasInternalError(errorString, errors.hasErrors())) if (errors.hasErrors()) return Response::Error(errors.errors());
*properties = std::move(result); *properties = std::move(result);
return Response::OK();
} }
void InjectedScript::releaseObject(const String16& objectId) { void InjectedScript::releaseObject(const String16& objectId) {
...@@ -172,55 +168,52 @@ void InjectedScript::releaseObject(const String16& objectId) { ...@@ -172,55 +168,52 @@ void InjectedScript::releaseObject(const String16& objectId) {
m_native->unbind(boundId); m_native->unbind(boundId);
} }
std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapObject( Response InjectedScript::wrapObject(
ErrorString* errorString, v8::Local<v8::Value> value, v8::Local<v8::Value> value, const String16& groupName, bool forceValueType,
const String16& groupName, bool forceValueType, bool generatePreview,
bool generatePreview) const { std::unique_ptr<protocol::Runtime::RemoteObject>* result) const {
v8::HandleScope handles(m_context->isolate()); v8::HandleScope handles(m_context->isolate());
v8::Local<v8::Value> wrappedObject; v8::Local<v8::Value> wrappedObject;
v8::Local<v8::Context> context = m_context->context(); v8::Local<v8::Context> context = m_context->context();
if (!wrapValue(errorString, value, groupName, forceValueType, generatePreview) Response response = wrapValue(value, groupName, forceValueType,
.ToLocal(&wrappedObject)) generatePreview, &wrappedObject);
return nullptr; if (!response.isSuccess()) return response;
protocol::ErrorSupport errors; protocol::ErrorSupport errors;
std::unique_ptr<protocol::Value> protocolValue = std::unique_ptr<protocol::Value> protocolValue;
toProtocolValue(errorString, context, wrappedObject); response = toProtocolValue(context, wrappedObject, &protocolValue);
if (!protocolValue) return nullptr; if (!response.isSuccess()) return response;
std::unique_ptr<protocol::Runtime::RemoteObject> remoteObject =
*result =
protocol::Runtime::RemoteObject::parse(protocolValue.get(), &errors); protocol::Runtime::RemoteObject::parse(protocolValue.get(), &errors);
if (!remoteObject) *errorString = errors.errors(); if (!result->get()) return Response::Error(errors.errors());
return remoteObject; return Response::OK();
} }
bool InjectedScript::wrapObjectProperty(ErrorString* errorString, Response InjectedScript::wrapObjectProperty(v8::Local<v8::Object> object,
v8::Local<v8::Object> object, v8::Local<v8::Name> key,
v8::Local<v8::Name> key, const String16& groupName,
const String16& groupName, bool forceValueType,
bool forceValueType, bool generatePreview) const {
bool generatePreview) const {
v8::Local<v8::Value> property; v8::Local<v8::Value> property;
v8::Local<v8::Context> context = m_context->context(); v8::Local<v8::Context> context = m_context->context();
if (hasInternalError(errorString, if (!object->Get(context, key).ToLocal(&property))
!object->Get(context, key).ToLocal(&property))) return Response::InternalError();
return false;
v8::Local<v8::Value> wrappedProperty; v8::Local<v8::Value> wrappedProperty;
if (!wrapValue(errorString, property, groupName, forceValueType, Response response = wrapValue(property, groupName, forceValueType,
generatePreview) generatePreview, &wrappedProperty);
.ToLocal(&wrappedProperty)) if (!response.isSuccess()) return response;
return false;
v8::Maybe<bool> success = v8::Maybe<bool> success =
createDataProperty(context, object, key, wrappedProperty); createDataProperty(context, object, key, wrappedProperty);
if (hasInternalError(errorString, success.IsNothing() || !success.FromJust())) if (success.IsNothing() || !success.FromJust())
return false; return Response::InternalError();
return true; return Response::OK();
} }
bool InjectedScript::wrapPropertyInArray(ErrorString* errorString, Response InjectedScript::wrapPropertyInArray(v8::Local<v8::Array> array,
v8::Local<v8::Array> array, v8::Local<v8::String> property,
v8::Local<v8::String> property, const String16& groupName,
const String16& groupName, bool forceValueType,
bool forceValueType, bool generatePreview) const {
bool generatePreview) const {
V8FunctionCall function(m_context->inspector(), m_context->context(), V8FunctionCall function(m_context->inspector(), m_context->context(),
v8Value(), "wrapPropertyInArray"); v8Value(), "wrapPropertyInArray");
function.appendArgument(array); function.appendArgument(array);
...@@ -230,29 +223,13 @@ bool InjectedScript::wrapPropertyInArray(ErrorString* errorString, ...@@ -230,29 +223,13 @@ bool InjectedScript::wrapPropertyInArray(ErrorString* errorString,
function.appendArgument(generatePreview); function.appendArgument(generatePreview);
bool hadException = false; bool hadException = false;
function.call(hadException); function.call(hadException);
return !hasInternalError(errorString, hadException); return hadException ? Response::InternalError() : Response::OK();
} }
bool InjectedScript::wrapObjectsInArray(ErrorString* errorString, Response InjectedScript::wrapValue(v8::Local<v8::Value> value,
v8::Local<v8::Array> array, const String16& groupName,
const String16& groupName, bool forceValueType, bool generatePreview,
bool forceValueType, v8::Local<v8::Value>* result) const {
bool generatePreview) const {
V8FunctionCall function(m_context->inspector(), m_context->context(),
v8Value(), "wrapObjectsInArray");
function.appendArgument(array);
function.appendArgument(groupName);
function.appendArgument(forceValueType);
function.appendArgument(generatePreview);
bool hadException = false;
function.call(hadException);
return !hasInternalError(errorString, hadException);
}
v8::MaybeLocal<v8::Value> InjectedScript::wrapValue(
ErrorString* errorString, v8::Local<v8::Value> value,
const String16& groupName, bool forceValueType,
bool generatePreview) const {
V8FunctionCall function(m_context->inspector(), m_context->context(), V8FunctionCall function(m_context->inspector(), m_context->context(),
v8Value(), "wrapObject"); v8Value(), "wrapObject");
function.appendArgument(value); function.appendArgument(value);
...@@ -260,10 +237,9 @@ v8::MaybeLocal<v8::Value> InjectedScript::wrapValue( ...@@ -260,10 +237,9 @@ v8::MaybeLocal<v8::Value> InjectedScript::wrapValue(
function.appendArgument(forceValueType); function.appendArgument(forceValueType);
function.appendArgument(generatePreview); function.appendArgument(generatePreview);
bool hadException = false; bool hadException = false;
v8::Local<v8::Value> r = function.call(hadException); *result = function.call(hadException);
if (hasInternalError(errorString, hadException || r.IsEmpty())) if (hadException || result->IsEmpty()) return Response::InternalError();
return v8::MaybeLocal<v8::Value>(); return Response::OK();
return r;
} }
std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable(
...@@ -280,21 +256,19 @@ std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( ...@@ -280,21 +256,19 @@ std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable(
bool hadException = false; bool hadException = false;
v8::Local<v8::Value> r = function.call(hadException); v8::Local<v8::Value> r = function.call(hadException);
if (hadException || r.IsEmpty()) return nullptr; if (hadException || r.IsEmpty()) return nullptr;
protocol::ErrorString errorString; std::unique_ptr<protocol::Value> protocolValue;
std::unique_ptr<protocol::Value> protocolValue = Response response = toProtocolValue(context, r, &protocolValue);
toProtocolValue(&errorString, context, r); if (!response.isSuccess()) return nullptr;
if (!protocolValue) return nullptr;
protocol::ErrorSupport errors; protocol::ErrorSupport errors;
return protocol::Runtime::RemoteObject::parse(protocolValue.get(), &errors); return protocol::Runtime::RemoteObject::parse(protocolValue.get(), &errors);
} }
bool InjectedScript::findObject(ErrorString* errorString, Response InjectedScript::findObject(const RemoteObjectId& objectId,
const RemoteObjectId& objectId, v8::Local<v8::Value>* outObject) const {
v8::Local<v8::Value>* outObject) const {
*outObject = m_native->objectForId(objectId.id()); *outObject = m_native->objectForId(objectId.id());
if (outObject->IsEmpty()) if (outObject->IsEmpty())
*errorString = "Could not find object with given id"; return Response::Error("Could not find object with given id");
return !outObject->IsEmpty(); return Response::OK();
} }
String16 InjectedScript::objectGroupName(const RemoteObjectId& objectId) const { String16 InjectedScript::objectGroupName(const RemoteObjectId& objectId) const {
...@@ -326,47 +300,41 @@ v8::Local<v8::Value> InjectedScript::lastEvaluationResult() const { ...@@ -326,47 +300,41 @@ v8::Local<v8::Value> InjectedScript::lastEvaluationResult() const {
return m_lastEvaluationResult.Get(m_context->isolate()); return m_lastEvaluationResult.Get(m_context->isolate());
} }
v8::MaybeLocal<v8::Value> InjectedScript::resolveCallArgument( Response InjectedScript::resolveCallArgument(
ErrorString* errorString, protocol::Runtime::CallArgument* callArgument) { protocol::Runtime::CallArgument* callArgument,
v8::Local<v8::Value>* result) {
if (callArgument->hasObjectId()) { if (callArgument->hasObjectId()) {
std::unique_ptr<RemoteObjectId> remoteObjectId = std::unique_ptr<RemoteObjectId> remoteObjectId;
RemoteObjectId::parse(errorString, callArgument->getObjectId("")); Response response =
if (!remoteObjectId) return v8::MaybeLocal<v8::Value>(); RemoteObjectId::parse(callArgument->getObjectId(""), &remoteObjectId);
if (remoteObjectId->contextId() != m_context->contextId()) { if (!response.isSuccess()) return response;
*errorString = if (remoteObjectId->contextId() != m_context->contextId())
return Response::Error(
"Argument should belong to the same JavaScript world as target " "Argument should belong to the same JavaScript world as target "
"object"; "object");
return v8::MaybeLocal<v8::Value>(); return findObject(*remoteObjectId, result);
}
v8::Local<v8::Value> object;
if (!findObject(errorString, *remoteObjectId, &object))
return v8::MaybeLocal<v8::Value>();
return object;
} }
if (callArgument->hasValue() || callArgument->hasUnserializableValue()) { if (callArgument->hasValue() || callArgument->hasUnserializableValue()) {
String16 value = String16 value =
callArgument->hasValue() callArgument->hasValue()
? callArgument->getValue(nullptr)->toJSONString() ? callArgument->getValue(nullptr)->toJSONString()
: "Number(\"" + callArgument->getUnserializableValue("") + "\")"; : "Number(\"" + callArgument->getUnserializableValue("") + "\")";
v8::Local<v8::Value> object;
if (!m_context->inspector() if (!m_context->inspector()
->compileAndRunInternalScript( ->compileAndRunInternalScript(
m_context->context(), toV8String(m_context->isolate(), value)) m_context->context(), toV8String(m_context->isolate(), value))
.ToLocal(&object)) { .ToLocal(result)) {
*errorString = "Couldn't parse value object in call argument"; return Response::Error("Couldn't parse value object in call argument");
return v8::MaybeLocal<v8::Value>();
} }
return object; return Response::OK();
} }
return v8::Undefined(m_context->isolate()); *result = v8::Undefined(m_context->isolate());
return Response::OK();
} }
std::unique_ptr<protocol::Runtime::ExceptionDetails> Response InjectedScript::createExceptionDetails(
InjectedScript::createExceptionDetails(ErrorString* errorString, const v8::TryCatch& tryCatch, const String16& objectGroup,
const v8::TryCatch& tryCatch, bool generatePreview, Maybe<protocol::Runtime::ExceptionDetails>* result) {
const String16& objectGroup, if (!tryCatch.HasCaught()) return Response::InternalError();
bool generatePreview) {
if (!tryCatch.HasCaught()) return nullptr;
v8::Local<v8::Message> message = tryCatch.Message(); v8::Local<v8::Message> message = tryCatch.Message();
v8::Local<v8::Value> exception = tryCatch.Exception(); v8::Local<v8::Value> exception = tryCatch.Exception();
String16 messageText = String16 messageText =
...@@ -396,43 +364,44 @@ InjectedScript::createExceptionDetails(ErrorString* errorString, ...@@ -396,43 +364,44 @@ InjectedScript::createExceptionDetails(ErrorString* errorString,
->buildInspectorObjectImpl()); ->buildInspectorObjectImpl());
} }
if (!exception.IsEmpty()) { if (!exception.IsEmpty()) {
std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = wrapObject( std::unique_ptr<protocol::Runtime::RemoteObject> wrapped;
errorString, exception, objectGroup, false /* forceValueType */, Response response =
generatePreview && !exception->IsNativeError()); wrapObject(exception, objectGroup, false /* forceValueType */,
if (!wrapped) return nullptr; generatePreview && !exception->IsNativeError(), &wrapped);
if (!response.isSuccess()) return response;
exceptionDetails->setException(std::move(wrapped)); exceptionDetails->setException(std::move(wrapped));
} }
return exceptionDetails; *result = std::move(exceptionDetails);
return Response::OK();
} }
void InjectedScript::wrapEvaluateResult( Response InjectedScript::wrapEvaluateResult(
ErrorString* errorString, v8::MaybeLocal<v8::Value> maybeResultValue, v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch& tryCatch,
const v8::TryCatch& tryCatch, const String16& objectGroup, const String16& objectGroup, bool returnByValue, bool generatePreview,
bool returnByValue, bool generatePreview,
std::unique_ptr<protocol::Runtime::RemoteObject>* result, std::unique_ptr<protocol::Runtime::RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
v8::Local<v8::Value> resultValue; v8::Local<v8::Value> resultValue;
if (!tryCatch.HasCaught()) { if (!tryCatch.HasCaught()) {
if (hasInternalError(errorString, !maybeResultValue.ToLocal(&resultValue))) if (!maybeResultValue.ToLocal(&resultValue))
return; return Response::InternalError();
std::unique_ptr<RemoteObject> remoteObject = wrapObject( Response response = wrapObject(resultValue, objectGroup, returnByValue,
errorString, resultValue, objectGroup, returnByValue, generatePreview); generatePreview, result);
if (!remoteObject) return; if (!response.isSuccess()) return response;
if (objectGroup == "console") if (objectGroup == "console")
m_lastEvaluationResult.Reset(m_context->isolate(), resultValue); m_lastEvaluationResult.Reset(m_context->isolate(), resultValue);
*result = std::move(remoteObject);
} else { } else {
v8::Local<v8::Value> exception = tryCatch.Exception(); v8::Local<v8::Value> exception = tryCatch.Exception();
std::unique_ptr<RemoteObject> remoteObject = Response response =
wrapObject(errorString, exception, objectGroup, false, wrapObject(exception, objectGroup, false,
generatePreview && !exception->IsNativeError()); generatePreview && !exception->IsNativeError(), result);
if (!remoteObject) return; if (!response.isSuccess()) return response;
// We send exception in result for compatibility reasons, even though it's // We send exception in result for compatibility reasons, even though it's
// accessible through exceptionDetails.exception. // accessible through exceptionDetails.exception.
*result = std::move(remoteObject); response = createExceptionDetails(tryCatch, objectGroup, generatePreview,
*exceptionDetails = createExceptionDetails(errorString, tryCatch, exceptionDetails);
objectGroup, generatePreview); if (!response.isSuccess()) return response;
} }
return Response::OK();
} }
v8::Local<v8::Object> InjectedScript::commandLineAPI() { v8::Local<v8::Object> InjectedScript::commandLineAPI() {
...@@ -442,10 +411,8 @@ v8::Local<v8::Object> InjectedScript::commandLineAPI() { ...@@ -442,10 +411,8 @@ v8::Local<v8::Object> InjectedScript::commandLineAPI() {
return m_commandLineAPI.Get(m_context->isolate()); return m_commandLineAPI.Get(m_context->isolate());
} }
InjectedScript::Scope::Scope(ErrorString* errorString, InjectedScript::Scope::Scope(V8InspectorImpl* inspector, int contextGroupId)
V8InspectorImpl* inspector, int contextGroupId) : m_inspector(inspector),
: m_errorString(errorString),
m_inspector(inspector),
m_contextGroupId(contextGroupId), m_contextGroupId(contextGroupId),
m_injectedScript(nullptr), m_injectedScript(nullptr),
m_handleScope(inspector->isolate()), m_handleScope(inspector->isolate()),
...@@ -454,29 +421,25 @@ InjectedScript::Scope::Scope(ErrorString* errorString, ...@@ -454,29 +421,25 @@ InjectedScript::Scope::Scope(ErrorString* errorString,
m_previousPauseOnExceptionsState(v8::DebugInterface::NoBreakOnException), m_previousPauseOnExceptionsState(v8::DebugInterface::NoBreakOnException),
m_userGesture(false) {} m_userGesture(false) {}
bool InjectedScript::Scope::initialize() { Response InjectedScript::Scope::initialize() {
cleanup(); cleanup();
// TODO(dgozman): what if we reattach to the same context group during // TODO(dgozman): what if we reattach to the same context group during
// evaluate? Introduce a session id? // evaluate? Introduce a session id?
V8InspectorSessionImpl* session = V8InspectorSessionImpl* session =
m_inspector->sessionForContextGroup(m_contextGroupId); m_inspector->sessionForContextGroup(m_contextGroupId);
if (!session) { if (!session) return Response::InternalError();
*m_errorString = "Internal error"; Response response = findInjectedScript(session);
return false; if (!response.isSuccess()) return response;
}
findInjectedScript(session);
if (!m_injectedScript) return false;
m_context = m_injectedScript->context()->context(); m_context = m_injectedScript->context()->context();
m_context->Enter(); m_context->Enter();
return true; return Response::OK();
} }
bool InjectedScript::Scope::installCommandLineAPI() { void InjectedScript::Scope::installCommandLineAPI() {
DCHECK(m_injectedScript && !m_context.IsEmpty() && DCHECK(m_injectedScript && !m_context.IsEmpty() &&
!m_commandLineAPIScope.get()); !m_commandLineAPIScope.get());
m_commandLineAPIScope.reset(new V8Console::CommandLineAPIScope( m_commandLineAPIScope.reset(new V8Console::CommandLineAPIScope(
m_context, m_injectedScript->commandLineAPI(), m_context->Global())); m_context, m_injectedScript->commandLineAPI(), m_context->Global()));
return true;
} }
void InjectedScript::Scope::ignoreExceptionsAndMuteConsole() { void InjectedScript::Scope::ignoreExceptionsAndMuteConsole() {
...@@ -523,59 +486,57 @@ InjectedScript::Scope::~Scope() { ...@@ -523,59 +486,57 @@ InjectedScript::Scope::~Scope() {
cleanup(); cleanup();
} }
InjectedScript::ContextScope::ContextScope(ErrorString* errorString, InjectedScript::ContextScope::ContextScope(V8InspectorImpl* inspector,
V8InspectorImpl* inspector,
int contextGroupId, int contextGroupId,
int executionContextId) int executionContextId)
: InjectedScript::Scope(errorString, inspector, contextGroupId), : InjectedScript::Scope(inspector, contextGroupId),
m_executionContextId(executionContextId) {} m_executionContextId(executionContextId) {}
InjectedScript::ContextScope::~ContextScope() {} InjectedScript::ContextScope::~ContextScope() {}
void InjectedScript::ContextScope::findInjectedScript( Response InjectedScript::ContextScope::findInjectedScript(
V8InspectorSessionImpl* session) { V8InspectorSessionImpl* session) {
m_injectedScript = return session->findInjectedScript(m_executionContextId, m_injectedScript);
session->findInjectedScript(m_errorString, m_executionContextId);
} }
InjectedScript::ObjectScope::ObjectScope(ErrorString* errorString, InjectedScript::ObjectScope::ObjectScope(V8InspectorImpl* inspector,
V8InspectorImpl* inspector,
int contextGroupId, int contextGroupId,
const String16& remoteObjectId) const String16& remoteObjectId)
: InjectedScript::Scope(errorString, inspector, contextGroupId), : InjectedScript::Scope(inspector, contextGroupId),
m_remoteObjectId(remoteObjectId) {} m_remoteObjectId(remoteObjectId) {}
InjectedScript::ObjectScope::~ObjectScope() {} InjectedScript::ObjectScope::~ObjectScope() {}
void InjectedScript::ObjectScope::findInjectedScript( Response InjectedScript::ObjectScope::findInjectedScript(
V8InspectorSessionImpl* session) { V8InspectorSessionImpl* session) {
std::unique_ptr<RemoteObjectId> remoteId = std::unique_ptr<RemoteObjectId> remoteId;
RemoteObjectId::parse(m_errorString, m_remoteObjectId); Response response = RemoteObjectId::parse(m_remoteObjectId, &remoteId);
if (!remoteId) return; if (!response.isSuccess()) return response;
InjectedScript* injectedScript = InjectedScript* injectedScript = nullptr;
session->findInjectedScript(m_errorString, remoteId.get()); response = session->findInjectedScript(remoteId.get(), injectedScript);
if (!injectedScript) return; if (!response.isSuccess()) return response;
m_objectGroupName = injectedScript->objectGroupName(*remoteId); m_objectGroupName = injectedScript->objectGroupName(*remoteId);
if (!injectedScript->findObject(m_errorString, *remoteId, &m_object)) return; response = injectedScript->findObject(*remoteId, &m_object);
if (!response.isSuccess()) return response;
m_injectedScript = injectedScript; m_injectedScript = injectedScript;
return Response::OK();
} }
InjectedScript::CallFrameScope::CallFrameScope(ErrorString* errorString, InjectedScript::CallFrameScope::CallFrameScope(V8InspectorImpl* inspector,
V8InspectorImpl* inspector,
int contextGroupId, int contextGroupId,
const String16& remoteObjectId) const String16& remoteObjectId)
: InjectedScript::Scope(errorString, inspector, contextGroupId), : InjectedScript::Scope(inspector, contextGroupId),
m_remoteCallFrameId(remoteObjectId) {} m_remoteCallFrameId(remoteObjectId) {}
InjectedScript::CallFrameScope::~CallFrameScope() {} InjectedScript::CallFrameScope::~CallFrameScope() {}
void InjectedScript::CallFrameScope::findInjectedScript( Response InjectedScript::CallFrameScope::findInjectedScript(
V8InspectorSessionImpl* session) { V8InspectorSessionImpl* session) {
std::unique_ptr<RemoteCallFrameId> remoteId = std::unique_ptr<RemoteCallFrameId> remoteId;
RemoteCallFrameId::parse(m_errorString, m_remoteCallFrameId); Response response = RemoteCallFrameId::parse(m_remoteCallFrameId, &remoteId);
if (!remoteId) return; if (!response.isSuccess()) return response;
m_frameOrdinal = static_cast<size_t>(remoteId->frameOrdinal()); m_frameOrdinal = static_cast<size_t>(remoteId->frameOrdinal());
m_injectedScript = session->findInjectedScript(m_errorString, remoteId.get()); return session->findInjectedScript(remoteId.get(), m_injectedScript);
} }
} // namespace v8_inspector } // namespace v8_inspector
...@@ -48,8 +48,8 @@ class V8FunctionCall; ...@@ -48,8 +48,8 @@ class V8FunctionCall;
class V8InspectorImpl; class V8InspectorImpl;
class V8InspectorSessionImpl; class V8InspectorSessionImpl;
using protocol::ErrorString;
using protocol::Maybe; using protocol::Maybe;
using protocol::Response;
class InjectedScript final { class InjectedScript final {
public: public:
...@@ -58,56 +58,51 @@ class InjectedScript final { ...@@ -58,56 +58,51 @@ class InjectedScript final {
InspectedContext* context() const { return m_context; } InspectedContext* context() const { return m_context; }
void getProperties( Response getProperties(
ErrorString*, v8::Local<v8::Object>, const String16& groupName, v8::Local<v8::Object>, const String16& groupName, bool ownProperties,
bool ownProperties, bool accessorPropertiesOnly, bool generatePreview, bool accessorPropertiesOnly, bool generatePreview,
std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>* std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>*
result, result,
Maybe<protocol::Runtime::ExceptionDetails>*); Maybe<protocol::Runtime::ExceptionDetails>*);
void releaseObject(const String16& objectId); void releaseObject(const String16& objectId);
std::unique_ptr<protocol::Runtime::RemoteObject> wrapObject( Response wrapObject(
ErrorString*, v8::Local<v8::Value>, const String16& groupName, v8::Local<v8::Value>, const String16& groupName, bool forceValueType,
bool forceValueType = false, bool generatePreview = false) const; bool generatePreview,
bool wrapObjectProperty(ErrorString*, v8::Local<v8::Object>, std::unique_ptr<protocol::Runtime::RemoteObject>* result) const;
v8::Local<v8::Name> key, const String16& groupName, Response wrapObjectProperty(v8::Local<v8::Object>, v8::Local<v8::Name> key,
bool forceValueType = false, const String16& groupName,
bool generatePreview = false) const; bool forceValueType = false,
bool wrapPropertyInArray(ErrorString*, v8::Local<v8::Array>, bool generatePreview = false) const;
v8::Local<v8::String> property, Response wrapPropertyInArray(v8::Local<v8::Array>,
const String16& groupName, v8::Local<v8::String> property,
bool forceValueType = false, const String16& groupName,
bool generatePreview = false) const; bool forceValueType = false,
bool wrapObjectsInArray(ErrorString*, v8::Local<v8::Array>, bool generatePreview = false) const;
const String16& groupName,
bool forceValueType = false,
bool generatePreview = false) const;
std::unique_ptr<protocol::Runtime::RemoteObject> wrapTable( std::unique_ptr<protocol::Runtime::RemoteObject> wrapTable(
v8::Local<v8::Value> table, v8::Local<v8::Value> columns) const; v8::Local<v8::Value> table, v8::Local<v8::Value> columns) const;
bool findObject(ErrorString*, const RemoteObjectId&, Response findObject(const RemoteObjectId&, v8::Local<v8::Value>*) const;
v8::Local<v8::Value>*) const;
String16 objectGroupName(const RemoteObjectId&) const; String16 objectGroupName(const RemoteObjectId&) const;
void releaseObjectGroup(const String16&); void releaseObjectGroup(const String16&);
void setCustomObjectFormatterEnabled(bool); void setCustomObjectFormatterEnabled(bool);
v8::MaybeLocal<v8::Value> resolveCallArgument( Response resolveCallArgument(protocol::Runtime::CallArgument*,
ErrorString*, protocol::Runtime::CallArgument*); v8::Local<v8::Value>* result);
std::unique_ptr<protocol::Runtime::ExceptionDetails> createExceptionDetails( Response createExceptionDetails(
ErrorString*, const v8::TryCatch&, const String16& groupName, const v8::TryCatch&, const String16& groupName, bool generatePreview,
bool generatePreview); Maybe<protocol::Runtime::ExceptionDetails>* result);
void wrapEvaluateResult( Response wrapEvaluateResult(
ErrorString*, v8::MaybeLocal<v8::Value> maybeResultValue, v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch&,
const v8::TryCatch&, const String16& objectGroup, bool returnByValue, const String16& objectGroup, bool returnByValue, bool generatePreview,
bool generatePreview,
std::unique_ptr<protocol::Runtime::RemoteObject>* result, std::unique_ptr<protocol::Runtime::RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>*); Maybe<protocol::Runtime::ExceptionDetails>*);
v8::Local<v8::Value> lastEvaluationResult() const; v8::Local<v8::Value> lastEvaluationResult() const;
class Scope { class Scope {
public: public:
bool initialize(); Response initialize();
bool installCommandLineAPI(); void installCommandLineAPI();
void ignoreExceptionsAndMuteConsole(); void ignoreExceptionsAndMuteConsole();
void pretendUserGesture(); void pretendUserGesture();
v8::Local<v8::Context> context() const { return m_context; } v8::Local<v8::Context> context() const { return m_context; }
...@@ -115,11 +110,10 @@ class InjectedScript final { ...@@ -115,11 +110,10 @@ class InjectedScript final {
const v8::TryCatch& tryCatch() const { return m_tryCatch; } const v8::TryCatch& tryCatch() const { return m_tryCatch; }
protected: protected:
Scope(ErrorString*, V8InspectorImpl*, int contextGroupId); Scope(V8InspectorImpl*, int contextGroupId);
virtual ~Scope(); virtual ~Scope();
virtual void findInjectedScript(V8InspectorSessionImpl*) = 0; virtual Response findInjectedScript(V8InspectorSessionImpl*) = 0;
ErrorString* m_errorString;
V8InspectorImpl* m_inspector; V8InspectorImpl* m_inspector;
int m_contextGroupId; int m_contextGroupId;
InjectedScript* m_injectedScript; InjectedScript* m_injectedScript;
...@@ -140,12 +134,11 @@ class InjectedScript final { ...@@ -140,12 +134,11 @@ class InjectedScript final {
class ContextScope : public Scope { class ContextScope : public Scope {
public: public:
ContextScope(ErrorString*, V8InspectorImpl*, int contextGroupId, ContextScope(V8InspectorImpl*, int contextGroupId, int executionContextId);
int executionContextId);
~ContextScope(); ~ContextScope();
private: private:
void findInjectedScript(V8InspectorSessionImpl*) override; Response findInjectedScript(V8InspectorSessionImpl*) override;
int m_executionContextId; int m_executionContextId;
DISALLOW_COPY_AND_ASSIGN(ContextScope); DISALLOW_COPY_AND_ASSIGN(ContextScope);
...@@ -153,14 +146,14 @@ class InjectedScript final { ...@@ -153,14 +146,14 @@ class InjectedScript final {
class ObjectScope : public Scope { class ObjectScope : public Scope {
public: public:
ObjectScope(ErrorString*, V8InspectorImpl*, int contextGroupId, ObjectScope(V8InspectorImpl*, int contextGroupId,
const String16& remoteObjectId); const String16& remoteObjectId);
~ObjectScope(); ~ObjectScope();
const String16& objectGroupName() const { return m_objectGroupName; } const String16& objectGroupName() const { return m_objectGroupName; }
v8::Local<v8::Value> object() const { return m_object; } v8::Local<v8::Value> object() const { return m_object; }
private: private:
void findInjectedScript(V8InspectorSessionImpl*) override; Response findInjectedScript(V8InspectorSessionImpl*) override;
String16 m_remoteObjectId; String16 m_remoteObjectId;
String16 m_objectGroupName; String16 m_objectGroupName;
v8::Local<v8::Value> m_object; v8::Local<v8::Value> m_object;
...@@ -170,13 +163,13 @@ class InjectedScript final { ...@@ -170,13 +163,13 @@ class InjectedScript final {
class CallFrameScope : public Scope { class CallFrameScope : public Scope {
public: public:
CallFrameScope(ErrorString*, V8InspectorImpl*, int contextGroupId, CallFrameScope(V8InspectorImpl*, int contextGroupId,
const String16& remoteCallFrameId); const String16& remoteCallFrameId);
~CallFrameScope(); ~CallFrameScope();
size_t frameOrdinal() const { return m_frameOrdinal; } size_t frameOrdinal() const { return m_frameOrdinal; }
private: private:
void findInjectedScript(V8InspectorSessionImpl*) override; Response findInjectedScript(V8InspectorSessionImpl*) override;
String16 m_remoteCallFrameId; String16 m_remoteCallFrameId;
size_t m_frameOrdinal; size_t m_frameOrdinal;
...@@ -187,10 +180,9 @@ class InjectedScript final { ...@@ -187,10 +180,9 @@ class InjectedScript final {
InjectedScript(InspectedContext*, v8::Local<v8::Object>, InjectedScript(InspectedContext*, v8::Local<v8::Object>,
std::unique_ptr<InjectedScriptNative>); std::unique_ptr<InjectedScriptNative>);
v8::Local<v8::Value> v8Value() const; v8::Local<v8::Value> v8Value() const;
v8::MaybeLocal<v8::Value> wrapValue(ErrorString*, v8::Local<v8::Value>, Response wrapValue(v8::Local<v8::Value>, const String16& groupName,
const String16& groupName, bool forceValueType, bool generatePreview,
bool forceValueType, v8::Local<v8::Value>* result) const;
bool generatePreview) const;
v8::Local<v8::Object> commandLineAPI(); v8::Local<v8::Object> commandLineAPI();
InspectedContext* m_context; InspectedContext* m_context;
......
...@@ -27,44 +27,34 @@ RemoteObjectIdBase::parseInjectedScriptId(const String16& objectId) { ...@@ -27,44 +27,34 @@ RemoteObjectIdBase::parseInjectedScriptId(const String16& objectId) {
RemoteObjectId::RemoteObjectId() : RemoteObjectIdBase(), m_id(0) {} RemoteObjectId::RemoteObjectId() : RemoteObjectIdBase(), m_id(0) {}
std::unique_ptr<RemoteObjectId> RemoteObjectId::parse( Response RemoteObjectId::parse(const String16& objectId,
ErrorString* errorString, const String16& objectId) { std::unique_ptr<RemoteObjectId>* result) {
std::unique_ptr<RemoteObjectId> result(new RemoteObjectId()); std::unique_ptr<RemoteObjectId> remoteObjectId(new RemoteObjectId());
std::unique_ptr<protocol::DictionaryValue> parsedObjectId = std::unique_ptr<protocol::DictionaryValue> parsedObjectId =
result->parseInjectedScriptId(objectId); remoteObjectId->parseInjectedScriptId(objectId);
if (!parsedObjectId) { if (!parsedObjectId) return Response::Error("Invalid remote object id");
*errorString = "Invalid remote object id";
return nullptr;
}
bool success = parsedObjectId->getInteger("id", &result->m_id); bool success = parsedObjectId->getInteger("id", &remoteObjectId->m_id);
if (!success) { if (!success) return Response::Error("Invalid remote object id");
*errorString = "Invalid remote object id"; *result = std::move(remoteObjectId);
return nullptr; return Response::OK();
}
return result;
} }
RemoteCallFrameId::RemoteCallFrameId() RemoteCallFrameId::RemoteCallFrameId()
: RemoteObjectIdBase(), m_frameOrdinal(0) {} : RemoteObjectIdBase(), m_frameOrdinal(0) {}
std::unique_ptr<RemoteCallFrameId> RemoteCallFrameId::parse( Response RemoteCallFrameId::parse(const String16& objectId,
ErrorString* errorString, const String16& objectId) { std::unique_ptr<RemoteCallFrameId>* result) {
std::unique_ptr<RemoteCallFrameId> result(new RemoteCallFrameId()); std::unique_ptr<RemoteCallFrameId> remoteCallFrameId(new RemoteCallFrameId());
std::unique_ptr<protocol::DictionaryValue> parsedObjectId = std::unique_ptr<protocol::DictionaryValue> parsedObjectId =
result->parseInjectedScriptId(objectId); remoteCallFrameId->parseInjectedScriptId(objectId);
if (!parsedObjectId) { if (!parsedObjectId) return Response::Error("Invalid call frame id");
*errorString = "Invalid call frame id";
return nullptr;
}
bool success = parsedObjectId->getInteger("ordinal", &result->m_frameOrdinal); bool success =
if (!success) { parsedObjectId->getInteger("ordinal", &remoteCallFrameId->m_frameOrdinal);
*errorString = "Invalid call frame id"; if (!success) return Response::Error("Invalid call frame id");
return nullptr; *result = std::move(remoteCallFrameId);
} return Response::OK();
return result;
} }
String16 RemoteCallFrameId::serialize(int injectedScriptId, int frameOrdinal) { String16 RemoteCallFrameId::serialize(int injectedScriptId, int frameOrdinal) {
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
namespace v8_inspector { namespace v8_inspector {
using protocol::ErrorString; using protocol::Response;
class RemoteObjectIdBase { class RemoteObjectIdBase {
public: public:
...@@ -27,7 +27,7 @@ class RemoteObjectIdBase { ...@@ -27,7 +27,7 @@ class RemoteObjectIdBase {
class RemoteObjectId final : public RemoteObjectIdBase { class RemoteObjectId final : public RemoteObjectIdBase {
public: public:
static std::unique_ptr<RemoteObjectId> parse(ErrorString*, const String16&); static Response parse(const String16&, std::unique_ptr<RemoteObjectId>*);
~RemoteObjectId() {} ~RemoteObjectId() {}
int id() const { return m_id; } int id() const { return m_id; }
...@@ -39,8 +39,7 @@ class RemoteObjectId final : public RemoteObjectIdBase { ...@@ -39,8 +39,7 @@ class RemoteObjectId final : public RemoteObjectIdBase {
class RemoteCallFrameId final : public RemoteObjectIdBase { class RemoteCallFrameId final : public RemoteObjectIdBase {
public: public:
static std::unique_ptr<RemoteCallFrameId> parse(ErrorString*, static Response parse(const String16&, std::unique_ptr<RemoteCallFrameId>*);
const String16&);
~RemoteCallFrameId() {} ~RemoteCallFrameId() {}
int frameOrdinal() const { return m_frameOrdinal; } int frameOrdinal() const { return m_frameOrdinal; }
......
...@@ -111,94 +111,6 @@ std::unique_ptr<protocol::Value> parseJSON(const String16& string) { ...@@ -111,94 +111,6 @@ std::unique_ptr<protocol::Value> parseJSON(const String16& string) {
} // namespace protocol } // namespace protocol
std::unique_ptr<protocol::Value> toProtocolValue(protocol::String* errorString,
v8::Local<v8::Context> context,
v8::Local<v8::Value> value,
int maxDepth) {
if (value.IsEmpty()) {
UNREACHABLE();
return nullptr;
}
if (!maxDepth) {
*errorString = "Object reference chain is too long";
return nullptr;
}
maxDepth--;
if (value->IsNull() || value->IsUndefined()) return protocol::Value::null();
if (value->IsBoolean())
return protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
if (value->IsNumber()) {
double doubleValue = value.As<v8::Number>()->Value();
int intValue = static_cast<int>(doubleValue);
if (intValue == doubleValue)
return protocol::FundamentalValue::create(intValue);
return protocol::FundamentalValue::create(doubleValue);
}
if (value->IsString())
return protocol::StringValue::create(
toProtocolString(value.As<v8::String>()));
if (value->IsArray()) {
v8::Local<v8::Array> array = value.As<v8::Array>();
std::unique_ptr<protocol::ListValue> inspectorArray =
protocol::ListValue::create();
uint32_t length = array->Length();
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> value;
if (!array->Get(context, i).ToLocal(&value)) {
*errorString = "Internal error";
return nullptr;
}
std::unique_ptr<protocol::Value> element =
toProtocolValue(errorString, context, value, maxDepth);
if (!element) return nullptr;
inspectorArray->pushValue(std::move(element));
}
return std::move(inspectorArray);
}
if (value->IsObject()) {
std::unique_ptr<protocol::DictionaryValue> jsonObject =
protocol::DictionaryValue::create();
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
v8::Local<v8::Array> propertyNames;
if (!object->GetPropertyNames(context).ToLocal(&propertyNames)) {
*errorString = "Internal error";
return nullptr;
}
uint32_t length = propertyNames->Length();
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> name;
if (!propertyNames->Get(context, i).ToLocal(&name)) {
*errorString = "Internal error";
return nullptr;
}
// FIXME(yurys): v8::Object should support GetOwnPropertyNames
if (name->IsString()) {
v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty(
context, v8::Local<v8::String>::Cast(name));
if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.FromJust())
continue;
}
v8::Local<v8::String> propertyName;
if (!name->ToString(context).ToLocal(&propertyName)) continue;
v8::Local<v8::Value> property;
if (!object->Get(context, name).ToLocal(&property)) {
*errorString = "Internal error";
return nullptr;
}
std::unique_ptr<protocol::Value> propertyValue =
toProtocolValue(errorString, context, property, maxDepth);
if (!propertyValue) return nullptr;
jsonObject->setValue(toProtocolString(propertyName),
std::move(propertyValue));
}
return std::move(jsonObject);
}
*errorString = "Object couldn't be returned by value";
return nullptr;
}
// static // static
std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string) { std::unique_ptr<StringBuffer> StringBuffer::create(const StringView& string) {
String16 owner = toString16(string); String16 owner = toString16(string);
......
...@@ -40,11 +40,6 @@ std::unique_ptr<protocol::Value> parseJSON(const String16& json); ...@@ -40,11 +40,6 @@ std::unique_ptr<protocol::Value> parseJSON(const String16& json);
} // namespace protocol } // namespace protocol
std::unique_ptr<protocol::Value> toProtocolValue(protocol::String* errorString,
v8::Local<v8::Context>,
v8::Local<v8::Value>,
int maxDepth = 1000);
v8::Local<v8::String> toV8String(v8::Isolate*, const String16&); v8::Local<v8::String> toV8String(v8::Isolate*, const String16&);
v8::Local<v8::String> toV8StringInternalized(v8::Isolate*, const String16&); v8::Local<v8::String> toV8StringInternalized(v8::Isolate*, const String16&);
v8::Local<v8::String> toV8StringInternalized(v8::Isolate*, const char*); v8::Local<v8::String> toV8StringInternalized(v8::Isolate*, const char*);
......
...@@ -618,12 +618,11 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info, ...@@ -618,12 +618,11 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
if (!context) return; if (!context) return;
InjectedScript* injectedScript = context->getInjectedScript(); InjectedScript* injectedScript = context->getInjectedScript();
if (!injectedScript) return; if (!injectedScript) return;
ErrorString errorString; std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject;
std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject = protocol::Response response =
injectedScript->wrapObject(&errorString, info[0], "", injectedScript->wrapObject(info[0], "", false /** forceValueType */,
false /** forceValueType */, false /** generatePreview */, &wrappedObject);
false /** generatePreview */); if (!response.isSuccess()) return;
if (!wrappedObject || !errorString.isEmpty()) return;
std::unique_ptr<protocol::DictionaryValue> hints = std::unique_ptr<protocol::DictionaryValue> hints =
protocol::DictionaryValue::create(); protocol::DictionaryValue::create();
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "src/inspector/v8-regex.h" #include "src/inspector/v8-regex.h"
#include "src/inspector/v8-runtime-agent-impl.h" #include "src/inspector/v8-runtime-agent-impl.h"
#include "src/inspector/v8-stack-trace-impl.h" #include "src/inspector/v8-stack-trace-impl.h"
#include "src/inspector/v8-value-copier.h"
#include "include/v8-inspector.h" #include "include/v8-inspector.h"
...@@ -560,9 +561,13 @@ void V8DebuggerAgentImpl::restartFrame( ...@@ -560,9 +561,13 @@ void V8DebuggerAgentImpl::restartFrame(
std::unique_ptr<Array<CallFrame>>* newCallFrames, std::unique_ptr<Array<CallFrame>>* newCallFrames,
Maybe<StackTrace>* asyncStackTrace) { Maybe<StackTrace>* asyncStackTrace) {
if (!assertPaused(errorString)) return; if (!assertPaused(errorString)) return;
InjectedScript::CallFrameScope scope( InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
errorString, m_inspector, m_session->contextGroupId(), callFrameId); callFrameId);
if (!scope.initialize()) return; Response response = scope.initialize();
if (!response.isSuccess()) {
*errorString = response.errorMessage();
return;
}
if (scope.frameOrdinal() >= m_pausedCallFrames.size()) { if (scope.frameOrdinal() >= m_pausedCallFrames.size()) {
*errorString = "Could not find call frame with given id"; *errorString = "Could not find call frame with given id";
return; return;
...@@ -715,16 +720,19 @@ void V8DebuggerAgentImpl::evaluateOnCallFrame( ...@@ -715,16 +720,19 @@ void V8DebuggerAgentImpl::evaluateOnCallFrame(
std::unique_ptr<RemoteObject>* result, std::unique_ptr<RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
if (!assertPaused(errorString)) return; if (!assertPaused(errorString)) return;
InjectedScript::CallFrameScope scope( InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
errorString, m_inspector, m_session->contextGroupId(), callFrameId); callFrameId);
if (!scope.initialize()) return; Response response = scope.initialize();
if (!response.isSuccess()) {
*errorString = response.errorMessage();
return;
}
if (scope.frameOrdinal() >= m_pausedCallFrames.size()) { if (scope.frameOrdinal() >= m_pausedCallFrames.size()) {
*errorString = "Could not find call frame with given id"; *errorString = "Could not find call frame with given id";
return; return;
} }
if (includeCommandLineAPI.fromMaybe(false) && !scope.installCommandLineAPI()) if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI();
return;
if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole(); if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole();
v8::MaybeLocal<v8::Value> maybeResultValue = v8::MaybeLocal<v8::Value> maybeResultValue =
...@@ -733,11 +741,16 @@ void V8DebuggerAgentImpl::evaluateOnCallFrame( ...@@ -733,11 +741,16 @@ void V8DebuggerAgentImpl::evaluateOnCallFrame(
// Re-initialize after running client's code, as it could have destroyed // Re-initialize after running client's code, as it could have destroyed
// context or session. // context or session.
if (!scope.initialize()) return; response = scope.initialize();
scope.injectedScript()->wrapEvaluateResult( if (!response.isSuccess()) {
errorString, maybeResultValue, scope.tryCatch(), *errorString = response.errorMessage();
objectGroup.fromMaybe(""), returnByValue.fromMaybe(false), return;
generatePreview.fromMaybe(false), result, exceptionDetails); }
response = scope.injectedScript()->wrapEvaluateResult(
maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""),
returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result,
exceptionDetails);
if (!response.isSuccess()) *errorString = response.errorMessage();
} }
void V8DebuggerAgentImpl::setVariableValue( void V8DebuggerAgentImpl::setVariableValue(
...@@ -746,15 +759,20 @@ void V8DebuggerAgentImpl::setVariableValue( ...@@ -746,15 +759,20 @@ void V8DebuggerAgentImpl::setVariableValue(
const String16& callFrameId) { const String16& callFrameId) {
if (!checkEnabled(errorString)) return; if (!checkEnabled(errorString)) return;
if (!assertPaused(errorString)) return; if (!assertPaused(errorString)) return;
InjectedScript::CallFrameScope scope( InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
errorString, m_inspector, m_session->contextGroupId(), callFrameId); callFrameId);
if (!scope.initialize()) return; Response response = scope.initialize();
if (!response.isSuccess()) {
*errorString = response.errorMessage();
return;
}
v8::Local<v8::Value> newValue; v8::Local<v8::Value> newValue;
if (!scope.injectedScript() response = scope.injectedScript()->resolveCallArgument(newValueArgument.get(),
->resolveCallArgument(errorString, newValueArgument.get()) &newValue);
.ToLocal(&newValue)) if (!response.isSuccess()) {
*errorString = response.errorMessage();
return; return;
}
if (scope.frameOrdinal() >= m_pausedCallFrames.size()) { if (scope.frameOrdinal() >= m_pausedCallFrames.size()) {
*errorString = "Could not find call frame with given id"; *errorString = "Could not find call frame with given id";
...@@ -907,7 +925,6 @@ std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames( ...@@ -907,7 +925,6 @@ std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames(
ErrorString* errorString) { ErrorString* errorString) {
if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size()) if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size())
return Array<CallFrame>::create(); return Array<CallFrame>::create();
ErrorString ignored;
v8::HandleScope handles(m_isolate); v8::HandleScope handles(m_isolate);
v8::Local<v8::Context> debuggerContext = v8::Local<v8::Context> debuggerContext =
v8::DebugInterface::GetDebugContext(m_isolate); v8::DebugInterface::GetDebugContext(m_isolate);
...@@ -925,9 +942,9 @@ std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames( ...@@ -925,9 +942,9 @@ std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames(
return Array<CallFrame>::create(); return Array<CallFrame>::create();
int contextId = currentCallFrame->contextId(); int contextId = currentCallFrame->contextId();
InjectedScript* injectedScript =
contextId ? m_session->findInjectedScript(&ignored, contextId) InjectedScript* injectedScript = nullptr;
: nullptr; if (contextId) m_session->findInjectedScript(contextId, injectedScript);
String16 callFrameId = String16 callFrameId =
RemoteCallFrameId::serialize(contextId, static_cast<int>(frameOrdinal)); RemoteCallFrameId::serialize(contextId, static_cast<int>(frameOrdinal));
...@@ -950,24 +967,31 @@ std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames( ...@@ -950,24 +967,31 @@ std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames(
!scopeChain->IsArray())) !scopeChain->IsArray()))
return Array<CallFrame>::create(); return Array<CallFrame>::create();
v8::Local<v8::Array> scopeChainArray = scopeChain.As<v8::Array>(); v8::Local<v8::Array> scopeChainArray = scopeChain.As<v8::Array>();
if (!injectedScript->wrapPropertyInArray( Response response = injectedScript->wrapPropertyInArray(
errorString, scopeChainArray, scopeChainArray, toV8StringInternalized(m_isolate, "object"),
toV8StringInternalized(m_isolate, "object"), backtraceObjectGroup);
backtraceObjectGroup)) if (!response.isSuccess()) {
*errorString = response.errorMessage();
return Array<CallFrame>::create(); return Array<CallFrame>::create();
if (!injectedScript->wrapObjectProperty( }
errorString, details, toV8StringInternalized(m_isolate, "this"), response = injectedScript->wrapObjectProperty(
backtraceObjectGroup)) details, toV8StringInternalized(m_isolate, "this"),
backtraceObjectGroup);
if (!response.isSuccess()) {
*errorString = response.errorMessage();
return Array<CallFrame>::create(); return Array<CallFrame>::create();
}
if (details if (details
->Has(debuggerContext, ->Has(debuggerContext,
toV8StringInternalized(m_isolate, "returnValue")) toV8StringInternalized(m_isolate, "returnValue"))
.FromMaybe(false)) { .FromMaybe(false)) {
if (!injectedScript->wrapObjectProperty( response = injectedScript->wrapObjectProperty(
errorString, details, details, toV8StringInternalized(m_isolate, "returnValue"),
toV8StringInternalized(m_isolate, "returnValue"), backtraceObjectGroup);
backtraceObjectGroup)) if (!response.isSuccess()) {
*errorString = response.errorMessage();
return Array<CallFrame>::create(); return Array<CallFrame>::create();
}
} }
} else { } else {
if (hasInternalError(errorString, !details if (hasInternalError(errorString, !details
...@@ -1010,9 +1034,9 @@ std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames( ...@@ -1010,9 +1034,9 @@ std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames(
return Array<CallFrame>::create(); return Array<CallFrame>::create();
} }
std::unique_ptr<protocol::Value> protocolValue = std::unique_ptr<protocol::Value> protocolValue;
toProtocolValue(errorString, debuggerContext, objects); Response response = toProtocolValue(debuggerContext, objects, &protocolValue);
if (!protocolValue) return Array<CallFrame>::create(); if (!response.isSuccess()) return Array<CallFrame>::create();
protocol::ErrorSupport errorSupport; protocol::ErrorSupport errorSupport;
std::unique_ptr<Array<CallFrame>> callFrames = std::unique_ptr<Array<CallFrame>> callFrames =
Array<CallFrame>::parse(protocolValue.get(), &errorSupport); Array<CallFrame>::parse(protocolValue.get(), &errorSupport);
...@@ -1127,17 +1151,17 @@ V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause( ...@@ -1127,17 +1151,17 @@ V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(
v8::HandleScope handles(m_isolate); v8::HandleScope handles(m_isolate);
if (!exception.IsEmpty()) { if (!exception.IsEmpty()) {
ErrorString ignored; InjectedScript* injectedScript = nullptr;
InjectedScript* injectedScript = m_session->findInjectedScript(V8Debugger::contextId(context),
m_session->findInjectedScript(&ignored, V8Debugger::contextId(context)); injectedScript);
if (injectedScript) { if (injectedScript) {
m_breakReason = m_breakReason =
isPromiseRejection isPromiseRejection
? protocol::Debugger::Paused::ReasonEnum::PromiseRejection ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection
: protocol::Debugger::Paused::ReasonEnum::Exception; : protocol::Debugger::Paused::ReasonEnum::Exception;
ErrorString errorString; std::unique_ptr<protocol::Runtime::RemoteObject> obj;
auto obj = injectedScript->wrapObject(&errorString, exception, injectedScript->wrapObject(exception, backtraceObjectGroup, false, false,
backtraceObjectGroup); &obj);
m_breakAuxData = obj ? obj->serialize() : nullptr; m_breakAuxData = obj ? obj->serialize() : nullptr;
// m_breakAuxData might be null after this. // m_breakAuxData might be null after this.
} }
......
...@@ -269,11 +269,10 @@ Response V8HeapProfilerAgentImpl::getHeapObjectId( ...@@ -269,11 +269,10 @@ Response V8HeapProfilerAgentImpl::getHeapObjectId(
v8::HandleScope handles(m_isolate); v8::HandleScope handles(m_isolate);
v8::Local<v8::Value> value; v8::Local<v8::Value> value;
v8::Local<v8::Context> context; v8::Local<v8::Context> context;
protocol::ErrorString errorString; Response response =
if (!m_session->unwrapObject(&errorString, objectId, &value, &context, m_session->unwrapObject(objectId, &value, &context, nullptr);
nullptr) || if (!response.isSuccess()) return response;
value->IsUndefined()) if (value->IsUndefined()) return Response::InternalError();
return Response::Error(errorString);
v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value); v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value);
*heapSnapshotObjectId = String16::fromInteger(static_cast<size_t>(id)); *heapSnapshotObjectId = String16::fromInteger(static_cast<size_t>(id));
......
...@@ -104,12 +104,12 @@ V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector, ...@@ -104,12 +104,12 @@ V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector,
} }
V8InspectorSessionImpl::~V8InspectorSessionImpl() { V8InspectorSessionImpl::~V8InspectorSessionImpl() {
ErrorString errorString; protocol::ErrorString errorString;
m_consoleAgent->disable(); m_consoleAgent->disable();
m_profilerAgent->disable(); m_profilerAgent->disable();
m_heapProfilerAgent->disable(); m_heapProfilerAgent->disable();
m_debuggerAgent->disable(&errorString); m_debuggerAgent->disable(&errorString);
m_runtimeAgent->disable(&errorString); m_runtimeAgent->disable();
discardInjectedScripts(); discardInjectedScripts();
m_inspector->disconnect(this); m_inspector->disconnect(this);
...@@ -165,42 +165,35 @@ void V8InspectorSessionImpl::discardInjectedScripts() { ...@@ -165,42 +165,35 @@ void V8InspectorSessionImpl::discardInjectedScripts() {
} }
} }
InjectedScript* V8InspectorSessionImpl::findInjectedScript( Response V8InspectorSessionImpl::findInjectedScript(
ErrorString* errorString, int contextId) { int contextId, InjectedScript*& injectedScript) {
if (!contextId) { injectedScript = nullptr;
*errorString = "Cannot find context with specified id"; if (!contextId)
return nullptr; return Response::Error("Cannot find context with specified id");
}
const V8InspectorImpl::ContextByIdMap* contexts = const V8InspectorImpl::ContextByIdMap* contexts =
m_inspector->contextGroup(m_contextGroupId); m_inspector->contextGroup(m_contextGroupId);
if (!contexts) { if (!contexts)
*errorString = "Cannot find context with specified id"; return Response::Error("Cannot find context with specified id");
return nullptr;
}
auto contextsIt = contexts->find(contextId); auto contextsIt = contexts->find(contextId);
if (contextsIt == contexts->end()) { if (contextsIt == contexts->end())
*errorString = "Cannot find context with specified id"; return Response::Error("Cannot find context with specified id");
return nullptr;
}
const std::unique_ptr<InspectedContext>& context = contextsIt->second; const std::unique_ptr<InspectedContext>& context = contextsIt->second;
if (!context->getInjectedScript()) { if (!context->getInjectedScript()) {
if (!context->createInjectedScript()) { if (!context->createInjectedScript())
*errorString = "Cannot access specified execution context"; return Response::Error("Cannot access specified execution context");
return nullptr;
}
if (m_customObjectFormatterEnabled) if (m_customObjectFormatterEnabled)
context->getInjectedScript()->setCustomObjectFormatterEnabled(true); context->getInjectedScript()->setCustomObjectFormatterEnabled(true);
} }
return context->getInjectedScript(); injectedScript = context->getInjectedScript();
return Response::OK();
} }
InjectedScript* V8InspectorSessionImpl::findInjectedScript( Response V8InspectorSessionImpl::findInjectedScript(
ErrorString* errorString, RemoteObjectIdBase* objectId) { RemoteObjectIdBase* objectId, InjectedScript*& injectedScript) {
return objectId ? findInjectedScript(errorString, objectId->contextId()) return findInjectedScript(objectId->contextId(), injectedScript);
: nullptr;
} }
void V8InspectorSessionImpl::releaseObjectGroup(const StringView& objectGroup) { void V8InspectorSessionImpl::releaseObjectGroup(const StringView& objectGroup) {
...@@ -230,31 +223,35 @@ bool V8InspectorSessionImpl::unwrapObject( ...@@ -230,31 +223,35 @@ bool V8InspectorSessionImpl::unwrapObject(
std::unique_ptr<StringBuffer>* error, const StringView& objectId, std::unique_ptr<StringBuffer>* error, const StringView& objectId,
v8::Local<v8::Value>* object, v8::Local<v8::Context>* context, v8::Local<v8::Value>* object, v8::Local<v8::Context>* context,
std::unique_ptr<StringBuffer>* objectGroup) { std::unique_ptr<StringBuffer>* objectGroup) {
ErrorString errorString;
String16 objectGroupString; String16 objectGroupString;
bool result = Response response = unwrapObject(toString16(objectId), object, context,
unwrapObject(&errorString, toString16(objectId), object, context, objectGroup ? &objectGroupString : nullptr);
objectGroup ? &objectGroupString : nullptr); if (!response.isSuccess()) {
if (error) *error = StringBufferImpl::adopt(errorString); if (error) {
String16 errorMessage = response.errorMessage();
*error = StringBufferImpl::adopt(errorMessage);
}
return false;
}
if (objectGroup) *objectGroup = StringBufferImpl::adopt(objectGroupString); if (objectGroup) *objectGroup = StringBufferImpl::adopt(objectGroupString);
return result; return true;
} }
bool V8InspectorSessionImpl::unwrapObject(ErrorString* errorString, Response V8InspectorSessionImpl::unwrapObject(const String16& objectId,
const String16& objectId, v8::Local<v8::Value>* object,
v8::Local<v8::Value>* object, v8::Local<v8::Context>* context,
v8::Local<v8::Context>* context, String16* objectGroup) {
String16* objectGroup) { std::unique_ptr<RemoteObjectId> remoteId;
std::unique_ptr<RemoteObjectId> remoteId = Response response = RemoteObjectId::parse(objectId, &remoteId);
RemoteObjectId::parse(errorString, objectId); if (!response.isSuccess()) return response;
if (!remoteId) return false; InjectedScript* injectedScript = nullptr;
InjectedScript* injectedScript = response = findInjectedScript(remoteId.get(), injectedScript);
findInjectedScript(errorString, remoteId.get()); if (!response.isSuccess()) return response;
if (!injectedScript) return false; response = injectedScript->findObject(*remoteId, object);
if (!injectedScript->findObject(errorString, *remoteId, object)) return false; if (!response.isSuccess()) return response;
*context = injectedScript->context()->context(); *context = injectedScript->context()->context();
if (objectGroup) *objectGroup = injectedScript->objectGroupName(*remoteId); if (objectGroup) *objectGroup = injectedScript->objectGroupName(*remoteId);
return true; return Response::OK();
} }
std::unique_ptr<protocol::Runtime::API::RemoteObject> std::unique_ptr<protocol::Runtime::API::RemoteObject>
...@@ -269,21 +266,20 @@ V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context, ...@@ -269,21 +266,20 @@ V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context,
v8::Local<v8::Value> value, v8::Local<v8::Value> value,
const String16& groupName, const String16& groupName,
bool generatePreview) { bool generatePreview) {
ErrorString errorString; InjectedScript* injectedScript = nullptr;
InjectedScript* injectedScript = findInjectedScript(V8Debugger::contextId(context), injectedScript);
findInjectedScript(&errorString, V8Debugger::contextId(context));
if (!injectedScript) return nullptr; if (!injectedScript) return nullptr;
return injectedScript->wrapObject(&errorString, value, groupName, false, std::unique_ptr<protocol::Runtime::RemoteObject> result;
generatePreview); injectedScript->wrapObject(value, groupName, false, generatePreview, &result);
return result;
} }
std::unique_ptr<protocol::Runtime::RemoteObject> std::unique_ptr<protocol::Runtime::RemoteObject>
V8InspectorSessionImpl::wrapTable(v8::Local<v8::Context> context, V8InspectorSessionImpl::wrapTable(v8::Local<v8::Context> context,
v8::Local<v8::Value> table, v8::Local<v8::Value> table,
v8::Local<v8::Value> columns) { v8::Local<v8::Value> columns) {
ErrorString errorString; InjectedScript* injectedScript = nullptr;
InjectedScript* injectedScript = findInjectedScript(V8Debugger::contextId(context), injectedScript);
findInjectedScript(&errorString, V8Debugger::contextId(context));
if (!injectedScript) return nullptr; if (!injectedScript) return nullptr;
return injectedScript->wrapTable(table, columns); return injectedScript->wrapTable(table, columns);
} }
...@@ -386,17 +382,17 @@ void V8InspectorSessionImpl::breakProgram(const StringView& breakReason, ...@@ -386,17 +382,17 @@ void V8InspectorSessionImpl::breakProgram(const StringView& breakReason,
} }
void V8InspectorSessionImpl::setSkipAllPauses(bool skip) { void V8InspectorSessionImpl::setSkipAllPauses(bool skip) {
ErrorString errorString; protocol::ErrorString errorString;
m_debuggerAgent->setSkipAllPauses(&errorString, skip); m_debuggerAgent->setSkipAllPauses(&errorString, skip);
} }
void V8InspectorSessionImpl::resume() { void V8InspectorSessionImpl::resume() {
ErrorString errorString; protocol::ErrorString errorString;
m_debuggerAgent->resume(&errorString); m_debuggerAgent->resume(&errorString);
} }
void V8InspectorSessionImpl::stepOver() { void V8InspectorSessionImpl::stepOver() {
ErrorString errorString; protocol::ErrorString errorString;
m_debuggerAgent->stepOver(&errorString); m_debuggerAgent->stepOver(&errorString);
} }
......
...@@ -26,7 +26,7 @@ class V8ProfilerAgentImpl; ...@@ -26,7 +26,7 @@ class V8ProfilerAgentImpl;
class V8RuntimeAgentImpl; class V8RuntimeAgentImpl;
class V8SchemaAgentImpl; class V8SchemaAgentImpl;
using protocol::ErrorString; using protocol::Response;
class V8InspectorSessionImpl : public V8InspectorSession, class V8InspectorSessionImpl : public V8InspectorSession,
public protocol::FrontendChannel { public protocol::FrontendChannel {
...@@ -44,8 +44,8 @@ class V8InspectorSessionImpl : public V8InspectorSession, ...@@ -44,8 +44,8 @@ class V8InspectorSessionImpl : public V8InspectorSession,
V8RuntimeAgentImpl* runtimeAgent() { return m_runtimeAgent.get(); } V8RuntimeAgentImpl* runtimeAgent() { return m_runtimeAgent.get(); }
int contextGroupId() const { return m_contextGroupId; } int contextGroupId() const { return m_contextGroupId; }
InjectedScript* findInjectedScript(ErrorString*, int contextId); Response findInjectedScript(int contextId, InjectedScript*&);
InjectedScript* findInjectedScript(ErrorString*, RemoteObjectIdBase*); Response findInjectedScript(RemoteObjectIdBase*, InjectedScript*&);
void reset(); void reset();
void discardInjectedScripts(); void discardInjectedScripts();
void reportAllContexts(V8RuntimeAgentImpl*); void reportAllContexts(V8RuntimeAgentImpl*);
...@@ -57,9 +57,8 @@ class V8InspectorSessionImpl : public V8InspectorSession, ...@@ -57,9 +57,8 @@ class V8InspectorSessionImpl : public V8InspectorSession,
v8::Local<v8::Context>, v8::Local<v8::Value> table, v8::Local<v8::Context>, v8::Local<v8::Value> table,
v8::Local<v8::Value> columns); v8::Local<v8::Value> columns);
std::vector<std::unique_ptr<protocol::Schema::Domain>> supportedDomainsImpl(); std::vector<std::unique_ptr<protocol::Schema::Domain>> supportedDomainsImpl();
bool unwrapObject(ErrorString*, const String16& objectId, Response unwrapObject(const String16& objectId, v8::Local<v8::Value>*,
v8::Local<v8::Value>*, v8::Local<v8::Context>*, v8::Local<v8::Context>*, String16* objectGroup);
String16* objectGroup);
void releaseObjectGroup(const String16& objectGroup); void releaseObjectGroup(const String16& objectGroup);
// V8InspectorSession implementation. // V8InspectorSession implementation.
......
...@@ -55,11 +55,6 @@ static const char runtimeEnabled[] = "runtimeEnabled"; ...@@ -55,11 +55,6 @@ static const char runtimeEnabled[] = "runtimeEnabled";
using protocol::Runtime::RemoteObject; using protocol::Runtime::RemoteObject;
static bool hasInternalError(ErrorString* errorString, bool hasError) {
if (hasError) *errorString = "Internal error";
return hasError;
}
namespace { namespace {
template <typename Callback> template <typename Callback>
...@@ -72,11 +67,11 @@ class ProtocolPromiseHandler { ...@@ -72,11 +67,11 @@ class ProtocolPromiseHandler {
bool returnByValue, bool generatePreview, bool returnByValue, bool generatePreview,
std::unique_ptr<Callback> callback) { std::unique_ptr<Callback> callback) {
if (value.IsEmpty()) { if (value.IsEmpty()) {
callback->sendFailure("Internal error"); callback->sendFailure(Response::InternalError());
return; return;
} }
if (!value.ToLocalChecked()->IsPromise()) { if (!value.ToLocalChecked()->IsPromise()) {
callback->sendFailure(notPromiseError); callback->sendFailure(Response::Error(notPromiseError));
return; return;
} }
v8::MicrotasksScope microtasks_scope(inspector->isolate(), v8::MicrotasksScope microtasks_scope(inspector->isolate(),
...@@ -94,7 +89,7 @@ class ProtocolPromiseHandler { ...@@ -94,7 +89,7 @@ class ProtocolPromiseHandler {
v8::ConstructorBehavior::kThrow) v8::ConstructorBehavior::kThrow)
.ToLocalChecked(); .ToLocalChecked();
if (promise->Then(context, thenCallbackFunction).IsEmpty()) { if (promise->Then(context, thenCallbackFunction).IsEmpty()) {
rawCallback->sendFailure("Internal error"); rawCallback->sendFailure(Response::InternalError());
return; return;
} }
v8::Local<v8::Function> catchCallbackFunction = v8::Local<v8::Function> catchCallbackFunction =
...@@ -102,7 +97,7 @@ class ProtocolPromiseHandler { ...@@ -102,7 +97,7 @@ class ProtocolPromiseHandler {
v8::ConstructorBehavior::kThrow) v8::ConstructorBehavior::kThrow)
.ToLocalChecked(); .ToLocalChecked();
if (promise->Catch(context, catchCallbackFunction).IsEmpty()) { if (promise->Catch(context, catchCallbackFunction).IsEmpty()) {
rawCallback->sendFailure("Internal error"); rawCallback->sendFailure(Response::InternalError());
return; return;
} }
} }
...@@ -180,25 +175,27 @@ class ProtocolPromiseHandler { ...@@ -180,25 +175,27 @@ class ProtocolPromiseHandler {
data.GetParameter()->m_wrapper.Reset(); data.GetParameter()->m_wrapper.Reset();
data.SetSecondPassCallback(cleanup); data.SetSecondPassCallback(cleanup);
} else { } else {
data.GetParameter()->m_callback->sendFailure("Promise was collected"); data.GetParameter()->m_callback->sendFailure(
Response::Error("Promise was collected"));
delete data.GetParameter(); delete data.GetParameter();
} }
} }
std::unique_ptr<protocol::Runtime::RemoteObject> wrapObject( std::unique_ptr<protocol::Runtime::RemoteObject> wrapObject(
v8::Local<v8::Value> value) { v8::Local<v8::Value> value) {
ErrorString errorString; InjectedScript::ContextScope scope(m_inspector, m_contextGroupId,
InjectedScript::ContextScope scope(&errorString, m_inspector, m_executionContextId);
m_contextGroupId, m_executionContextId); Response response = scope.initialize();
if (!scope.initialize()) { if (!response.isSuccess()) {
m_callback->sendFailure(errorString); m_callback->sendFailure(response);
return nullptr; return nullptr;
} }
std::unique_ptr<protocol::Runtime::RemoteObject> wrappedValue = std::unique_ptr<protocol::Runtime::RemoteObject> wrappedValue;
scope.injectedScript()->wrapObject(&errorString, value, m_objectGroup, response = scope.injectedScript()->wrapObject(
m_returnByValue, m_generatePreview); value, m_objectGroup, m_returnByValue, m_generatePreview,
if (!wrappedValue) { &wrappedValue);
m_callback->sendFailure(errorString); if (!response.isSuccess()) {
m_callback->sendFailure(response);
return nullptr; return nullptr;
} }
return wrappedValue; return wrappedValue;
...@@ -223,34 +220,30 @@ bool wrapEvaluateResultAsync(InjectedScript* injectedScript, ...@@ -223,34 +220,30 @@ bool wrapEvaluateResultAsync(InjectedScript* injectedScript,
std::unique_ptr<RemoteObject> result; std::unique_ptr<RemoteObject> result;
Maybe<protocol::Runtime::ExceptionDetails> exceptionDetails; Maybe<protocol::Runtime::ExceptionDetails> exceptionDetails;
ErrorString errorString; Response response = injectedScript->wrapEvaluateResult(
injectedScript->wrapEvaluateResult( maybeResultValue, tryCatch, objectGroup, returnByValue, generatePreview,
&errorString, maybeResultValue, tryCatch, objectGroup, returnByValue, &result, &exceptionDetails);
generatePreview, &result, &exceptionDetails); if (response.isSuccess()) {
if (errorString.isEmpty()) { callback->sendSuccess(std::move(result), std::move(exceptionDetails));
callback->sendSuccess(std::move(result), exceptionDetails);
return true; return true;
} }
callback->sendFailure(errorString); callback->sendFailure(response);
return false; return false;
} }
int ensureContext(ErrorString* errorString, V8InspectorImpl* inspector, Response ensureContext(V8InspectorImpl* inspector, int contextGroupId,
int contextGroupId, const Maybe<int>& executionContextId) { Maybe<int> executionContextId, int* contextId) {
int contextId;
if (executionContextId.isJust()) { if (executionContextId.isJust()) {
contextId = executionContextId.fromJust(); *contextId = executionContextId.fromJust();
} else { } else {
v8::HandleScope handles(inspector->isolate()); v8::HandleScope handles(inspector->isolate());
v8::Local<v8::Context> defaultContext = v8::Local<v8::Context> defaultContext =
inspector->client()->ensureDefaultContextInGroup(contextGroupId); inspector->client()->ensureDefaultContextInGroup(contextGroupId);
if (defaultContext.IsEmpty()) { if (defaultContext.IsEmpty())
*errorString = "Cannot find default execution context"; return Response::Error("Cannot find default execution context");
return 0; *contextId = V8Debugger::contextId(defaultContext);
}
contextId = V8Debugger::contextId(defaultContext);
} }
return contextId; return Response::OK();
} }
} // namespace } // namespace
...@@ -267,38 +260,33 @@ V8RuntimeAgentImpl::V8RuntimeAgentImpl( ...@@ -267,38 +260,33 @@ V8RuntimeAgentImpl::V8RuntimeAgentImpl(
V8RuntimeAgentImpl::~V8RuntimeAgentImpl() {} V8RuntimeAgentImpl::~V8RuntimeAgentImpl() {}
void V8RuntimeAgentImpl::evaluate( void V8RuntimeAgentImpl::evaluate(
const String16& expression, const Maybe<String16>& objectGroup, const String16& expression, Maybe<String16> objectGroup,
const Maybe<bool>& includeCommandLineAPI, const Maybe<bool>& silent, Maybe<bool> includeCommandLineAPI, Maybe<bool> silent,
const Maybe<int>& executionContextId, const Maybe<bool>& returnByValue, Maybe<int> executionContextId, Maybe<bool> returnByValue,
const Maybe<bool>& generatePreview, const Maybe<bool>& userGesture, Maybe<bool> generatePreview, Maybe<bool> userGesture,
const Maybe<bool>& awaitPromise, Maybe<bool> awaitPromise, std::unique_ptr<EvaluateCallback> callback) {
std::unique_ptr<EvaluateCallback> callback) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
"EvaluateScript"); "EvaluateScript");
ErrorString errorString; int contextId = 0;
int contextId = Response response = ensureContext(m_inspector, m_session->contextGroupId(),
ensureContext(&errorString, m_inspector, m_session->contextGroupId(), std::move(executionContextId), &contextId);
executionContextId); if (!response.isSuccess()) {
if (!errorString.isEmpty()) { callback->sendFailure(response);
callback->sendFailure(errorString);
return; return;
} }
InjectedScript::ContextScope scope(&errorString, m_inspector, InjectedScript::ContextScope scope(m_inspector, m_session->contextGroupId(),
m_session->contextGroupId(), contextId); contextId);
if (!scope.initialize()) { response = scope.initialize();
callback->sendFailure(errorString); if (!response.isSuccess()) {
callback->sendFailure(response);
return; return;
} }
if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole(); if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole();
if (userGesture.fromMaybe(false)) scope.pretendUserGesture(); if (userGesture.fromMaybe(false)) scope.pretendUserGesture();
if (includeCommandLineAPI.fromMaybe(false) && if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI();
!scope.installCommandLineAPI()) {
callback->sendFailure(errorString);
return;
}
bool evalIsDisabled = !scope.context()->IsCodeGenerationFromStringsAllowed(); bool evalIsDisabled = !scope.context()->IsCodeGenerationFromStringsAllowed();
// Temporarily enable allow evals for inspector. // Temporarily enable allow evals for inspector.
...@@ -315,8 +303,9 @@ void V8RuntimeAgentImpl::evaluate( ...@@ -315,8 +303,9 @@ void V8RuntimeAgentImpl::evaluate(
// Re-initialize after running client's code, as it could have destroyed // Re-initialize after running client's code, as it could have destroyed
// context or session. // context or session.
if (!scope.initialize()) { response = scope.initialize();
callback->sendFailure(errorString); if (!response.isSuccess()) {
callback->sendFailure(response);
return; return;
} }
...@@ -336,14 +325,14 @@ void V8RuntimeAgentImpl::evaluate( ...@@ -336,14 +325,14 @@ void V8RuntimeAgentImpl::evaluate(
} }
void V8RuntimeAgentImpl::awaitPromise( void V8RuntimeAgentImpl::awaitPromise(
const String16& promiseObjectId, const Maybe<bool>& returnByValue, const String16& promiseObjectId, Maybe<bool> returnByValue,
const Maybe<bool>& generatePreview, Maybe<bool> generatePreview,
std::unique_ptr<AwaitPromiseCallback> callback) { std::unique_ptr<AwaitPromiseCallback> callback) {
ErrorString errorString; InjectedScript::ObjectScope scope(m_inspector, m_session->contextGroupId(),
InjectedScript::ObjectScope scope( promiseObjectId);
&errorString, m_inspector, m_session->contextGroupId(), promiseObjectId); Response response = scope.initialize();
if (!scope.initialize()) { if (!response.isSuccess()) {
callback->sendFailure(errorString); callback->sendFailure(response);
return; return;
} }
ProtocolPromiseHandler<AwaitPromiseCallback>::add( ProtocolPromiseHandler<AwaitPromiseCallback>::add(
...@@ -356,17 +345,15 @@ void V8RuntimeAgentImpl::awaitPromise( ...@@ -356,17 +345,15 @@ void V8RuntimeAgentImpl::awaitPromise(
void V8RuntimeAgentImpl::callFunctionOn( void V8RuntimeAgentImpl::callFunctionOn(
const String16& objectId, const String16& expression, const String16& objectId, const String16& expression,
const Maybe<protocol::Array<protocol::Runtime::CallArgument>>& Maybe<protocol::Array<protocol::Runtime::CallArgument>> optionalArguments,
optionalArguments, Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
const Maybe<bool>& silent, const Maybe<bool>& returnByValue, Maybe<bool> userGesture, Maybe<bool> awaitPromise,
const Maybe<bool>& generatePreview, const Maybe<bool>& userGesture,
const Maybe<bool>& awaitPromise,
std::unique_ptr<CallFunctionOnCallback> callback) { std::unique_ptr<CallFunctionOnCallback> callback) {
ErrorString errorString; InjectedScript::ObjectScope scope(m_inspector, m_session->contextGroupId(),
InjectedScript::ObjectScope scope(&errorString, m_inspector, objectId);
m_session->contextGroupId(), objectId); Response response = scope.initialize();
if (!scope.initialize()) { if (!response.isSuccess()) {
callback->sendFailure(errorString); callback->sendFailure(response);
return; return;
} }
...@@ -379,10 +366,10 @@ void V8RuntimeAgentImpl::callFunctionOn( ...@@ -379,10 +366,10 @@ void V8RuntimeAgentImpl::callFunctionOn(
argv.reset(new v8::Local<v8::Value>[argc]); argv.reset(new v8::Local<v8::Value>[argc]);
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
v8::Local<v8::Value> argumentValue; v8::Local<v8::Value> argumentValue;
if (!scope.injectedScript() response = scope.injectedScript()->resolveCallArgument(arguments->get(i),
->resolveCallArgument(&errorString, arguments->get(i)) &argumentValue);
.ToLocal(&argumentValue)) { if (!response.isSuccess()) {
callback->sendFailure(errorString); callback->sendFailure(response);
return; return;
} }
argv[i] = argumentValue; argv[i] = argumentValue;
...@@ -398,8 +385,9 @@ void V8RuntimeAgentImpl::callFunctionOn( ...@@ -398,8 +385,9 @@ void V8RuntimeAgentImpl::callFunctionOn(
toV8String(m_inspector->isolate(), "(" + expression + ")")); toV8String(m_inspector->isolate(), "(" + expression + ")"));
// Re-initialize after running client's code, as it could have destroyed // Re-initialize after running client's code, as it could have destroyed
// context or session. // context or session.
if (!scope.initialize()) { response = scope.initialize();
callback->sendFailure(errorString); if (!response.isSuccess()) {
callback->sendFailure(response);
return; return;
} }
...@@ -413,7 +401,8 @@ void V8RuntimeAgentImpl::callFunctionOn( ...@@ -413,7 +401,8 @@ void V8RuntimeAgentImpl::callFunctionOn(
v8::Local<v8::Value> functionValue; v8::Local<v8::Value> functionValue;
if (!maybeFunctionValue.ToLocal(&functionValue) || if (!maybeFunctionValue.ToLocal(&functionValue) ||
!functionValue->IsFunction()) { !functionValue->IsFunction()) {
callback->sendFailure("Given expression does not evaluate to a function"); callback->sendFailure(
Response::Error("Given expression does not evaluate to a function"));
return; return;
} }
...@@ -422,8 +411,9 @@ void V8RuntimeAgentImpl::callFunctionOn( ...@@ -422,8 +411,9 @@ void V8RuntimeAgentImpl::callFunctionOn(
argv.get()); argv.get());
// Re-initialize after running client's code, as it could have destroyed // Re-initialize after running client's code, as it could have destroyed
// context or session. // context or session.
if (!scope.initialize()) { response = scope.initialize();
callback->sendFailure(errorString); if (!response.isSuccess()) {
callback->sendFailure(response);
return; return;
} }
...@@ -444,10 +434,9 @@ void V8RuntimeAgentImpl::callFunctionOn( ...@@ -444,10 +434,9 @@ void V8RuntimeAgentImpl::callFunctionOn(
std::move(callback)); std::move(callback));
} }
void V8RuntimeAgentImpl::getProperties( Response V8RuntimeAgentImpl::getProperties(
ErrorString* errorString, const String16& objectId, const String16& objectId, Maybe<bool> ownProperties,
const Maybe<bool>& ownProperties, const Maybe<bool>& accessorPropertiesOnly, Maybe<bool> accessorPropertiesOnly, Maybe<bool> generatePreview,
const Maybe<bool>& generatePreview,
std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>* std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>*
result, result,
Maybe<protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>* Maybe<protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>*
...@@ -455,105 +444,103 @@ void V8RuntimeAgentImpl::getProperties( ...@@ -455,105 +444,103 @@ void V8RuntimeAgentImpl::getProperties(
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
using protocol::Runtime::InternalPropertyDescriptor; using protocol::Runtime::InternalPropertyDescriptor;
InjectedScript::ObjectScope scope(errorString, m_inspector, InjectedScript::ObjectScope scope(m_inspector, m_session->contextGroupId(),
m_session->contextGroupId(), objectId); objectId);
if (!scope.initialize()) return; Response response = scope.initialize();
if (!response.isSuccess()) return response;
scope.ignoreExceptionsAndMuteConsole(); scope.ignoreExceptionsAndMuteConsole();
if (!scope.object()->IsObject()) { if (!scope.object()->IsObject())
*errorString = "Value with given id is not an object"; return Response::Error("Value with given id is not an object");
return;
}
v8::Local<v8::Object> object = scope.object().As<v8::Object>(); v8::Local<v8::Object> object = scope.object().As<v8::Object>();
scope.injectedScript()->getProperties( response = scope.injectedScript()->getProperties(
errorString, object, scope.objectGroupName(), object, scope.objectGroupName(), ownProperties.fromMaybe(false),
ownProperties.fromMaybe(false), accessorPropertiesOnly.fromMaybe(false), accessorPropertiesOnly.fromMaybe(false), generatePreview.fromMaybe(false),
generatePreview.fromMaybe(false), result, exceptionDetails); result, exceptionDetails);
if (!errorString->isEmpty() || exceptionDetails->isJust() || if (!response.isSuccess()) return response;
accessorPropertiesOnly.fromMaybe(false)) if (exceptionDetails->isJust() || accessorPropertiesOnly.fromMaybe(false))
return; return Response::OK();
v8::Local<v8::Array> propertiesArray; v8::Local<v8::Array> propertiesArray;
if (hasInternalError(errorString, !m_inspector->debugger() if (!m_inspector->debugger()
->internalProperties(scope.context(), ->internalProperties(scope.context(), scope.object())
scope.object()) .ToLocal(&propertiesArray)) {
.ToLocal(&propertiesArray))) return Response::InternalError();
return; }
std::unique_ptr<protocol::Array<InternalPropertyDescriptor>> std::unique_ptr<protocol::Array<InternalPropertyDescriptor>>
propertiesProtocolArray = propertiesProtocolArray =
protocol::Array<InternalPropertyDescriptor>::create(); protocol::Array<InternalPropertyDescriptor>::create();
for (uint32_t i = 0; i < propertiesArray->Length(); i += 2) { for (uint32_t i = 0; i < propertiesArray->Length(); i += 2) {
v8::Local<v8::Value> name; v8::Local<v8::Value> name;
if (hasInternalError( if (!propertiesArray->Get(scope.context(), i).ToLocal(&name) ||
errorString, !name->IsString()) {
!propertiesArray->Get(scope.context(), i).ToLocal(&name)) || return Response::InternalError();
!name->IsString()) }
return;
v8::Local<v8::Value> value; v8::Local<v8::Value> value;
if (hasInternalError( if (!propertiesArray->Get(scope.context(), i + 1).ToLocal(&value))
errorString, return Response::InternalError();
!propertiesArray->Get(scope.context(), i + 1).ToLocal(&value))) std::unique_ptr<RemoteObject> wrappedValue;
return; protocol::Response response = scope.injectedScript()->wrapObject(
std::unique_ptr<RemoteObject> wrappedValue = value, scope.objectGroupName(), false, false, &wrappedValue);
scope.injectedScript()->wrapObject(errorString, value, if (!response.isSuccess()) return response;
scope.objectGroupName());
if (!wrappedValue) return;
propertiesProtocolArray->addItem( propertiesProtocolArray->addItem(
InternalPropertyDescriptor::create() InternalPropertyDescriptor::create()
.setName(toProtocolString(name.As<v8::String>())) .setName(toProtocolString(name.As<v8::String>()))
.setValue(std::move(wrappedValue)) .setValue(std::move(wrappedValue))
.build()); .build());
} }
if (!propertiesProtocolArray->length()) return; if (propertiesProtocolArray->length())
*internalProperties = std::move(propertiesProtocolArray); *internalProperties = std::move(propertiesProtocolArray);
return Response::OK();
} }
void V8RuntimeAgentImpl::releaseObject(ErrorString* errorString, Response V8RuntimeAgentImpl::releaseObject(const String16& objectId) {
const String16& objectId) { InjectedScript::ObjectScope scope(m_inspector, m_session->contextGroupId(),
InjectedScript::ObjectScope scope(errorString, m_inspector, objectId);
m_session->contextGroupId(), objectId); Response response = scope.initialize();
if (!scope.initialize()) return; if (!response.isSuccess()) return response;
scope.injectedScript()->releaseObject(objectId); scope.injectedScript()->releaseObject(objectId);
return Response::OK();
} }
void V8RuntimeAgentImpl::releaseObjectGroup(ErrorString*, Response V8RuntimeAgentImpl::releaseObjectGroup(const String16& objectGroup) {
const String16& objectGroup) {
m_session->releaseObjectGroup(objectGroup); m_session->releaseObjectGroup(objectGroup);
return Response::OK();
} }
void V8RuntimeAgentImpl::runIfWaitingForDebugger(ErrorString* errorString) { Response V8RuntimeAgentImpl::runIfWaitingForDebugger() {
m_inspector->client()->runIfWaitingForDebugger(m_session->contextGroupId()); m_inspector->client()->runIfWaitingForDebugger(m_session->contextGroupId());
return Response::OK();
} }
void V8RuntimeAgentImpl::setCustomObjectFormatterEnabled(ErrorString*, Response V8RuntimeAgentImpl::setCustomObjectFormatterEnabled(bool enabled) {
bool enabled) {
m_state->setBoolean(V8RuntimeAgentImplState::customObjectFormatterEnabled, m_state->setBoolean(V8RuntimeAgentImplState::customObjectFormatterEnabled,
enabled); enabled);
m_session->setCustomObjectFormatterEnabled(enabled); m_session->setCustomObjectFormatterEnabled(enabled);
return Response::OK();
} }
void V8RuntimeAgentImpl::discardConsoleEntries(ErrorString*) { Response V8RuntimeAgentImpl::discardConsoleEntries() {
V8ConsoleMessageStorage* storage = V8ConsoleMessageStorage* storage =
m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId()); m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId());
storage->clear(); storage->clear();
return Response::OK();
} }
void V8RuntimeAgentImpl::compileScript( Response V8RuntimeAgentImpl::compileScript(
ErrorString* errorString, const String16& expression, const String16& expression, const String16& sourceURL, bool persistScript,
const String16& sourceURL, bool persistScript, Maybe<int> executionContextId, Maybe<String16>* scriptId,
const Maybe<int>& executionContextId, Maybe<String16>* scriptId,
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
if (!m_enabled) { if (!m_enabled) return Response::Error("Runtime agent is not enabled");
*errorString = "Runtime agent is not enabled";
return; int contextId = 0;
} Response response = ensureContext(m_inspector, m_session->contextGroupId(),
int contextId = std::move(executionContextId), &contextId);
ensureContext(errorString, m_inspector, m_session->contextGroupId(), if (!response.isSuccess()) return response;
executionContextId); InjectedScript::ContextScope scope(m_inspector, m_session->contextGroupId(),
if (!errorString->isEmpty()) return; contextId);
InjectedScript::ContextScope scope(errorString, m_inspector, response = scope.initialize();
m_session->contextGroupId(), contextId); if (!response.isSuccess()) return response;
if (!scope.initialize()) return;
if (!persistScript) m_inspector->debugger()->muteScriptParsedEvents(); if (!persistScript) m_inspector->debugger()->muteScriptParsedEvents();
v8::Local<v8::Script> script = m_inspector->compileScript( v8::Local<v8::Script> script = m_inspector->compileScript(
...@@ -561,15 +548,17 @@ void V8RuntimeAgentImpl::compileScript( ...@@ -561,15 +548,17 @@ void V8RuntimeAgentImpl::compileScript(
sourceURL, false); sourceURL, false);
if (!persistScript) m_inspector->debugger()->unmuteScriptParsedEvents(); if (!persistScript) m_inspector->debugger()->unmuteScriptParsedEvents();
if (script.IsEmpty()) { if (script.IsEmpty()) {
if (scope.tryCatch().HasCaught()) if (scope.tryCatch().HasCaught()) {
*exceptionDetails = scope.injectedScript()->createExceptionDetails( response = scope.injectedScript()->createExceptionDetails(
errorString, scope.tryCatch(), String16(), false); scope.tryCatch(), String16(), false, exceptionDetails);
else if (!response.isSuccess()) return response;
*errorString = "Script compilation failed"; return Response::OK();
return; } else {
return Response::Error("Script compilation failed");
}
} }
if (!persistScript) return; if (!persistScript) return Response::OK();
String16 scriptValueId = String16 scriptValueId =
String16::fromInteger(script->GetUnboundScript()->GetId()); String16::fromInteger(script->GetUnboundScript()->GetId());
...@@ -577,38 +566,39 @@ void V8RuntimeAgentImpl::compileScript( ...@@ -577,38 +566,39 @@ void V8RuntimeAgentImpl::compileScript(
new v8::Global<v8::Script>(m_inspector->isolate(), script)); new v8::Global<v8::Script>(m_inspector->isolate(), script));
m_compiledScripts[scriptValueId] = std::move(global); m_compiledScripts[scriptValueId] = std::move(global);
*scriptId = scriptValueId; *scriptId = scriptValueId;
return Response::OK();
} }
void V8RuntimeAgentImpl::runScript( void V8RuntimeAgentImpl::runScript(
const String16& scriptId, const Maybe<int>& executionContextId, const String16& scriptId, Maybe<int> executionContextId,
const Maybe<String16>& objectGroup, const Maybe<bool>& silent, Maybe<String16> objectGroup, Maybe<bool> silent,
const Maybe<bool>& includeCommandLineAPI, const Maybe<bool>& returnByValue, Maybe<bool> includeCommandLineAPI, Maybe<bool> returnByValue,
const Maybe<bool>& generatePreview, const Maybe<bool>& awaitPromise, Maybe<bool> generatePreview, Maybe<bool> awaitPromise,
std::unique_ptr<RunScriptCallback> callback) { std::unique_ptr<RunScriptCallback> callback) {
if (!m_enabled) { if (!m_enabled) {
callback->sendFailure("Runtime agent is not enabled"); callback->sendFailure(Response::Error("Runtime agent is not enabled"));
return; return;
} }
auto it = m_compiledScripts.find(scriptId); auto it = m_compiledScripts.find(scriptId);
if (it == m_compiledScripts.end()) { if (it == m_compiledScripts.end()) {
callback->sendFailure("No script with given id"); callback->sendFailure(Response::Error("No script with given id"));
return; return;
} }
ErrorString errorString; int contextId = 0;
int contextId = Response response = ensureContext(m_inspector, m_session->contextGroupId(),
ensureContext(&errorString, m_inspector, m_session->contextGroupId(), std::move(executionContextId), &contextId);
executionContextId); if (!response.isSuccess()) {
if (!errorString.isEmpty()) { callback->sendFailure(response);
callback->sendFailure(errorString);
return; return;
} }
InjectedScript::ContextScope scope(&errorString, m_inspector, InjectedScript::ContextScope scope(m_inspector, m_session->contextGroupId(),
m_session->contextGroupId(), contextId); contextId);
if (!scope.initialize()) { response = scope.initialize();
callback->sendFailure(errorString); if (!response.isSuccess()) {
callback->sendFailure(response);
return; return;
} }
...@@ -618,19 +608,22 @@ void V8RuntimeAgentImpl::runScript( ...@@ -618,19 +608,22 @@ void V8RuntimeAgentImpl::runScript(
m_compiledScripts.erase(it); m_compiledScripts.erase(it);
v8::Local<v8::Script> script = scriptWrapper->Get(m_inspector->isolate()); v8::Local<v8::Script> script = scriptWrapper->Get(m_inspector->isolate());
if (script.IsEmpty()) { if (script.IsEmpty()) {
callback->sendFailure("Script execution failed"); callback->sendFailure(Response::Error("Script execution failed"));
return; return;
} }
if (includeCommandLineAPI.fromMaybe(false) && !scope.installCommandLineAPI()) if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI();
return;
v8::MaybeLocal<v8::Value> maybeResultValue = v8::MaybeLocal<v8::Value> maybeResultValue =
m_inspector->runCompiledScript(scope.context(), script); m_inspector->runCompiledScript(scope.context(), script);
// Re-initialize after running client's code, as it could have destroyed // Re-initialize after running client's code, as it could have destroyed
// context or session. // context or session.
if (!scope.initialize()) return; response = scope.initialize();
if (!response.isSuccess()) {
callback->sendFailure(response);
return;
}
if (!awaitPromise.fromMaybe(false) || scope.tryCatch().HasCaught()) { if (!awaitPromise.fromMaybe(false) || scope.tryCatch().HasCaught()) {
wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue, wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue,
...@@ -652,15 +645,14 @@ void V8RuntimeAgentImpl::restore() { ...@@ -652,15 +645,14 @@ void V8RuntimeAgentImpl::restore() {
if (!m_state->booleanProperty(V8RuntimeAgentImplState::runtimeEnabled, false)) if (!m_state->booleanProperty(V8RuntimeAgentImplState::runtimeEnabled, false))
return; return;
m_frontend.executionContextsCleared(); m_frontend.executionContextsCleared();
ErrorString error; enable();
enable(&error);
if (m_state->booleanProperty( if (m_state->booleanProperty(
V8RuntimeAgentImplState::customObjectFormatterEnabled, false)) V8RuntimeAgentImplState::customObjectFormatterEnabled, false))
m_session->setCustomObjectFormatterEnabled(true); m_session->setCustomObjectFormatterEnabled(true);
} }
void V8RuntimeAgentImpl::enable(ErrorString* errorString) { Response V8RuntimeAgentImpl::enable() {
if (m_enabled) return; if (m_enabled) return Response::OK();
m_inspector->client()->beginEnsureAllContextsInGroup( m_inspector->client()->beginEnsureAllContextsInGroup(
m_session->contextGroupId()); m_session->contextGroupId());
m_enabled = true; m_enabled = true;
...@@ -670,12 +662,13 @@ void V8RuntimeAgentImpl::enable(ErrorString* errorString) { ...@@ -670,12 +662,13 @@ void V8RuntimeAgentImpl::enable(ErrorString* errorString) {
V8ConsoleMessageStorage* storage = V8ConsoleMessageStorage* storage =
m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId()); m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId());
for (const auto& message : storage->messages()) { for (const auto& message : storage->messages()) {
if (!reportMessage(message.get(), false)) return; if (!reportMessage(message.get(), false)) break;
} }
return Response::OK();
} }
void V8RuntimeAgentImpl::disable(ErrorString* errorString) { Response V8RuntimeAgentImpl::disable() {
if (!m_enabled) return; if (!m_enabled) return Response::OK();
m_enabled = false; m_enabled = false;
m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, false); m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, false);
m_inspector->disableStackCapturingIfNeeded(); m_inspector->disableStackCapturingIfNeeded();
...@@ -683,6 +676,7 @@ void V8RuntimeAgentImpl::disable(ErrorString* errorString) { ...@@ -683,6 +676,7 @@ void V8RuntimeAgentImpl::disable(ErrorString* errorString) {
reset(); reset();
m_inspector->client()->endEnsureAllContextsInGroup( m_inspector->client()->endEnsureAllContextsInGroup(
m_session->contextGroupId()); m_session->contextGroupId());
return Response::OK();
} }
void V8RuntimeAgentImpl::reset() { void V8RuntimeAgentImpl::reset() {
......
...@@ -46,7 +46,7 @@ class V8ConsoleMessage; ...@@ -46,7 +46,7 @@ class V8ConsoleMessage;
class V8InspectorImpl; class V8InspectorImpl;
class V8InspectorSessionImpl; class V8InspectorSessionImpl;
using protocol::ErrorString; using protocol::Response;
using protocol::Maybe; using protocol::Maybe;
class V8RuntimeAgentImpl : public protocol::Runtime::Backend { class V8RuntimeAgentImpl : public protocol::Runtime::Backend {
...@@ -57,51 +57,45 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { ...@@ -57,51 +57,45 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend {
void restore(); void restore();
// Part of the protocol. // Part of the protocol.
void enable(ErrorString*) override; Response enable() override;
void disable(ErrorString*) override; Response disable() override;
void evaluate(const String16& expression, const Maybe<String16>& objectGroup, void evaluate(const String16& expression, Maybe<String16> objectGroup,
const Maybe<bool>& includeCommandLineAPI, Maybe<bool> includeCommandLineAPI, Maybe<bool> silent,
const Maybe<bool>& silent, const Maybe<int>& executionContextId, Maybe<int> executionContextId, Maybe<bool> returnByValue,
const Maybe<bool>& returnByValue, Maybe<bool> generatePreview, Maybe<bool> userGesture,
const Maybe<bool>& generatePreview, Maybe<bool> awaitPromise,
const Maybe<bool>& userGesture, const Maybe<bool>& awaitPromise,
std::unique_ptr<EvaluateCallback>) override; std::unique_ptr<EvaluateCallback>) override;
void awaitPromise(const String16& promiseObjectId, void awaitPromise(const String16& promiseObjectId, Maybe<bool> returnByValue,
const Maybe<bool>& returnByValue, Maybe<bool> generatePreview,
const Maybe<bool>& generatePreview,
std::unique_ptr<AwaitPromiseCallback>) override; std::unique_ptr<AwaitPromiseCallback>) override;
void callFunctionOn( void callFunctionOn(
const String16& objectId, const String16& expression, const String16& objectId, const String16& expression,
const Maybe<protocol::Array<protocol::Runtime::CallArgument>>& Maybe<protocol::Array<protocol::Runtime::CallArgument>> optionalArguments,
optionalArguments, Maybe<bool> silent, Maybe<bool> returnByValue,
const Maybe<bool>& silent, const Maybe<bool>& returnByValue, Maybe<bool> generatePreview, Maybe<bool> userGesture,
const Maybe<bool>& generatePreview, const Maybe<bool>& userGesture, Maybe<bool> awaitPromise,
const Maybe<bool>& awaitPromise,
std::unique_ptr<CallFunctionOnCallback>) override; std::unique_ptr<CallFunctionOnCallback>) override;
void releaseObject(ErrorString*, const String16& objectId) override; Response releaseObject(const String16& objectId) override;
void getProperties( Response getProperties(
ErrorString*, const String16& objectId, const Maybe<bool>& ownProperties, const String16& objectId, Maybe<bool> ownProperties,
const Maybe<bool>& accessorPropertiesOnly, Maybe<bool> accessorPropertiesOnly, Maybe<bool> generatePreview,
const Maybe<bool>& generatePreview,
std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>* std::unique_ptr<protocol::Array<protocol::Runtime::PropertyDescriptor>>*
result, result,
Maybe<protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>* Maybe<protocol::Array<protocol::Runtime::InternalPropertyDescriptor>>*
internalProperties, internalProperties,
Maybe<protocol::Runtime::ExceptionDetails>*) override; Maybe<protocol::Runtime::ExceptionDetails>*) override;
void releaseObjectGroup(ErrorString*, const String16& objectGroup) override; Response releaseObjectGroup(const String16& objectGroup) override;
void runIfWaitingForDebugger(ErrorString*) override; Response runIfWaitingForDebugger() override;
void setCustomObjectFormatterEnabled(ErrorString*, bool) override; Response setCustomObjectFormatterEnabled(bool) override;
void discardConsoleEntries(ErrorString*) override; Response discardConsoleEntries() override;
void compileScript(ErrorString*, const String16& expression, Response compileScript(const String16& expression, const String16& sourceURL,
const String16& sourceURL, bool persistScript, bool persistScript, Maybe<int> executionContextId,
const Maybe<int>& executionContextId, Maybe<String16>*, Maybe<String16>*,
Maybe<protocol::Runtime::ExceptionDetails>*) override; Maybe<protocol::Runtime::ExceptionDetails>*) override;
void runScript(const String16&, const Maybe<int>& executionContextId, void runScript(const String16&, Maybe<int> executionContextId,
const Maybe<String16>& objectGroup, const Maybe<bool>& silent, Maybe<String16> objectGroup, Maybe<bool> silent,
const Maybe<bool>& includeCommandLineAPI, Maybe<bool> includeCommandLineAPI, Maybe<bool> returnByValue,
const Maybe<bool>& returnByValue, Maybe<bool> generatePreview, Maybe<bool> awaitPromise,
const Maybe<bool>& generatePreview,
const Maybe<bool>& awaitPromise,
std::unique_ptr<RunScriptCallback>) override; std::unique_ptr<RunScriptCallback>) override;
void reset(); void reset();
......
...@@ -73,6 +73,96 @@ class V8ValueCopier { ...@@ -73,6 +73,96 @@ class V8ValueCopier {
int m_calls; int m_calls;
}; };
protocol::Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value, int maxDepth,
std::unique_ptr<protocol::Value>* result) {
using protocol::Response;
if (value.IsEmpty()) {
UNREACHABLE();
return Response::InternalError();
}
if (!maxDepth) return Response::Error("Object reference chain is too long");
maxDepth--;
if (value->IsNull() || value->IsUndefined()) {
*result = protocol::Value::null();
return Response::OK();
}
if (value->IsBoolean()) {
*result =
protocol::FundamentalValue::create(value.As<v8::Boolean>()->Value());
return Response::OK();
}
if (value->IsNumber()) {
double doubleValue = value.As<v8::Number>()->Value();
int intValue = static_cast<int>(doubleValue);
if (intValue == doubleValue) {
*result = protocol::FundamentalValue::create(intValue);
return Response::OK();
}
*result = protocol::FundamentalValue::create(doubleValue);
return Response::OK();
}
if (value->IsString()) {
*result =
protocol::StringValue::create(toProtocolString(value.As<v8::String>()));
return Response::OK();
}
if (value->IsArray()) {
v8::Local<v8::Array> array = value.As<v8::Array>();
std::unique_ptr<protocol::ListValue> inspectorArray =
protocol::ListValue::create();
uint32_t length = array->Length();
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> value;
if (!array->Get(context, i).ToLocal(&value))
return Response::InternalError();
std::unique_ptr<protocol::Value> element;
Response response = toProtocolValue(context, value, maxDepth, &element);
if (!response.isSuccess()) return response;
inspectorArray->pushValue(std::move(element));
}
*result = std::move(inspectorArray);
return Response::OK();
}
if (value->IsObject()) {
std::unique_ptr<protocol::DictionaryValue> jsonObject =
protocol::DictionaryValue::create();
v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
v8::Local<v8::Array> propertyNames;
if (!object->GetPropertyNames(context).ToLocal(&propertyNames))
return Response::InternalError();
uint32_t length = propertyNames->Length();
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> name;
if (!propertyNames->Get(context, i).ToLocal(&name))
return Response::InternalError();
// FIXME(yurys): v8::Object should support GetOwnPropertyNames
if (name->IsString()) {
v8::Maybe<bool> hasRealNamedProperty = object->HasRealNamedProperty(
context, v8::Local<v8::String>::Cast(name));
if (!hasRealNamedProperty.IsJust() || !hasRealNamedProperty.FromJust())
continue;
}
v8::Local<v8::String> propertyName;
if (!name->ToString(context).ToLocal(&propertyName)) continue;
v8::Local<v8::Value> property;
if (!object->Get(context, name).ToLocal(&property))
return Response::InternalError();
std::unique_ptr<protocol::Value> propertyValue;
Response response =
toProtocolValue(context, property, maxDepth, &propertyValue);
if (!response.isSuccess()) return response;
jsonObject->setValue(toProtocolString(propertyName),
std::move(propertyValue));
}
*result = std::move(jsonObject);
return Response::OK();
}
return Response::Error("Object couldn't be returned by value");
}
} // namespace } // namespace
v8::MaybeLocal<v8::Value> copyValueFromDebuggerContext( v8::MaybeLocal<v8::Value> copyValueFromDebuggerContext(
...@@ -107,4 +197,10 @@ v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context, ...@@ -107,4 +197,10 @@ v8::Maybe<bool> createDataProperty(v8::Local<v8::Context> context,
return array->CreateDataProperty(context, index, value); return array->CreateDataProperty(context, index, value);
} }
protocol::Response toProtocolValue(v8::Local<v8::Context> context,
v8::Local<v8::Value> value,
std::unique_ptr<protocol::Value>* result) {
return toProtocolValue(context, value, 1000, result);
}
} // namespace v8_inspector } // namespace v8_inspector
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef V8_INSPECTOR_V8VALUECOPIER_H_ #ifndef V8_INSPECTOR_V8VALUECOPIER_H_
#define V8_INSPECTOR_V8VALUECOPIER_H_ #define V8_INSPECTOR_V8VALUECOPIER_H_
#include "src/inspector/protocol/Protocol.h"
#include "include/v8.h" #include "include/v8.h"
namespace v8_inspector { namespace v8_inspector {
...@@ -19,6 +21,9 @@ v8::Maybe<bool> createDataProperty(v8::Local<v8::Context>, ...@@ -19,6 +21,9 @@ v8::Maybe<bool> createDataProperty(v8::Local<v8::Context>,
v8::Maybe<bool> createDataProperty(v8::Local<v8::Context>, v8::Local<v8::Array>, v8::Maybe<bool> createDataProperty(v8::Local<v8::Context>, v8::Local<v8::Array>,
int index, v8::Local<v8::Value>); int index, v8::Local<v8::Value>);
protocol::Response toProtocolValue(v8::Local<v8::Context>, v8::Local<v8::Value>,
std::unique_ptr<protocol::Value>* result);
} // namespace v8_inspector } // namespace v8_inspector
#endif // V8_INSPECTOR_V8VALUECOPIER_H_ #endif // V8_INSPECTOR_V8VALUECOPIER_H_
...@@ -330,7 +330,7 @@ def resolve_type(protocol, prop): ...@@ -330,7 +330,7 @@ def resolve_type(protocol, prop):
def new_style(domain): def new_style(domain):
domains = [ "Schema", "Console", "Profiler", "HeapProfiler" ] domains = [ "Schema", "Console", "Profiler", "HeapProfiler", "Runtime" ]
return domain["domain"] in domains return domain["domain"] in domains
......
...@@ -14,5 +14,5 @@ description. ...@@ -14,5 +14,5 @@ description.
Local modifications: Local modifications:
- This only includes the lib/ and templates/ directories, scripts, build - This only includes the lib/ and templates/ directories, scripts, build
and the LICENSE files. and the LICENSE files.
- New style domains [ "Schema", "Console", "Profiler", "HeapProfiler" ] are - New style domains [ "Schema", "Console", "Profiler", "HeapProfiler",
added in CodeGenerator.py. "Runtime" ] are added in CodeGenerator.py.
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment