11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#if defined(V8_OS_STARBOARD) 61cb0ef41Sopenharmony_ci#include "starboard/system.h" 71cb0ef41Sopenharmony_ci#define __builtin_abort SbSystemBreakIntoDebugger 81cb0ef41Sopenharmony_ci#endif 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include "src/inspector/v8-stack-trace-impl.h" 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include <algorithm> 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci#include "../../third_party/inspector_protocol/crdtp/json.h" 151cb0ef41Sopenharmony_ci#include "src/debug/debug-interface.h" 161cb0ef41Sopenharmony_ci#include "src/inspector/v8-debugger.h" 171cb0ef41Sopenharmony_ci#include "src/inspector/v8-inspector-impl.h" 181cb0ef41Sopenharmony_ci#include "src/tracing/trace-event.h" 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ciusing v8_crdtp::SpanFrom; 211cb0ef41Sopenharmony_ciusing v8_crdtp::json::ConvertCBORToJSON; 221cb0ef41Sopenharmony_ciusing v8_crdtp::json::ConvertJSONToCBOR; 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_cinamespace v8_inspector { 251cb0ef41Sopenharmony_cinamespace { 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cistatic const char kId[] = "id"; 281cb0ef41Sopenharmony_cistatic const char kDebuggerId[] = "debuggerId"; 291cb0ef41Sopenharmony_cistatic const char kShouldPause[] = "shouldPause"; 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_cistatic const v8::StackTrace::StackTraceOptions stackTraceOptions = 321cb0ef41Sopenharmony_ci static_cast<v8::StackTrace::StackTraceOptions>( 331cb0ef41Sopenharmony_ci v8::StackTrace::kDetailed | 341cb0ef41Sopenharmony_ci v8::StackTrace::kExposeFramesAcrossSecurityOrigins); 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_cistd::vector<std::shared_ptr<StackFrame>> toFramesVector( 371cb0ef41Sopenharmony_ci V8Debugger* debugger, v8::Local<v8::StackTrace> v8StackTrace, 381cb0ef41Sopenharmony_ci int maxStackSize) { 391cb0ef41Sopenharmony_ci DCHECK(debugger->isolate()->InContext()); 401cb0ef41Sopenharmony_ci int frameCount = std::min(v8StackTrace->GetFrameCount(), maxStackSize); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci TRACE_EVENT1( 431cb0ef41Sopenharmony_ci TRACE_DISABLED_BY_DEFAULT("v8.inspector") "," TRACE_DISABLED_BY_DEFAULT( 441cb0ef41Sopenharmony_ci "v8.stack_trace"), 451cb0ef41Sopenharmony_ci "toFramesVector", "frameCount", frameCount); 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci std::vector<std::shared_ptr<StackFrame>> frames(frameCount); 481cb0ef41Sopenharmony_ci for (int i = 0; i < frameCount; ++i) { 491cb0ef41Sopenharmony_ci frames[i] = 501cb0ef41Sopenharmony_ci debugger->symbolize(v8StackTrace->GetFrame(debugger->isolate(), i)); 511cb0ef41Sopenharmony_ci } 521cb0ef41Sopenharmony_ci return frames; 531cb0ef41Sopenharmony_ci} 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_civoid calculateAsyncChain(V8Debugger* debugger, 561cb0ef41Sopenharmony_ci std::shared_ptr<AsyncStackTrace>* asyncParent, 571cb0ef41Sopenharmony_ci V8StackTraceId* externalParent, int* maxAsyncDepth) { 581cb0ef41Sopenharmony_ci *asyncParent = debugger->currentAsyncParent(); 591cb0ef41Sopenharmony_ci *externalParent = debugger->currentExternalParent(); 601cb0ef41Sopenharmony_ci DCHECK(externalParent->IsInvalid() || !*asyncParent); 611cb0ef41Sopenharmony_ci if (maxAsyncDepth) *maxAsyncDepth = debugger->maxAsyncCallChainDepth(); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci // Only the top stack in the chain may be empty, so ensure that second stack 641cb0ef41Sopenharmony_ci // is non-empty (it's the top of appended chain). 651cb0ef41Sopenharmony_ci if (*asyncParent && (*asyncParent)->isEmpty()) { 661cb0ef41Sopenharmony_ci *asyncParent = (*asyncParent)->parent().lock(); 671cb0ef41Sopenharmony_ci } 681cb0ef41Sopenharmony_ci} 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( 711cb0ef41Sopenharmony_ci V8Debugger* debugger, 721cb0ef41Sopenharmony_ci const std::vector<std::shared_ptr<StackFrame>>& frames, 731cb0ef41Sopenharmony_ci const String16& description, 741cb0ef41Sopenharmony_ci const std::shared_ptr<AsyncStackTrace>& asyncParent, 751cb0ef41Sopenharmony_ci const V8StackTraceId& externalParent, int maxAsyncDepth) { 761cb0ef41Sopenharmony_ci if (asyncParent && frames.empty() && 771cb0ef41Sopenharmony_ci description == asyncParent->description()) { 781cb0ef41Sopenharmony_ci return asyncParent->buildInspectorObject(debugger, maxAsyncDepth); 791cb0ef41Sopenharmony_ci } 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci auto inspectorFrames = 821cb0ef41Sopenharmony_ci std::make_unique<protocol::Array<protocol::Runtime::CallFrame>>(); 831cb0ef41Sopenharmony_ci for (const std::shared_ptr<StackFrame>& frame : frames) { 841cb0ef41Sopenharmony_ci V8InspectorClient* client = nullptr; 851cb0ef41Sopenharmony_ci if (debugger && debugger->inspector()) 861cb0ef41Sopenharmony_ci client = debugger->inspector()->client(); 871cb0ef41Sopenharmony_ci inspectorFrames->emplace_back(frame->buildInspectorObject(client)); 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = 901cb0ef41Sopenharmony_ci protocol::Runtime::StackTrace::create() 911cb0ef41Sopenharmony_ci .setCallFrames(std::move(inspectorFrames)) 921cb0ef41Sopenharmony_ci .build(); 931cb0ef41Sopenharmony_ci if (!description.isEmpty()) stackTrace->setDescription(description); 941cb0ef41Sopenharmony_ci if (asyncParent) { 951cb0ef41Sopenharmony_ci if (maxAsyncDepth > 0) { 961cb0ef41Sopenharmony_ci stackTrace->setParent( 971cb0ef41Sopenharmony_ci asyncParent->buildInspectorObject(debugger, maxAsyncDepth - 1)); 981cb0ef41Sopenharmony_ci } else if (debugger) { 991cb0ef41Sopenharmony_ci stackTrace->setParentId( 1001cb0ef41Sopenharmony_ci protocol::Runtime::StackTraceId::create() 1011cb0ef41Sopenharmony_ci .setId(stackTraceIdToString( 1021cb0ef41Sopenharmony_ci AsyncStackTrace::store(debugger, asyncParent))) 1031cb0ef41Sopenharmony_ci .build()); 1041cb0ef41Sopenharmony_ci } 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci if (!externalParent.IsInvalid()) { 1071cb0ef41Sopenharmony_ci stackTrace->setParentId( 1081cb0ef41Sopenharmony_ci protocol::Runtime::StackTraceId::create() 1091cb0ef41Sopenharmony_ci .setId(stackTraceIdToString(externalParent.id)) 1101cb0ef41Sopenharmony_ci .setDebuggerId( 1111cb0ef41Sopenharmony_ci internal::V8DebuggerId(externalParent.debugger_id).toString()) 1121cb0ef41Sopenharmony_ci .build()); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci return stackTrace; 1151cb0ef41Sopenharmony_ci} 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci} // namespace 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ciV8StackTraceId::V8StackTraceId() 1201cb0ef41Sopenharmony_ci : id(0), debugger_id(internal::V8DebuggerId().pair()) {} 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ciV8StackTraceId::V8StackTraceId(uintptr_t id, 1231cb0ef41Sopenharmony_ci const std::pair<int64_t, int64_t> debugger_id) 1241cb0ef41Sopenharmony_ci : id(id), debugger_id(debugger_id) {} 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ciV8StackTraceId::V8StackTraceId(uintptr_t id, 1271cb0ef41Sopenharmony_ci const std::pair<int64_t, int64_t> debugger_id, 1281cb0ef41Sopenharmony_ci bool should_pause) 1291cb0ef41Sopenharmony_ci : id(id), debugger_id(debugger_id), should_pause(should_pause) {} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciV8StackTraceId::V8StackTraceId(StringView json) 1321cb0ef41Sopenharmony_ci : id(0), debugger_id(internal::V8DebuggerId().pair()) { 1331cb0ef41Sopenharmony_ci if (json.length() == 0) return; 1341cb0ef41Sopenharmony_ci std::vector<uint8_t> cbor; 1351cb0ef41Sopenharmony_ci if (json.is8Bit()) { 1361cb0ef41Sopenharmony_ci ConvertJSONToCBOR( 1371cb0ef41Sopenharmony_ci v8_crdtp::span<uint8_t>(json.characters8(), json.length()), &cbor); 1381cb0ef41Sopenharmony_ci } else { 1391cb0ef41Sopenharmony_ci ConvertJSONToCBOR( 1401cb0ef41Sopenharmony_ci v8_crdtp::span<uint16_t>(json.characters16(), json.length()), &cbor); 1411cb0ef41Sopenharmony_ci } 1421cb0ef41Sopenharmony_ci auto dict = protocol::DictionaryValue::cast( 1431cb0ef41Sopenharmony_ci protocol::Value::parseBinary(cbor.data(), cbor.size())); 1441cb0ef41Sopenharmony_ci if (!dict) return; 1451cb0ef41Sopenharmony_ci String16 s; 1461cb0ef41Sopenharmony_ci if (!dict->getString(kId, &s)) return; 1471cb0ef41Sopenharmony_ci bool isOk = false; 1481cb0ef41Sopenharmony_ci int64_t parsedId = s.toInteger64(&isOk); 1491cb0ef41Sopenharmony_ci if (!isOk || !parsedId) return; 1501cb0ef41Sopenharmony_ci if (!dict->getString(kDebuggerId, &s)) return; 1511cb0ef41Sopenharmony_ci internal::V8DebuggerId debuggerId(s); 1521cb0ef41Sopenharmony_ci if (!debuggerId.isValid()) return; 1531cb0ef41Sopenharmony_ci if (!dict->getBoolean(kShouldPause, &should_pause)) return; 1541cb0ef41Sopenharmony_ci id = parsedId; 1551cb0ef41Sopenharmony_ci debugger_id = debuggerId.pair(); 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_cibool V8StackTraceId::IsInvalid() const { return !id; } 1591cb0ef41Sopenharmony_ci 1601cb0ef41Sopenharmony_cistd::unique_ptr<StringBuffer> V8StackTraceId::ToString() { 1611cb0ef41Sopenharmony_ci if (IsInvalid()) return nullptr; 1621cb0ef41Sopenharmony_ci auto dict = protocol::DictionaryValue::create(); 1631cb0ef41Sopenharmony_ci dict->setString(kId, String16::fromInteger64(id)); 1641cb0ef41Sopenharmony_ci dict->setString(kDebuggerId, internal::V8DebuggerId(debugger_id).toString()); 1651cb0ef41Sopenharmony_ci dict->setBoolean(kShouldPause, should_pause); 1661cb0ef41Sopenharmony_ci std::vector<uint8_t> json; 1671cb0ef41Sopenharmony_ci v8_crdtp::json::ConvertCBORToJSON(v8_crdtp::SpanFrom(dict->Serialize()), 1681cb0ef41Sopenharmony_ci &json); 1691cb0ef41Sopenharmony_ci return StringBufferFrom(std::move(json)); 1701cb0ef41Sopenharmony_ci} 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ciStackFrame::StackFrame(String16&& functionName, int scriptId, 1731cb0ef41Sopenharmony_ci String16&& sourceURL, int lineNumber, int columnNumber, 1741cb0ef41Sopenharmony_ci bool hasSourceURLComment) 1751cb0ef41Sopenharmony_ci : m_functionName(std::move(functionName)), 1761cb0ef41Sopenharmony_ci m_scriptId(scriptId), 1771cb0ef41Sopenharmony_ci m_sourceURL(std::move(sourceURL)), 1781cb0ef41Sopenharmony_ci m_lineNumber(lineNumber), 1791cb0ef41Sopenharmony_ci m_columnNumber(columnNumber), 1801cb0ef41Sopenharmony_ci m_hasSourceURLComment(hasSourceURLComment) { 1811cb0ef41Sopenharmony_ci DCHECK_NE(v8::Message::kNoLineNumberInfo, m_lineNumber + 1); 1821cb0ef41Sopenharmony_ci DCHECK_NE(v8::Message::kNoColumnInfo, m_columnNumber + 1); 1831cb0ef41Sopenharmony_ci} 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ciconst String16& StackFrame::functionName() const { return m_functionName; } 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ciint StackFrame::scriptId() const { return m_scriptId; } 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ciconst String16& StackFrame::sourceURL() const { return m_sourceURL; } 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ciint StackFrame::lineNumber() const { return m_lineNumber; } 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ciint StackFrame::columnNumber() const { return m_columnNumber; } 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Runtime::CallFrame> StackFrame::buildInspectorObject( 1961cb0ef41Sopenharmony_ci V8InspectorClient* client) const { 1971cb0ef41Sopenharmony_ci String16 frameUrl; 1981cb0ef41Sopenharmony_ci const char* dataURIPrefix = "data:"; 1991cb0ef41Sopenharmony_ci if (m_sourceURL.substring(0, strlen(dataURIPrefix)) != dataURIPrefix) { 2001cb0ef41Sopenharmony_ci frameUrl = m_sourceURL; 2011cb0ef41Sopenharmony_ci } 2021cb0ef41Sopenharmony_ci 2031cb0ef41Sopenharmony_ci if (client && !m_hasSourceURLComment && frameUrl.length() > 0) { 2041cb0ef41Sopenharmony_ci std::unique_ptr<StringBuffer> url = 2051cb0ef41Sopenharmony_ci client->resourceNameToUrl(toStringView(m_sourceURL)); 2061cb0ef41Sopenharmony_ci if (url) { 2071cb0ef41Sopenharmony_ci frameUrl = toString16(url->string()); 2081cb0ef41Sopenharmony_ci } 2091cb0ef41Sopenharmony_ci } 2101cb0ef41Sopenharmony_ci return protocol::Runtime::CallFrame::create() 2111cb0ef41Sopenharmony_ci .setFunctionName(m_functionName) 2121cb0ef41Sopenharmony_ci .setScriptId(String16::fromInteger(m_scriptId)) 2131cb0ef41Sopenharmony_ci .setUrl(frameUrl) 2141cb0ef41Sopenharmony_ci .setLineNumber(m_lineNumber) 2151cb0ef41Sopenharmony_ci .setColumnNumber(m_columnNumber) 2161cb0ef41Sopenharmony_ci .build(); 2171cb0ef41Sopenharmony_ci} 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_cibool StackFrame::isEqual(StackFrame* frame) const { 2201cb0ef41Sopenharmony_ci return m_scriptId == frame->m_scriptId && 2211cb0ef41Sopenharmony_ci m_lineNumber == frame->m_lineNumber && 2221cb0ef41Sopenharmony_ci m_columnNumber == frame->m_columnNumber; 2231cb0ef41Sopenharmony_ci} 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci// static 2261cb0ef41Sopenharmony_cistd::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create( 2271cb0ef41Sopenharmony_ci V8Debugger* debugger, v8::Local<v8::StackTrace> v8StackTrace, 2281cb0ef41Sopenharmony_ci int maxStackSize) { 2291cb0ef41Sopenharmony_ci DCHECK(debugger); 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci v8::Isolate* isolate = debugger->isolate(); 2321cb0ef41Sopenharmony_ci v8::HandleScope scope(isolate); 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci std::vector<std::shared_ptr<StackFrame>> frames; 2351cb0ef41Sopenharmony_ci if (!v8StackTrace.IsEmpty() && v8StackTrace->GetFrameCount()) { 2361cb0ef41Sopenharmony_ci frames = toFramesVector(debugger, v8StackTrace, maxStackSize); 2371cb0ef41Sopenharmony_ci } 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci int maxAsyncDepth = 0; 2401cb0ef41Sopenharmony_ci std::shared_ptr<AsyncStackTrace> asyncParent; 2411cb0ef41Sopenharmony_ci V8StackTraceId externalParent; 2421cb0ef41Sopenharmony_ci calculateAsyncChain(debugger, &asyncParent, &externalParent, &maxAsyncDepth); 2431cb0ef41Sopenharmony_ci if (frames.empty() && !asyncParent && externalParent.IsInvalid()) 2441cb0ef41Sopenharmony_ci return nullptr; 2451cb0ef41Sopenharmony_ci return std::unique_ptr<V8StackTraceImpl>(new V8StackTraceImpl( 2461cb0ef41Sopenharmony_ci std::move(frames), maxAsyncDepth, asyncParent, externalParent)); 2471cb0ef41Sopenharmony_ci} 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_ci// static 2501cb0ef41Sopenharmony_cistd::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture( 2511cb0ef41Sopenharmony_ci V8Debugger* debugger, int maxStackSize) { 2521cb0ef41Sopenharmony_ci DCHECK(debugger); 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci TRACE_EVENT1( 2551cb0ef41Sopenharmony_ci TRACE_DISABLED_BY_DEFAULT("v8.inspector") "," TRACE_DISABLED_BY_DEFAULT( 2561cb0ef41Sopenharmony_ci "v8.stack_trace"), 2571cb0ef41Sopenharmony_ci "V8StackTraceImpl::capture", "maxFrameCount", maxStackSize); 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci v8::Isolate* isolate = debugger->isolate(); 2601cb0ef41Sopenharmony_ci v8::HandleScope handleScope(isolate); 2611cb0ef41Sopenharmony_ci v8::Local<v8::StackTrace> v8StackTrace; 2621cb0ef41Sopenharmony_ci if (isolate->InContext()) { 2631cb0ef41Sopenharmony_ci v8StackTrace = v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, 2641cb0ef41Sopenharmony_ci stackTraceOptions); 2651cb0ef41Sopenharmony_ci } 2661cb0ef41Sopenharmony_ci return V8StackTraceImpl::create(debugger, v8StackTrace, maxStackSize); 2671cb0ef41Sopenharmony_ci} 2681cb0ef41Sopenharmony_ci 2691cb0ef41Sopenharmony_ciV8StackTraceImpl::V8StackTraceImpl( 2701cb0ef41Sopenharmony_ci std::vector<std::shared_ptr<StackFrame>> frames, int maxAsyncDepth, 2711cb0ef41Sopenharmony_ci std::shared_ptr<AsyncStackTrace> asyncParent, 2721cb0ef41Sopenharmony_ci const V8StackTraceId& externalParent) 2731cb0ef41Sopenharmony_ci : m_frames(std::move(frames)), 2741cb0ef41Sopenharmony_ci m_maxAsyncDepth(maxAsyncDepth), 2751cb0ef41Sopenharmony_ci m_asyncParent(std::move(asyncParent)), 2761cb0ef41Sopenharmony_ci m_externalParent(externalParent) {} 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ciV8StackTraceImpl::~V8StackTraceImpl() = default; 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_cistd::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() { 2811cb0ef41Sopenharmony_ci return std::unique_ptr<V8StackTrace>(new V8StackTraceImpl( 2821cb0ef41Sopenharmony_ci m_frames, 0, std::shared_ptr<AsyncStackTrace>(), V8StackTraceId())); 2831cb0ef41Sopenharmony_ci} 2841cb0ef41Sopenharmony_ci 2851cb0ef41Sopenharmony_ciStringView V8StackTraceImpl::firstNonEmptySourceURL() const { 2861cb0ef41Sopenharmony_ci StackFrameIterator current(this); 2871cb0ef41Sopenharmony_ci while (!current.done()) { 2881cb0ef41Sopenharmony_ci if (current.frame()->sourceURL().length()) { 2891cb0ef41Sopenharmony_ci return toStringView(current.frame()->sourceURL()); 2901cb0ef41Sopenharmony_ci } 2911cb0ef41Sopenharmony_ci current.next(); 2921cb0ef41Sopenharmony_ci } 2931cb0ef41Sopenharmony_ci return StringView(); 2941cb0ef41Sopenharmony_ci} 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_cibool V8StackTraceImpl::isEmpty() const { return m_frames.empty(); } 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ciStringView V8StackTraceImpl::topSourceURL() const { 2991cb0ef41Sopenharmony_ci return toStringView(m_frames[0]->sourceURL()); 3001cb0ef41Sopenharmony_ci} 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_ciint V8StackTraceImpl::topLineNumber() const { 3031cb0ef41Sopenharmony_ci return m_frames[0]->lineNumber() + 1; 3041cb0ef41Sopenharmony_ci} 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ciint V8StackTraceImpl::topColumnNumber() const { 3071cb0ef41Sopenharmony_ci return m_frames[0]->columnNumber() + 1; 3081cb0ef41Sopenharmony_ci} 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ciint V8StackTraceImpl::topScriptId() const { return m_frames[0]->scriptId(); } 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_ciStringView V8StackTraceImpl::topFunctionName() const { 3131cb0ef41Sopenharmony_ci return toStringView(m_frames[0]->functionName()); 3141cb0ef41Sopenharmony_ci} 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Runtime::StackTrace> 3171cb0ef41Sopenharmony_ciV8StackTraceImpl::buildInspectorObjectImpl(V8Debugger* debugger) const { 3181cb0ef41Sopenharmony_ci return buildInspectorObjectImpl(debugger, m_maxAsyncDepth); 3191cb0ef41Sopenharmony_ci} 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Runtime::StackTrace> 3221cb0ef41Sopenharmony_ciV8StackTraceImpl::buildInspectorObjectImpl(V8Debugger* debugger, 3231cb0ef41Sopenharmony_ci int maxAsyncDepth) const { 3241cb0ef41Sopenharmony_ci return buildInspectorObjectCommon(debugger, m_frames, String16(), 3251cb0ef41Sopenharmony_ci m_asyncParent.lock(), m_externalParent, 3261cb0ef41Sopenharmony_ci maxAsyncDepth); 3271cb0ef41Sopenharmony_ci} 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Runtime::API::StackTrace> 3301cb0ef41Sopenharmony_ciV8StackTraceImpl::buildInspectorObject(int maxAsyncDepth) const { 3311cb0ef41Sopenharmony_ci return buildInspectorObjectImpl(nullptr, 3321cb0ef41Sopenharmony_ci std::min(maxAsyncDepth, m_maxAsyncDepth)); 3331cb0ef41Sopenharmony_ci} 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_cistd::unique_ptr<StringBuffer> V8StackTraceImpl::toString() const { 3361cb0ef41Sopenharmony_ci String16Builder stackTrace; 3371cb0ef41Sopenharmony_ci for (size_t i = 0; i < m_frames.size(); ++i) { 3381cb0ef41Sopenharmony_ci const StackFrame& frame = *m_frames[i]; 3391cb0ef41Sopenharmony_ci stackTrace.append("\n at " + (frame.functionName().length() 3401cb0ef41Sopenharmony_ci ? frame.functionName() 3411cb0ef41Sopenharmony_ci : "(anonymous function)")); 3421cb0ef41Sopenharmony_ci stackTrace.append(" ("); 3431cb0ef41Sopenharmony_ci stackTrace.append(frame.sourceURL()); 3441cb0ef41Sopenharmony_ci stackTrace.append(':'); 3451cb0ef41Sopenharmony_ci stackTrace.append(String16::fromInteger(frame.lineNumber() + 1)); 3461cb0ef41Sopenharmony_ci stackTrace.append(':'); 3471cb0ef41Sopenharmony_ci stackTrace.append(String16::fromInteger(frame.columnNumber() + 1)); 3481cb0ef41Sopenharmony_ci stackTrace.append(')'); 3491cb0ef41Sopenharmony_ci } 3501cb0ef41Sopenharmony_ci return StringBufferFrom(stackTrace.toString()); 3511cb0ef41Sopenharmony_ci} 3521cb0ef41Sopenharmony_ci 3531cb0ef41Sopenharmony_cibool V8StackTraceImpl::isEqualIgnoringTopFrame( 3541cb0ef41Sopenharmony_ci V8StackTraceImpl* stackTrace) const { 3551cb0ef41Sopenharmony_ci StackFrameIterator current(this); 3561cb0ef41Sopenharmony_ci StackFrameIterator target(stackTrace); 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci current.next(); 3591cb0ef41Sopenharmony_ci target.next(); 3601cb0ef41Sopenharmony_ci while (!current.done() && !target.done()) { 3611cb0ef41Sopenharmony_ci if (!current.frame()->isEqual(target.frame())) { 3621cb0ef41Sopenharmony_ci return false; 3631cb0ef41Sopenharmony_ci } 3641cb0ef41Sopenharmony_ci current.next(); 3651cb0ef41Sopenharmony_ci target.next(); 3661cb0ef41Sopenharmony_ci } 3671cb0ef41Sopenharmony_ci return current.done() == target.done(); 3681cb0ef41Sopenharmony_ci} 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ciV8StackTraceImpl::StackFrameIterator::StackFrameIterator( 3711cb0ef41Sopenharmony_ci const V8StackTraceImpl* stackTrace) 3721cb0ef41Sopenharmony_ci : m_currentIt(stackTrace->m_frames.begin()), 3731cb0ef41Sopenharmony_ci m_currentEnd(stackTrace->m_frames.end()), 3741cb0ef41Sopenharmony_ci m_parent(stackTrace->m_asyncParent.lock().get()) {} 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_civoid V8StackTraceImpl::StackFrameIterator::next() { 3771cb0ef41Sopenharmony_ci if (m_currentIt == m_currentEnd) return; 3781cb0ef41Sopenharmony_ci ++m_currentIt; 3791cb0ef41Sopenharmony_ci while (m_currentIt == m_currentEnd && m_parent) { 3801cb0ef41Sopenharmony_ci const std::vector<std::shared_ptr<StackFrame>>& frames = m_parent->frames(); 3811cb0ef41Sopenharmony_ci m_currentIt = frames.begin(); 3821cb0ef41Sopenharmony_ci m_currentEnd = frames.end(); 3831cb0ef41Sopenharmony_ci m_parent = m_parent->parent().lock().get(); 3841cb0ef41Sopenharmony_ci } 3851cb0ef41Sopenharmony_ci} 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_cibool V8StackTraceImpl::StackFrameIterator::done() { 3881cb0ef41Sopenharmony_ci return m_currentIt == m_currentEnd; 3891cb0ef41Sopenharmony_ci} 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ciStackFrame* V8StackTraceImpl::StackFrameIterator::frame() { 3921cb0ef41Sopenharmony_ci return m_currentIt->get(); 3931cb0ef41Sopenharmony_ci} 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ci// static 3961cb0ef41Sopenharmony_cistd::shared_ptr<AsyncStackTrace> AsyncStackTrace::capture( 3971cb0ef41Sopenharmony_ci V8Debugger* debugger, const String16& description, bool skipTopFrame) { 3981cb0ef41Sopenharmony_ci DCHECK(debugger); 3991cb0ef41Sopenharmony_ci 4001cb0ef41Sopenharmony_ci int maxStackSize = debugger->maxCallStackSizeToCapture(); 4011cb0ef41Sopenharmony_ci TRACE_EVENT1( 4021cb0ef41Sopenharmony_ci TRACE_DISABLED_BY_DEFAULT("v8.inspector") "," TRACE_DISABLED_BY_DEFAULT( 4031cb0ef41Sopenharmony_ci "v8.stack_trace"), 4041cb0ef41Sopenharmony_ci "AsyncStackTrace::capture", "maxFrameCount", maxStackSize); 4051cb0ef41Sopenharmony_ci 4061cb0ef41Sopenharmony_ci v8::Isolate* isolate = debugger->isolate(); 4071cb0ef41Sopenharmony_ci v8::HandleScope handleScope(isolate); 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci std::vector<std::shared_ptr<StackFrame>> frames; 4101cb0ef41Sopenharmony_ci if (isolate->InContext()) { 4111cb0ef41Sopenharmony_ci v8::Local<v8::StackTrace> v8StackTrace = v8::StackTrace::CurrentStackTrace( 4121cb0ef41Sopenharmony_ci isolate, maxStackSize, stackTraceOptions); 4131cb0ef41Sopenharmony_ci frames = toFramesVector(debugger, v8StackTrace, maxStackSize); 4141cb0ef41Sopenharmony_ci if (skipTopFrame && !frames.empty()) { 4151cb0ef41Sopenharmony_ci frames.erase(frames.begin()); 4161cb0ef41Sopenharmony_ci } 4171cb0ef41Sopenharmony_ci } 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci std::shared_ptr<AsyncStackTrace> asyncParent; 4201cb0ef41Sopenharmony_ci V8StackTraceId externalParent; 4211cb0ef41Sopenharmony_ci calculateAsyncChain(debugger, &asyncParent, &externalParent, nullptr); 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_ci if (frames.empty() && !asyncParent && externalParent.IsInvalid()) 4241cb0ef41Sopenharmony_ci return nullptr; 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_ci // When async call chain is empty but doesn't contain useful schedule stack 4271cb0ef41Sopenharmony_ci // but doesn't synchronous we can merge them together. e.g. Promise 4281cb0ef41Sopenharmony_ci // ThenableJob. 4291cb0ef41Sopenharmony_ci if (asyncParent && frames.empty() && 4301cb0ef41Sopenharmony_ci (asyncParent->m_description == description || description.isEmpty())) { 4311cb0ef41Sopenharmony_ci return asyncParent; 4321cb0ef41Sopenharmony_ci } 4331cb0ef41Sopenharmony_ci 4341cb0ef41Sopenharmony_ci return std::shared_ptr<AsyncStackTrace>(new AsyncStackTrace( 4351cb0ef41Sopenharmony_ci description, std::move(frames), asyncParent, externalParent)); 4361cb0ef41Sopenharmony_ci} 4371cb0ef41Sopenharmony_ci 4381cb0ef41Sopenharmony_ciAsyncStackTrace::AsyncStackTrace( 4391cb0ef41Sopenharmony_ci const String16& description, 4401cb0ef41Sopenharmony_ci std::vector<std::shared_ptr<StackFrame>> frames, 4411cb0ef41Sopenharmony_ci std::shared_ptr<AsyncStackTrace> asyncParent, 4421cb0ef41Sopenharmony_ci const V8StackTraceId& externalParent) 4431cb0ef41Sopenharmony_ci : m_id(0), 4441cb0ef41Sopenharmony_ci m_description(description), 4451cb0ef41Sopenharmony_ci m_frames(std::move(frames)), 4461cb0ef41Sopenharmony_ci m_asyncParent(std::move(asyncParent)), 4471cb0ef41Sopenharmony_ci m_externalParent(externalParent) {} 4481cb0ef41Sopenharmony_ci 4491cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Runtime::StackTrace> 4501cb0ef41Sopenharmony_ciAsyncStackTrace::buildInspectorObject(V8Debugger* debugger, 4511cb0ef41Sopenharmony_ci int maxAsyncDepth) const { 4521cb0ef41Sopenharmony_ci return buildInspectorObjectCommon(debugger, m_frames, m_description, 4531cb0ef41Sopenharmony_ci m_asyncParent.lock(), m_externalParent, 4541cb0ef41Sopenharmony_ci maxAsyncDepth); 4551cb0ef41Sopenharmony_ci} 4561cb0ef41Sopenharmony_ci 4571cb0ef41Sopenharmony_ciuintptr_t AsyncStackTrace::store(V8Debugger* debugger, 4581cb0ef41Sopenharmony_ci std::shared_ptr<AsyncStackTrace> stack) { 4591cb0ef41Sopenharmony_ci if (stack->m_id) return stack->m_id; 4601cb0ef41Sopenharmony_ci stack->m_id = debugger->storeStackTrace(stack); 4611cb0ef41Sopenharmony_ci return stack->m_id; 4621cb0ef41Sopenharmony_ci} 4631cb0ef41Sopenharmony_ci 4641cb0ef41Sopenharmony_ciconst String16& AsyncStackTrace::description() const { return m_description; } 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_cistd::weak_ptr<AsyncStackTrace> AsyncStackTrace::parent() const { 4671cb0ef41Sopenharmony_ci return m_asyncParent; 4681cb0ef41Sopenharmony_ci} 4691cb0ef41Sopenharmony_ci 4701cb0ef41Sopenharmony_cibool AsyncStackTrace::isEmpty() const { return m_frames.empty(); } 4711cb0ef41Sopenharmony_ci 4721cb0ef41Sopenharmony_ci} // namespace v8_inspector 473