void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) { if (!m_enabled) return; String16 id; String16 resolvedTitle; // Take last started profile if no title was passed. if (title.isEmpty()) { if (m_startedProfiles.empty()) return; id = m_startedProfiles.back().m_id; resolvedTitle = m_startedProfiles.back().m_title; m_startedProfiles.pop_back(); } else { for (size_t i = 0; i < m_startedProfiles.size(); i++) { if (m_startedProfiles[i].m_title == title) { resolvedTitle = title; id = m_startedProfiles[i].m_id; m_startedProfiles.erase(m_startedProfiles.begin() + i); break; } } if (id.isEmpty()) return; } std::unique_ptr<protocol::Profiler::CPUProfile> profile = stopProfiling(id, true); if (!profile) return; std::unique_ptr<protocol::Debugger::Location> location = currentDebugLocation(m_session->debugger()); m_frontend.consoleProfileFinished(id, std::move(location), std::move(profile), resolvedTitle); }
void InjectedScriptNative::releaseObjectGroup(const String16& groupName) { if (groupName.isEmpty()) return; NameToObjectGroup::iterator groupIt = m_nameToObjectGroup.find(groupName); if (groupIt == m_nameToObjectGroup.end()) return; for (int id : *groupIt->second) unbind(id); m_nameToObjectGroup.remove(groupName); }
int V8Regex::match(const String16& string, int startFrom, int* matchLength) const { if (matchLength) *matchLength = 0; if (m_regex.IsEmpty() || string.isEmpty()) return -1; // v8 strings are limited to int. if (string.length() > INT_MAX) return -1; v8::Isolate* isolate = m_debugger->isolate(); v8::HandleScope handleScope(isolate); v8::Local<v8::Context> context = m_debugger->regexContext(); v8::MicrotasksScope microtasks(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); v8::TryCatch tryCatch(isolate); v8::Local<v8::RegExp> regex = m_regex.Get(isolate); v8::Local<v8::Value> exec; if (!regex->Get(context, toV8StringInternalized(isolate, "exec")).ToLocal(&exec)) return -1; v8::Local<v8::Value> argv[] = { toV8String(isolate, string.substring(startFrom)) }; v8::Local<v8::Value> returnValue; if (!exec.As<v8::Function>()->Call(context, regex, WTF_ARRAY_LENGTH(argv), argv).ToLocal(&returnValue)) return -1; // RegExp#exec returns null if there's no match, otherwise it returns an // Array of strings with the first being the whole match string and others // being subgroups. The Array also has some random properties tacked on like // "index" which is the offset of the match. // // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec ASSERT(!returnValue.IsEmpty()); if (!returnValue->IsArray()) return -1; v8::Local<v8::Array> result = returnValue.As<v8::Array>(); v8::Local<v8::Value> matchOffset; if (!result->Get(context, toV8StringInternalized(isolate, "index")).ToLocal(&matchOffset)) return -1; if (matchLength) { v8::Local<v8::Value> match; if (!result->Get(context, 0).ToLocal(&match)) return -1; *matchLength = match.As<v8::String>()->Length(); } return matchOffset.As<v8::Int32>()->Value() + startFrom; }
void InjectedScriptNative::addObjectToGroup(int objectId, const String16& groupName) { if (groupName.isEmpty()) return; if (objectId <= 0) return; m_idToObjectGroupName.set(objectId, groupName); auto it = m_nameToObjectGroup.find(groupName); if (it == m_nameToObjectGroup.end()) { m_nameToObjectGroup.set(groupName, protocol::Vector<int>()); it = m_nameToObjectGroup.find(groupName); } it->second->append(objectId); }
// static std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(double timestampMS, MessageType type, MessageLevel level, const String16& messageText, std::vector<v8::Local<v8::Value>>* arguments, std::unique_ptr<V8StackTrace> stackTrace, InspectedContext* context) { v8::Isolate* isolate = context->isolate(); int contextId = context->contextId(); int contextGroupId = context->contextGroupId(); V8DebuggerImpl* debugger = context->debugger(); String16 url; unsigned lineNumber = 0; unsigned columnNumber = 0; if (stackTrace && !stackTrace->isEmpty()) { url = stackTrace->topSourceURL(); lineNumber = stackTrace->topLineNumber(); columnNumber = stackTrace->topColumnNumber(); } String16 actualMessage = messageText; Arguments messageArguments; if (arguments && arguments->size()) { for (size_t i = 0; i < arguments->size(); ++i) messageArguments.push_back(wrapUnique(new v8::Global<v8::Value>(isolate, arguments->at(i)))); if (actualMessage.isEmpty()) actualMessage = V8ValueStringBuilder::toString(messageArguments.at(0)->Get(isolate), isolate); } std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage(timestampMS, ConsoleAPIMessageSource, level, actualMessage, url, lineNumber, columnNumber, std::move(stackTrace), 0 /* scriptId */, String16() /* requestIdentifier */)); message->m_type = type; if (messageArguments.size()) { message->m_contextId = contextId; message->m_arguments.swap(messageArguments); } debugger->client()->messageAddedToConsole(contextGroupId, message->m_source, message->m_level, message->m_message, message->m_url, message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get()); return message; }
v8::Local<v8::String> toV8StringInternalized(v8::Isolate* isolate, const String16& string) { if (string.isEmpty()) return v8::String::Empty(isolate); return v8::String::NewFromTwoByte(isolate, reinterpret_cast<const uint16_t*>(string.characters16()), v8::NewStringType::kInternalized, string.length()).ToLocalChecked(); }