14#include "src/inspector/protocol/Protocol.h" 
   31      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Log;
 
   33      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Debug;
 
   35      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Info;
 
   37      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Error;
 
   39      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Warning;
 
   41      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Clear;
 
   43      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Dir;
 
   45      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Dirxml;
 
   47      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Table;
 
   49      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Trace;
 
   51      return protocol::Runtime::ConsoleAPICalled::TypeEnum::StartGroup;
 
   53      return protocol::Runtime::ConsoleAPICalled::TypeEnum::StartGroupCollapsed;
 
   55      return protocol::Runtime::ConsoleAPICalled::TypeEnum::EndGroup;
 
   57      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Assert;
 
   59      return protocol::Runtime::ConsoleAPICalled::TypeEnum::TimeEnd;
 
   61      return protocol::Runtime::ConsoleAPICalled::TypeEnum::Count;
 
   63  return protocol::Runtime::ConsoleAPICalled::TypeEnum::Log;
 
   66const char kGlobalConsoleMessageHandleLabel[] = 
"DevTools console";
 
   67const unsigned maxConsoleMessageCount = 1000;
 
   68const int maxConsoleMessageV8Size = 10 * 1024 * 1024;
 
   69const unsigned maxArrayItemsLimit = 10000;
 
   70const unsigned maxStackDepthLimit = 32;
 
   72class V8ValueStringBuilder {
 
   76    V8ValueStringBuilder builder(context);
 
   77    if (!builder.append(value)) 
return String16();
 
   78    return builder.toString();
 
   84    IgnoreUndefined = 1 << 1,
 
   95    if (value.IsEmpty()) 
return true;
 
   96    if ((ignoreOptions & IgnoreNull) && value->IsNull()) 
return true;
 
   97    if ((ignoreOptions & IgnoreUndefined) && value->IsUndefined()) 
return true;
 
   98    if (value->IsBigIntObject()) {
 
  100    } 
else if (value->IsBooleanObject()) {
 
  103    } 
else if (value->IsNumberObject()) {
 
  106    } 
else if (value->IsStringObject()) {
 
  108    } 
else if (value->IsSymbolObject()) {
 
  111    if (value->IsString()) 
return append(value.As<
v8::String>());
 
  112    if (value->IsBigInt()) 
return append(value.As<
v8::BigInt>());
 
  113    if (value->IsSymbol()) 
return append(value.As<
v8::Symbol>());
 
  114    if (value->IsArray()) 
return append(value.As<
v8::Array>());
 
  115    if (value->IsProxy()) {
 
  119    if (value->IsObject() && !value->IsDate() && !value->IsFunction() &&
 
  120        !value->IsNativeError() && !value->IsRegExp()) {
 
  123      if (object->ObjectProtoToString(m_context).ToLocal(&stringValue))
 
  124        return append(stringValue);
 
  127    if (!value->ToString(m_context).ToLocal(&stringValue)) 
return false;
 
  128    return append(stringValue);
 
  132    for (
const auto& it : m_visitedArrays) {
 
  133      if (it == array) 
return true;
 
  135    uint32_t length = array->Length();
 
  136    if (length > m_arrayLimit) 
return false;
 
  145      if (!array->Get(m_context, 
i).ToLocal(&value)) 
continue;
 
  146      if (!append(value, IgnoreNull | IgnoreUndefined)) {
 
  157    bool result = append(symbol->Description(m_isolate), IgnoreUndefined);
 
  164    if (!bigint->ToString(m_context).ToLocal(&bigint_string)) 
return false;
 
  165    bool result = append(bigint_string);
 
  173    if (!
string.IsEmpty()) {
 
  179  String16 toString() {
 
  197      m_timestamp(timestamp),
 
  205      m_revokedExceptionId(0) {}
 
 
  210                                   unsigned columnNumber,
 
  211                                   std::unique_ptr<V8StackTraceImpl> stackTrace,
 
  213  const char* dataURIPrefix = 
"data:";
 
  214  if (url.
substring(0, strlen(dataURIPrefix)) == dataURIPrefix) {
 
 
  226    protocol::Console::Frontend* frontend)
 const {
 
  228  String16 level = protocol::Console::ConsoleMessage::LevelEnum::Log;
 
  231    level = protocol::Console::ConsoleMessage::LevelEnum::Debug;
 
  234    level = protocol::Console::ConsoleMessage::LevelEnum::Error;
 
  236    level = protocol::Console::ConsoleMessage::LevelEnum::Warning;
 
  238    level = protocol::Console::ConsoleMessage::LevelEnum::Info;
 
  239  std::unique_ptr<protocol::Console::ConsoleMessage> 
result =
 
  240      protocol::Console::ConsoleMessage::create()
 
  241          .setSource(protocol::Console::ConsoleMessage::SourceEnum::ConsoleApi)
 
  248  frontend->messageAdded(std::move(
result));
 
 
  251std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>>
 
  253                                bool generatePreview)
 const {
 
  257  if (
m_arguments.empty() || !contextId) 
return nullptr;
 
  259      inspector->
getContext(contextGroupId, contextId);
 
  260  if (!inspectedContext) 
return nullptr;
 
  267      std::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>();
 
  275      if (secondArgument->IsArray()) {
 
  277      } 
else if (secondArgument->IsString()) {
 
  280        if (array->Set(context, 0, secondArgument).IsJust()) {
 
  285    std::unique_ptr<protocol::Runtime::RemoteObject> wrapped =
 
  287    inspectedContext = inspector->
getContext(contextGroupId, contextId);
 
  288    if (!inspectedContext) 
return nullptr;
 
  290      args->emplace_back(std::move(wrapped));
 
  296      std::unique_ptr<protocol::Runtime::RemoteObject> wrapped =
 
  299      inspectedContext = inspector->
getContext(contextGroupId, contextId);
 
  300      if (!inspectedContext) 
return nullptr;
 
  305      args->emplace_back(std::move(wrapped));
 
 
  313                                        bool generatePreview)
 const {
 
  320    std::unique_ptr<protocol::Runtime::RemoteObject> exception =
 
  323    std::unique_ptr<protocol::Runtime::ExceptionDetails> exceptionDetails =
 
  324        protocol::Runtime::ExceptionDetails::create()
 
  334      exceptionDetails->setStackTrace(
 
  338    if (exception) exceptionDetails->setException(std::move(exception));
 
  339    std::unique_ptr<protocol::DictionaryValue> data =
 
  341    if (data) exceptionDetails->setExceptionMetaData(std::move(data));
 
  342    frontend->exceptionThrown(
m_timestamp, std::move(exceptionDetails));
 
  350    std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>>
 
  355          std::make_unique<protocol::Array<protocol::Runtime::RemoteObject>>();
 
  357        std::unique_ptr<protocol::Runtime::RemoteObject> messageArg =
 
  358            protocol::Runtime::RemoteObject::create()
 
  359                .setType(protocol::Runtime::RemoteObject::TypeEnum::String)
 
  361        messageArg->setValue(protocol::StringValue::create(
m_message));
 
  362        arguments->emplace_back(std::move(messageArg));
 
  365    std::optional<String16> consoleContext;
 
  367    std::unique_ptr<protocol::Runtime::StackTrace> stackTrace;
 
  383    frontend->consoleAPICalled(
 
  385        m_timestamp, std::move(stackTrace), std::move(consoleContext));
 
 
  391std::unique_ptr<protocol::DictionaryValue>
 
  401  if (!maybe_exception.
ToLocal(&exception)) 
return nullptr;
 
 
  406std::unique_ptr<protocol::Runtime::RemoteObject>
 
  408                                bool generatePreview)
 const {
 
  413  if (!inspectedContext) 
return nullptr;
 
 
  433    std::unique_ptr<V8StackTraceImpl> stackTrace) {
 
  436  std::unique_ptr<V8ConsoleMessage> message(
 
  438  if (stackTrace && !stackTrace->isEmpty()) {
 
  439    message->m_url = 
toString16(stackTrace->topSourceURL());
 
  440    message->m_lineNumber = stackTrace->topLineNumber();
 
  441    message->m_columnNumber = stackTrace->topColumnNumber();
 
  443  message->m_stackTrace = std::move(stackTrace);
 
  444  message->m_consoleContext = consoleContext;
 
  445  message->m_type = 
type;
 
  446  message->m_contextId = contextId;
 
  448    std::unique_ptr<v8::Global<v8::Value>> argument(
 
  450    argument->AnnotateStrongRetainer(kGlobalConsoleMessageHandleLabel);
 
  451    message->m_arguments.push_back(std::move(argument));
 
  457      message->m_message += 
String16(
" ");
 
  461    message->m_message += V8ValueStringBuilder::toString(arg, v8Context);
 
  483        message->m_columnNumber, message->m_stackTrace.get());
 
 
  492    unsigned lineNumber, 
unsigned columnNumber,
 
  493    std::unique_ptr<V8StackTraceImpl> stackTrace, 
int scriptId,
 
  496  std::unique_ptr<V8ConsoleMessage> consoleMessage(
 
  498  consoleMessage->setLocation(url, lineNumber, columnNumber,
 
  499                              std::move(stackTrace), scriptId);
 
  500  consoleMessage->m_exceptionId = exceptionId;
 
  501  consoleMessage->m_detailedMessage = detailedMessage;
 
  502  if (contextId && !exception.IsEmpty()) {
 
  503    consoleMessage->m_contextId = contextId;
 
  504    consoleMessage->m_arguments.push_back(
 
  507    consoleMessage->m_v8Size +=
 
  510  return consoleMessage;
 
 
  515    double timestamp, 
const String16& messageText,
 
  516    unsigned revokedExceptionId) {
 
  519  message->m_revokedExceptionId = revokedExceptionId;
 
 
  537    : 
m_inspector(inspector), m_contextGroupId(contextGroupId) {}
 
 
  562    std::unique_ptr<V8ConsoleMessage> message) {
 
  567  TraceV8ConsoleMessageEvent(message->origin(), message->type());
 
  578  if (
m_messages.size() == maxConsoleMessageCount) {
 
  582  while (
m_estimatedSize + message->estimatedSize() > maxConsoleMessageV8Size &&
 
 
  599  for (
auto& data : 
m_data) {
 
  600    data.second.m_counters.clear();
 
  601    data.second.m_reportedDeprecationMessages.clear();
 
 
  607  std::set<String16>& reportedDeprecationMessages =
 
  608      m_data[contextId].m_reportedDeprecationMessages;
 
  609  auto it = reportedDeprecationMessages.find(
method);
 
  610  if (it != reportedDeprecationMessages.end()) 
return false;
 
  611  reportedDeprecationMessages.insert(it, 
method);
 
 
  622  std::map<LabelKey, int>& counters = 
m_data[contextId].m_counters;
 
  624  if (it == counters.end()) 
return false;
 
 
  639                                                       int consoleContextId,
 
  641  auto& timers = 
m_data[contextId].m_timers;
 
  642  auto it = timers.find(std::make_pair(consoleContextId, 
label));
 
  643  if (it == timers.end()) 
return std::nullopt;
 
 
  648                                                       int consoleContextId,
 
  650  auto& timers = 
m_data[contextId].m_timers;
 
  651  auto it = timers.find(std::make_pair(consoleContextId, 
label));
 
  652  if (it == timers.end()) 
return std::nullopt;
 
 
  665    auto it = 
m_data.find(contextId);
 
 
static Local< Array > New(Isolate *isolate, int length=0)
 
static V8_INLINE Local< Boolean > New(Isolate *isolate, bool value)
 
V8_INLINE Local< S > As() const
 
V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local< S > *out) const
 
static Local< Number > New(Isolate *isolate, double value)
 
v8::Local< v8::Context > context() const
 
v8::Isolate * isolate() const
 
String16 substring(size_t pos, size_t len=UINT_MAX) const
 
static String16 fromInteger(int)
 
void messageAdded(V8ConsoleMessage *)
 
bool countReset(int contextId, int consoleContextId, const String16 &id)
 
bool time(int contextId, int consoleContextId, const String16 &label)
 
bool shouldReportDeprecationMessage(int contextId, const String16 &method)
 
int count(int contextId, int consoleContextId, const String16 &id)
 
void contextDestroyed(int contextId)
 
void addMessage(std::unique_ptr< V8ConsoleMessage >)
 
std::optional< double > timeLog(int contextId, int consoleContextId, const String16 &label)
 
V8ConsoleMessageStorage(V8InspectorImpl *, int contextGroupId)
 
std::map< int, PerContextData > m_data
 
std::optional< double > timeEnd(int contextId, int consoleContextId, const String16 &label)
 
std::deque< std::unique_ptr< V8ConsoleMessage > > m_messages
 
V8InspectorImpl * m_inspector
 
~V8ConsoleMessageStorage()
 
std::pair< int, String16 > LabelKey
 
static std::unique_ptr< V8ConsoleMessage > createForConsoleAPI(v8::Local< v8::Context > v8Context, int contextId, int groupId, V8InspectorImpl *inspector, double timestamp, ConsoleAPIType, v8::MemorySpan< const v8::Local< v8::Value > > arguments, const String16 &consoleContext, std::unique_ptr< V8StackTraceImpl >)
 
void contextDestroyed(int contextId)
 
V8MessageOrigin origin() const
 
void reportToFrontend(protocol::Console::Frontend *) const
 
std::unique_ptr< V8StackTraceImpl > m_stackTrace
 
std::unique_ptr< protocol::DictionaryValue > getAssociatedExceptionData(V8InspectorImpl *inspector, V8InspectorSessionImpl *session) const
 
static std::unique_ptr< V8ConsoleMessage > createForRevokedException(double timestamp, const String16 &message, unsigned revokedExceptionId)
 
ConsoleAPIType type() const
 
std::vector< std::unique_ptr< v8::Global< v8::Value > > > Arguments
 
static std::unique_ptr< V8ConsoleMessage > createForException(double timestamp, const String16 &detailedMessage, const String16 &url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr< V8StackTraceImpl >, int scriptId, v8::Isolate *, const String16 &message, int contextId, v8::Local< v8::Value > exception, unsigned exceptionId)
 
std::unique_ptr< protocol::Runtime::RemoteObject > wrapException(V8InspectorSessionImpl *, bool generatePreview) const
 
unsigned m_revokedExceptionId
 
std::unique_ptr< protocol::Array< protocol::Runtime::RemoteObject > > wrapArguments(V8InspectorSessionImpl *, bool generatePreview) const
 
String16 m_consoleContext
 
String16 m_detailedMessage
 
void setLocation(const String16 &url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr< V8StackTraceImpl >, int scriptId)
 
V8ConsoleMessage(V8MessageOrigin, double timestamp, const String16 &message)
 
virtual double currentTimeMS()
 
virtual void consoleAPIMessage(int contextGroupId, v8::Isolate::MessageErrorLevel level, const StringView &message, const StringView &url, unsigned lineNumber, unsigned columnNumber, V8StackTrace *)
 
std::unique_ptr< protocol::DictionaryValue > getAssociatedExceptionDataForProtocol(v8::Local< v8::Value > exception)
 
v8::Isolate * isolate() const
 
InspectedContext * getContext(int groupId, int contextId) const
 
bool hasConsoleMessageStorage(int contextGroupId)
 
V8InspectorClient * client()
 
void forEachSession(int contextGroupId, const std::function< void(V8InspectorSessionImpl *)> &callback)
 
std::unique_ptr< protocol::Runtime::RemoteObject > wrapObject(v8::Local< v8::Context >, v8::Local< v8::Value >, const String16 &groupName, bool generatePreview)
 
void releaseObjectGroup(const String16 &objectGroup)
 
V8InspectorImpl * inspector() const
 
V8ConsoleAgentImpl * consoleAgent()
 
std::unique_ptr< protocol::Runtime::RemoteObject > wrapTable(v8::Local< v8::Context >, v8::Local< v8::Object > table, v8::MaybeLocal< v8::Array > columns)
 
V8RuntimeAgentImpl * runtimeAgent()
 
int contextGroupId() const
 
void messageAdded(V8ConsoleMessage *)
 
base::Vector< const DirectHandle< Object > > args
 
ZoneVector< RpoNumber > & result
 
int EstimatedValueSize(Isolate *v8_isolate, Local< Value > value)
 
String16 toProtocolString(v8::Isolate *isolate, v8::Local< v8::String > value)
 
StringView toStringView(const String16 &string)
 
String16 toString16(const StringView &string)
 
#define DCHECK(condition)
 
#define DCHECK_EQ(v1, v2)
 
#define TRACE_EVENT_INSTANT0(category_group, name, scope)
 
#define TRACE_EVENT_SCOPE_THREAD
 
v8::LocalVector< v8::Array > m_visitedArrays
 
v8::Local< v8::Context > m_context
 
String16Builder m_builder
 
V8InspectorImpl * m_inspector
 
std::unique_ptr< ValueMirror > value