diff options
Diffstat (limited to 'deps/v8/src/inspector')
-rw-r--r-- | deps/v8/src/inspector/DEPS | 1 | ||||
-rw-r--r-- | deps/v8/src/inspector/OWNERS | 2 | ||||
-rw-r--r-- | deps/v8/src/inspector/injected-script.cc | 74 | ||||
-rw-r--r-- | deps/v8/src/inspector/injected-script.h | 6 | ||||
-rw-r--r-- | deps/v8/src/inspector/v8-runtime-agent-impl.cc | 2 | ||||
-rw-r--r-- | deps/v8/src/inspector/value-mirror.cc | 75 |
6 files changed, 103 insertions, 57 deletions
diff --git a/deps/v8/src/inspector/DEPS b/deps/v8/src/inspector/DEPS index e5fa06fd54..f72dcce0a9 100644 --- a/deps/v8/src/inspector/DEPS +++ b/deps/v8/src/inspector/DEPS @@ -6,6 +6,7 @@ include_rules = [ "+src/base/logging.h", "+src/base/macros.h", "+src/base/memory.h", + "+src/base/optional.h", "+src/base/platform/platform.h", "+src/base/platform/mutex.h", "+src/base/safe_conversions.h", diff --git a/deps/v8/src/inspector/OWNERS b/deps/v8/src/inspector/OWNERS index a979205084..92422c0a88 100644 --- a/deps/v8/src/inspector/OWNERS +++ b/deps/v8/src/inspector/OWNERS @@ -5,6 +5,6 @@ kozyatinskiy@chromium.org pfeldman@chromium.org yangguo@chromium.org -per-file PRESUBMIT.py=file://INFRA_OWNERS +per-file PRESUBMIT.py=file:../../INFRA_OWNERS # COMPONENT: Platform>DevTools>JavaScript diff --git a/deps/v8/src/inspector/injected-script.cc b/deps/v8/src/inspector/injected-script.cc index ad91a8e65e..18a10285dd 100644 --- a/deps/v8/src/inspector/injected-script.cc +++ b/deps/v8/src/inspector/injected-script.cc @@ -50,8 +50,8 @@ namespace v8_inspector { namespace { -static const char kGlobalHandleLabel[] = "DevTools console"; -static bool isResolvableNumberLike(String16 query) { +const char kGlobalHandleLabel[] = "DevTools console"; +bool isResolvableNumberLike(String16 query) { return query == "Infinity" || query == "-Infinity" || query == "NaN"; } } // namespace @@ -220,8 +220,13 @@ class InjectedScript::ProtocolPromiseHandler { : 0) .setColumnNumber( stack && !stack->isEmpty() ? stack->topColumnNumber() : 0) - .setException(wrappedValue->clone()) .build(); + response = scope.injectedScript()->addExceptionToDetails( + result, exceptionDetails.get(), m_objectGroup); + if (!response.isSuccess()) { + callback->sendFailure(response); + return; + } if (stack) exceptionDetails->setStackTrace( stack->buildInspectorObjectImpl(m_inspector->debugger())); @@ -289,8 +294,7 @@ Response InjectedScript::getProperties( PropertyAccumulator accumulator(&mirrors); if (!ValueMirror::getProperties(context, object, ownProperties, accessorPropertiesOnly, &accumulator)) { - return createExceptionDetails(tryCatch, groupName, wrapMode, - exceptionDetails); + return createExceptionDetails(tryCatch, groupName, exceptionDetails); } for (const PropertyMirror& mirror : mirrors) { std::unique_ptr<PropertyDescriptor> descriptor = @@ -489,14 +493,18 @@ std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( &limit, &limit, &preview); if (!preview) return nullptr; - std::unordered_set<String16> selectedColumns; + std::vector<String16> selectedColumns; + std::unordered_set<String16> columnSet; v8::Local<v8::Array> v8Columns; if (maybeColumns.ToLocal(&v8Columns)) { for (uint32_t i = 0; i < v8Columns->Length(); ++i) { v8::Local<v8::Value> column; if (v8Columns->Get(context, i).ToLocal(&column) && column->IsString()) { - selectedColumns.insert( - toProtocolString(isolate, column.As<v8::String>())); + String16 name = toProtocolString(isolate, column.As<v8::String>()); + if (columnSet.find(name) == columnSet.end()) { + columnSet.insert(name); + selectedColumns.push_back(name); + } } } } @@ -505,14 +513,18 @@ std::unique_ptr<protocol::Runtime::RemoteObject> InjectedScript::wrapTable( *preview->getProperties()) { ObjectPreview* columnPreview = column->getValuePreview(nullptr); if (!columnPreview) continue; - - auto filtered = v8::base::make_unique<Array<PropertyPreview>>(); + // Use raw pointer here since the lifetime of each PropertyPreview is + // ensured by columnPreview. This saves an additional clone. + std::unordered_map<String16, PropertyPreview*> columnMap; for (const std::unique_ptr<PropertyPreview>& property : *columnPreview->getProperties()) { - if (selectedColumns.find(property->getName()) != - selectedColumns.end()) { - filtered->emplace_back(property->clone()); - } + if (columnSet.find(property->getName()) == columnSet.end()) continue; + columnMap[property->getName()] = property.get(); + } + auto filtered = v8::base::make_unique<Array<PropertyPreview>>(); + for (const String16& column : selectedColumns) { + if (columnMap.find(column) == columnMap.end()) continue; + filtered->push_back(columnMap[column]->clone()); } columnPreview->setProperties(std::move(filtered)); } @@ -632,9 +644,25 @@ Response InjectedScript::resolveCallArgument( return Response::OK(); } +Response InjectedScript::addExceptionToDetails( + v8::Local<v8::Value> exception, + protocol::Runtime::ExceptionDetails* exceptionDetails, + const String16& objectGroup) { + if (exception.IsEmpty()) return Response::OK(); + std::unique_ptr<protocol::Runtime::RemoteObject> wrapped; + Response response = + wrapObject(exception, objectGroup, + exception->IsNativeError() ? WrapMode::kNoPreview + : WrapMode::kWithPreview, + &wrapped); + if (!response.isSuccess()) return response; + exceptionDetails->setException(std::move(wrapped)); + return Response::OK(); +} + Response InjectedScript::createExceptionDetails( const v8::TryCatch& tryCatch, const String16& objectGroup, - WrapMode wrapMode, Maybe<protocol::Runtime::ExceptionDetails>* result) { + 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(); @@ -667,16 +695,9 @@ Response InjectedScript::createExceptionDetails( ->createStackTrace(stackTrace) ->buildInspectorObjectImpl(m_context->inspector()->debugger())); } - if (!exception.IsEmpty()) { - std::unique_ptr<protocol::Runtime::RemoteObject> wrapped; - Response response = - wrapObject(exception, objectGroup, - exception->IsNativeError() ? WrapMode::kNoPreview - : WrapMode::kWithPreview, - &wrapped); - if (!response.isSuccess()) return response; - exceptionDetails->setException(std::move(wrapped)); - } + Response response = + addExceptionToDetails(exception, exceptionDetails.get(), objectGroup); + if (!response.isSuccess()) return response; *result = std::move(exceptionDetails); return Response::OK(); } @@ -709,8 +730,7 @@ Response InjectedScript::wrapEvaluateResult( if (!response.isSuccess()) return response; // We send exception in result for compatibility reasons, even though it's // accessible through exceptionDetails.exception. - response = createExceptionDetails(tryCatch, objectGroup, wrapMode, - exceptionDetails); + response = createExceptionDetails(tryCatch, objectGroup, exceptionDetails); if (!response.isSuccess()) return response; } return Response::OK(); diff --git a/deps/v8/src/inspector/injected-script.h b/deps/v8/src/inspector/injected-script.h index 03c743e1cd..d007e9121e 100644 --- a/deps/v8/src/inspector/injected-script.h +++ b/deps/v8/src/inspector/injected-script.h @@ -117,7 +117,7 @@ class InjectedScript final { v8::Local<v8::Value>* result); Response createExceptionDetails( - const v8::TryCatch&, const String16& groupName, WrapMode wrapMode, + const v8::TryCatch&, const String16& groupName, Maybe<protocol::Runtime::ExceptionDetails>* result); Response wrapEvaluateResult( v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch&, @@ -219,6 +219,10 @@ class InjectedScript final { void discardEvaluateCallbacks(); std::unique_ptr<EvaluateCallback> takeEvaluateCallback( EvaluateCallback* callback); + Response addExceptionToDetails( + v8::Local<v8::Value> exception, + protocol::Runtime::ExceptionDetails* exceptionDetails, + const String16& objectGroup); InspectedContext* m_context; int m_sessionId; diff --git a/deps/v8/src/inspector/v8-runtime-agent-impl.cc b/deps/v8/src/inspector/v8-runtime-agent-impl.cc index fd2d35abd7..a8aee0b7f3 100644 --- a/deps/v8/src/inspector/v8-runtime-agent-impl.cc +++ b/deps/v8/src/inspector/v8-runtime-agent-impl.cc @@ -490,7 +490,7 @@ Response V8RuntimeAgentImpl::compileScript( if (!isOk) { if (scope.tryCatch().HasCaught()) { response = scope.injectedScript()->createExceptionDetails( - scope.tryCatch(), String16(), WrapMode::kNoPreview, exceptionDetails); + scope.tryCatch(), String16(), exceptionDetails); if (!response.isSuccess()) return response; return Response::OK(); } else { diff --git a/deps/v8/src/inspector/value-mirror.cc b/deps/v8/src/inspector/value-mirror.cc index 3ab9085c44..9edfbc1a21 100644 --- a/deps/v8/src/inspector/value-mirror.cc +++ b/deps/v8/src/inspector/value-mirror.cc @@ -7,6 +7,7 @@ #include <algorithm> #include <cmath> +#include "src/base/optional.h" #include "src/debug/debug-interface.h" #include "src/inspector/v8-debugger.h" #include "src/inspector/v8-inspector-impl.h" @@ -199,37 +200,57 @@ String16 descriptionForRegExp(v8::Isolate* isolate, enum class ErrorType { kNative, kClient }; +// Build a description from an exception using the following rules: +// * Usually return the stack trace found in the {stack} property. +// * If the stack trace does not start with the class name of the passed +// exception, try to build a description from the class name, the +// {message} property and the rest of the stack trace. +// (The stack trace is only used if {message} was also found in +// said stack trace). String16 descriptionForError(v8::Local<v8::Context> context, v8::Local<v8::Object> object, ErrorType type) { v8::Isolate* isolate = context->GetIsolate(); v8::TryCatch tryCatch(isolate); String16 className = toProtocolString(isolate, object->GetConstructorName()); - v8::Local<v8::Value> stackValue; - if (!object->Get(context, toV8String(isolate, "stack")) - .ToLocal(&stackValue) || - !stackValue->IsString()) { - return className; - } - String16 stack = toProtocolString(isolate, stackValue.As<v8::String>()); - String16 description = stack; - if (type == ErrorType::kClient) { - if (stack.substring(0, className.length()) != className) { - v8::Local<v8::Value> messageValue; - if (!object->Get(context, toV8String(isolate, "message")) - .ToLocal(&messageValue) || - !messageValue->IsString()) { - return stack; - } - String16 message = toProtocolStringWithTypeCheck(isolate, messageValue); - size_t index = stack.find(message); - String16 stackWithoutMessage = - index != String16::kNotFound - ? stack.substring(index + message.length()) - : String16(); - description = className + ": " + message + stackWithoutMessage; + + v8::base::Optional<String16> stack; + { + v8::Local<v8::Value> stackValue; + if (object->Get(context, toV8String(isolate, "stack")) + .ToLocal(&stackValue) && + stackValue->IsString()) { + stack = toProtocolString(isolate, stackValue.As<v8::String>()); } } - return description; + + if (type == ErrorType::kNative && stack) return *stack; + + if (stack && stack->substring(0, className.length()) == className) { + return *stack; + } + + v8::base::Optional<String16> message; + { + v8::Local<v8::Value> messageValue; + if (object->Get(context, toV8String(isolate, "message")) + .ToLocal(&messageValue) && + messageValue->IsString()) { + String16 msg = toProtocolStringWithTypeCheck(isolate, messageValue); + if (!msg.isEmpty()) message = msg; + } + } + + if (!message) return stack ? *stack : className; + + String16 description = className + ": " + *message; + if (!stack) return description; + + DCHECK(stack && message); + size_t index = stack->find(*message); + String16 stackWithoutMessage = + index != String16::kNotFound ? stack->substring(index + message->length()) + : String16(); + return description + stackWithoutMessage; } String16 descriptionForObject(v8::Isolate* isolate, @@ -1593,13 +1614,13 @@ std::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context, value, RemoteObject::SubtypeEnum::Regexp, descriptionForRegExp(isolate, value.As<v8::RegExp>())); } - if (value->IsFunction()) { - return v8::base::make_unique<FunctionMirror>(value); - } if (value->IsProxy()) { return v8::base::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Proxy, "Proxy"); } + if (value->IsFunction()) { + return v8::base::make_unique<FunctionMirror>(value); + } if (value->IsDate()) { return v8::base::make_unique<ObjectMirror>( value, RemoteObject::SubtypeEnum::Date, |