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