1bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// Copyright 2016 the V8 project authors. All rights reserved.
2bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// Use of this source code is governed by a BSD-style license that can be
3bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// found in the LICENSE file.
4bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
5bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/v8-stack-trace-impl.h"
6bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
7bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/string-util.h"
8bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/v8-debugger.h"
9bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/v8-inspector-impl.h"
10bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "src/inspector/v8-profiler-agent-impl.h"
11bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
12bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "include/v8-debug.h"
13bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "include/v8-profiler.h"
14bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "include/v8-version.h"
15bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
16bd8388b4555645b3d29abc6a94c303638064d69awonjong.leenamespace v8_inspector {
17bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
18bd8388b4555645b3d29abc6a94c303638064d69awonjong.leenamespace {
19bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
20bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic const v8::StackTrace::StackTraceOptions stackTraceOptions =
21bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    static_cast<v8::StackTrace::StackTraceOptions>(
22bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        v8::StackTrace::kLineNumber | v8::StackTrace::kColumnOffset |
23bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        v8::StackTrace::kScriptId | v8::StackTrace::kScriptNameOrSourceURL |
24bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        v8::StackTrace::kFunctionName);
25bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
26bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame toFrame(v8::Local<v8::StackFrame> frame) {
27bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  String16 scriptId = String16::fromInteger(frame->GetScriptId());
28bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  String16 sourceName;
29bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL());
30bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (!sourceNameValue.IsEmpty())
31bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    sourceName = toProtocolString(sourceNameValue);
32bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
33bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  String16 functionName;
34bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  v8::Local<v8::String> functionNameValue(frame->GetFunctionName());
35bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (!functionNameValue.IsEmpty())
36bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    functionName = toProtocolString(functionNameValue);
37bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
38bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  int sourceLineNumber = frame->GetLineNumber();
39bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  int sourceColumn = frame->GetColumn();
40bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return V8StackTraceImpl::Frame(functionName, scriptId, sourceName,
41bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                                 sourceLineNumber, sourceColumn);
42bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
43bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
44bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid toFramesVector(v8::Local<v8::StackTrace> stackTrace,
45bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    std::vector<V8StackTraceImpl::Frame>& frames,
46bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    size_t maxStackSize, v8::Isolate* isolate) {
47bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  DCHECK(isolate->InContext());
48bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  int frameCount = stackTrace->GetFrameCount();
49bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (frameCount > static_cast<int>(maxStackSize))
50bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    frameCount = static_cast<int>(maxStackSize);
51bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  for (int i = 0; i < frameCount; i++) {
52bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i);
53bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    frames.push_back(toFrame(stackFrame));
54bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  }
55bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
56bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
57bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}  //  namespace
58bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
59bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame::Frame()
60bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    : m_functionName("undefined"),
61bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_scriptId(""),
62bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_scriptName("undefined"),
63bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_lineNumber(0),
64bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_columnNumber(0) {}
65bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
66bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame::Frame(const String16& functionName,
67bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                               const String16& scriptId,
68bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                               const String16& scriptName, int lineNumber,
69bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                               int column)
70bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    : m_functionName(functionName),
71bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_scriptId(scriptId),
72bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_scriptName(scriptName),
73bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_lineNumber(lineNumber),
74bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_columnNumber(column) {
75bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  DCHECK(m_lineNumber != v8::Message::kNoLineNumberInfo);
76bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  DCHECK(m_columnNumber != v8::Message::kNoColumnInfo);
77bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
78bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
79bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame::~Frame() {}
80bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
81bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// buildInspectorObject() and SourceLocation's toTracedValue() should set the
82bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// same fields.
83bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// If either of them is modified, the other should be also modified.
84bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<protocol::Runtime::CallFrame>
85bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame::buildInspectorObject() const {
86bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return protocol::Runtime::CallFrame::create()
87bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      .setFunctionName(m_functionName)
88bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      .setScriptId(m_scriptId)
89bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      .setUrl(m_scriptName)
90bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      .setLineNumber(m_lineNumber - 1)
91bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      .setColumnNumber(m_columnNumber - 1)
92bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      .build();
93bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
94bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
95bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::Frame V8StackTraceImpl::Frame::clone() const {
96bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return Frame(m_functionName, m_scriptId, m_scriptName, m_lineNumber,
97bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee               m_columnNumber);
98bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
99bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
100bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// static
101bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(
102bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    v8::Isolate* isolate, bool capture) {
103bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  isolate->SetCaptureStackTraceForUncaughtExceptions(
104bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      capture, V8StackTraceImpl::maxCallStackSizeToCapture, stackTraceOptions);
105bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
106bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
107bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// static
108bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create(
109bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    V8Debugger* debugger, int contextGroupId,
110bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    v8::Local<v8::StackTrace> stackTrace, size_t maxStackSize,
111bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    const String16& description) {
112bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  v8::Isolate* isolate = v8::Isolate::GetCurrent();
113bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  v8::HandleScope scope(isolate);
114bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  std::vector<V8StackTraceImpl::Frame> frames;
115bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (!stackTrace.IsEmpty())
116bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    toFramesVector(stackTrace, frames, maxStackSize, isolate);
117bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
118bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  int maxAsyncCallChainDepth = 1;
119bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  V8StackTraceImpl* asyncCallChain = nullptr;
120bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (debugger && maxStackSize > 1) {
121bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    asyncCallChain = debugger->currentAsyncCallChain();
122bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    maxAsyncCallChainDepth = debugger->maxAsyncCallChainDepth();
123bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  }
124bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // Do not accidentally append async call chain from another group. This should
125bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // not
126bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // happen if we have proper instrumentation, but let's double-check to be
127bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // safe.
128bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (contextGroupId && asyncCallChain && asyncCallChain->m_contextGroupId &&
129bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      asyncCallChain->m_contextGroupId != contextGroupId) {
130bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    asyncCallChain = nullptr;
131bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    maxAsyncCallChainDepth = 1;
132bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  }
133bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
134bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // Only the top stack in the chain may be empty, so ensure that second stack
135bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // is non-empty (it's the top of appended chain).
136bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (asyncCallChain && asyncCallChain->isEmpty())
137bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    asyncCallChain = asyncCallChain->m_parent.get();
138bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
139bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (stackTrace.IsEmpty() && !asyncCallChain) return nullptr;
140bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
141bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  std::unique_ptr<V8StackTraceImpl> result(new V8StackTraceImpl(
142bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      contextGroupId, description, frames,
143bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      asyncCallChain ? asyncCallChain->cloneImpl() : nullptr));
144bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
145bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // Crop to not exceed maxAsyncCallChainDepth.
146bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  V8StackTraceImpl* deepest = result.get();
147bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  while (deepest && maxAsyncCallChainDepth) {
148bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    deepest = deepest->m_parent.get();
149bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    maxAsyncCallChainDepth--;
150bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  }
151bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (deepest) deepest->m_parent.reset();
152bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
153bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return result;
154bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
155bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
156bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee// static
157bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture(
158bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    V8Debugger* debugger, int contextGroupId, size_t maxStackSize,
159bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    const String16& description) {
160bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  v8::Isolate* isolate = v8::Isolate::GetCurrent();
161bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  v8::HandleScope handleScope(isolate);
162bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  v8::Local<v8::StackTrace> stackTrace;
163bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (isolate->InContext()) {
164bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (debugger) {
165bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      V8InspectorImpl* inspector = debugger->inspector();
166bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      V8ProfilerAgentImpl* profilerAgent =
167bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee          inspector->enabledProfilerAgentForGroup(contextGroupId);
168bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      if (profilerAgent) profilerAgent->collectSample();
169bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    }
170bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace = v8::StackTrace::CurrentStackTrace(
171bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        isolate, static_cast<int>(maxStackSize), stackTraceOptions);
172bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  }
173bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return V8StackTraceImpl::create(debugger, contextGroupId, stackTrace,
174bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                                  maxStackSize, description);
175bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
176bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
177bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::cloneImpl() {
178bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  std::vector<Frame> framesCopy(m_frames);
179bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return wrapUnique(
180bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy,
181bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                           m_parent ? m_parent->cloneImpl() : nullptr));
182bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
183bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
184bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() {
185bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  std::vector<Frame> frames;
186bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  for (size_t i = 0; i < m_frames.size(); i++)
187bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    frames.push_back(m_frames.at(i).clone());
188bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return wrapUnique(
189bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      new V8StackTraceImpl(m_contextGroupId, m_description, frames, nullptr));
190bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
191bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
192bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::V8StackTraceImpl(int contextGroupId,
193bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                                   const String16& description,
194bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                                   std::vector<Frame>& frames,
195bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                                   std::unique_ptr<V8StackTraceImpl> parent)
196bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    : m_contextGroupId(contextGroupId),
197bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_description(description),
198bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      m_parent(std::move(parent)) {
199bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  m_frames.swap(frames);
200bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
201bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
202bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::~V8StackTraceImpl() {}
203bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
204bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeStringView V8StackTraceImpl::topSourceURL() const {
205bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  DCHECK(m_frames.size());
206bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return toStringView(m_frames[0].m_scriptName);
207bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
208bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
209bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeint V8StackTraceImpl::topLineNumber() const {
210bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  DCHECK(m_frames.size());
211bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return m_frames[0].m_lineNumber;
212bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
213bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
214bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeint V8StackTraceImpl::topColumnNumber() const {
215bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  DCHECK(m_frames.size());
216bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return m_frames[0].m_columnNumber;
217bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
218bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
219bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeStringView V8StackTraceImpl::topFunctionName() const {
220bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  DCHECK(m_frames.size());
221bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return toStringView(m_frames[0].m_functionName);
222bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
223bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
224bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeStringView V8StackTraceImpl::topScriptId() const {
225bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  DCHECK(m_frames.size());
226bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return toStringView(m_frames[0].m_scriptId);
227bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
228bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
229bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<protocol::Runtime::StackTrace>
230bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::buildInspectorObjectImpl() const {
231bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  std::unique_ptr<protocol::Array<protocol::Runtime::CallFrame>> frames =
232bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      protocol::Array<protocol::Runtime::CallFrame>::create();
233bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  for (size_t i = 0; i < m_frames.size(); i++)
234bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    frames->addItem(m_frames.at(i).buildInspectorObject());
235bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
236bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  std::unique_ptr<protocol::Runtime::StackTrace> stackTrace =
237bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      protocol::Runtime::StackTrace::create()
238bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee          .setCallFrames(std::move(frames))
239bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee          .build();
240bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (!m_description.isEmpty()) stackTrace->setDescription(m_description);
241bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (m_parent) stackTrace->setParent(m_parent->buildInspectorObjectImpl());
242bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return stackTrace;
243bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
244bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
245bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<protocol::Runtime::StackTrace>
246bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::buildInspectorObjectForTail(V8Debugger* debugger) const {
247bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  v8::HandleScope handleScope(v8::Isolate::GetCurrent());
248bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // Next call collapses possible empty stack and ensures
249bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  // maxAsyncCallChainDepth.
250bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  std::unique_ptr<V8StackTraceImpl> fullChain = V8StackTraceImpl::create(
251bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      debugger, m_contextGroupId, v8::Local<v8::StackTrace>(),
252bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      V8StackTraceImpl::maxCallStackSizeToCapture);
253bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  if (!fullChain || !fullChain->m_parent) return nullptr;
254bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return fullChain->m_parent->buildInspectorObjectImpl();
255bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
256bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
257bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<protocol::Runtime::API::StackTrace>
258bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeV8StackTraceImpl::buildInspectorObject() const {
259bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return buildInspectorObjectImpl();
260bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
261bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
262bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestd::unique_ptr<StringBuffer> V8StackTraceImpl::toString() const {
263bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  String16Builder stackTrace;
264bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  for (size_t i = 0; i < m_frames.size(); ++i) {
265bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    const Frame& frame = m_frames[i];
266bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace.append("\n    at " + (frame.functionName().length()
267bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                                         ? frame.functionName()
268bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                                         : "(anonymous function)"));
269bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace.append(" (");
270bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace.append(frame.sourceURL());
271bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace.append(':');
272bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace.append(String16::fromInteger(frame.lineNumber()));
273bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace.append(':');
274bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace.append(String16::fromInteger(frame.columnNumber()));
275bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    stackTrace.append(')');
276bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  }
277bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  String16 string = stackTrace.toString();
278bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  return StringBufferImpl::adopt(string);
279bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
280bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
281bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}  // namespace v8_inspector
282bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee