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

[inspector] migrate Runtime to new style

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

Review-Url: https://codereview.chromium.org/2467853003
Cr-Commit-Position: refs/heads/master@{#40744}
parent 5df5a28f
......@@ -259,18 +259,6 @@ InjectedScript.prototype = {
}
},
/**
* @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
......
This diff is collapsed.
......@@ -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,
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;
bool wrapObjectsInArray(ErrorString*, v8::Local<v8::Array>,
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*);
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 resolveCallArgument(protocol::Runtime::CallArgument*,
v8::Local<v8::Value>* result);
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;
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;
if (!scope.injectedScript()
->resolveCallArgument(errorString, newValueArgument.get())
.ToLocal(&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,25 +967,32 @@ 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
->Set(debuggerContext,
......@@ -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,
Response response = unwrapObject(toString16(objectId), object, context,
objectGroup ? &objectGroupString : nullptr);
if (error) *error = StringBufferImpl::adopt(errorString);
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,
Response V8InspectorSessionImpl::unwrapObject(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;
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.
......
This diff is collapsed.
......@@ -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>*,
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&, 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,
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
......
......@@ -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.
\ No newline at end of file
- New style domains [ "Schema", "Console", "Profiler", "HeapProfiler",
"Runtime" ] are added in CodeGenerator.py.
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment