| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/inspector/v8-stack-trace-impl.h" | 5 #include "src/inspector/v8-stack-trace-impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "src/inspector/v8-debugger.h" | 9 #include "src/inspector/v8-debugger.h" |
| 10 #include "src/inspector/wasm-translation.h" | 10 #include "src/inspector/wasm-translation.h" |
| 11 | 11 |
| 12 namespace v8_inspector { | 12 namespace v8_inspector { |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 static const v8::StackTrace::StackTraceOptions stackTraceOptions = | 16 static const v8::StackTrace::StackTraceOptions stackTraceOptions = |
| 17 static_cast<v8::StackTrace::StackTraceOptions>( | 17 static_cast<v8::StackTrace::StackTraceOptions>( |
| 18 v8::StackTrace::kDetailed | | 18 v8::StackTrace::kDetailed | |
| 19 v8::StackTrace::kExposeFramesAcrossSecurityOrigins); | 19 v8::StackTrace::kExposeFramesAcrossSecurityOrigins); |
| 20 | 20 |
| 21 std::vector<V8StackTraceImpl::Frame> toFramesVector( | 21 std::vector<std::shared_ptr<StackFrame>> toFramesVector( |
| 22 V8Debugger* debugger, v8::Local<v8::StackTrace> v8StackTrace, | 22 V8Debugger* debugger, v8::Local<v8::StackTrace> v8StackTrace, |
| 23 int maxStackSize) { | 23 int maxStackSize) { |
| 24 DCHECK(debugger->isolate()->InContext()); | 24 DCHECK(debugger->isolate()->InContext()); |
| 25 int frameCount = std::min(v8StackTrace->GetFrameCount(), maxStackSize); | 25 int frameCount = std::min(v8StackTrace->GetFrameCount(), maxStackSize); |
| 26 std::vector<V8StackTraceImpl::Frame> frames; | 26 std::vector<std::shared_ptr<StackFrame>> frames; |
| 27 for (int i = 0; i < frameCount; ++i) { | 27 for (int i = 0; i < frameCount; ++i) { |
| 28 v8::Local<v8::StackFrame> v8Frame = v8StackTrace->GetFrame(i); | 28 frames.push_back(debugger->symbolize(v8StackTrace->GetFrame(i))); |
| 29 frames.emplace_back(v8Frame); | |
| 30 // TODO(clemensh): Figure out a way to do this translation only right before | |
| 31 // sending the stack trace over wire. | |
| 32 if (v8Frame->IsWasm()) frames.back().translate(debugger->wasmTranslation()); | |
| 33 } | 29 } |
| 34 return frames; | 30 return frames; |
| 35 } | 31 } |
| 36 | 32 |
| 37 void calculateAsyncChain(V8Debugger* debugger, int contextGroupId, | 33 void calculateAsyncChain(V8Debugger* debugger, int contextGroupId, |
| 38 std::shared_ptr<AsyncStackTrace>* asyncParent, | 34 std::shared_ptr<AsyncStackTrace>* asyncParent, |
| 39 std::shared_ptr<AsyncStackTrace>* asyncCreation, | 35 std::shared_ptr<AsyncStackTrace>* asyncCreation, |
| 40 int* maxAsyncDepth) { | 36 int* maxAsyncDepth) { |
| 41 *asyncParent = debugger->currentAsyncParent(); | 37 *asyncParent = debugger->currentAsyncParent(); |
| 42 *asyncCreation = debugger->currentAsyncCreation(); | 38 *asyncCreation = debugger->currentAsyncCreation(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 59 // Only the top stack in the chain may be empty and doesn't contain creation | 55 // Only the top stack in the chain may be empty and doesn't contain creation |
| 60 // stack, so ensure that second stack is non-empty (it's the top of appended | 56 // stack, so ensure that second stack is non-empty (it's the top of appended |
| 61 // chain). | 57 // chain). |
| 62 if (*asyncParent && !(*asyncCreation) && !(*asyncParent)->creation().lock() && | 58 if (*asyncParent && !(*asyncCreation) && !(*asyncParent)->creation().lock() && |
| 63 (*asyncParent)->isEmpty()) { | 59 (*asyncParent)->isEmpty()) { |
| 64 *asyncParent = (*asyncParent)->parent().lock(); | 60 *asyncParent = (*asyncParent)->parent().lock(); |
| 65 } | 61 } |
| 66 } | 62 } |
| 67 | 63 |
| 68 std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( | 64 std::unique_ptr<protocol::Runtime::StackTrace> buildInspectorObjectCommon( |
| 69 const std::vector<V8StackTraceImpl::Frame>& frames, | 65 const std::vector<std::shared_ptr<StackFrame>>& frames, |
| 70 const std::shared_ptr<AsyncStackTrace>& asyncParent, | 66 const std::shared_ptr<AsyncStackTrace>& asyncParent, |
| 71 const std::shared_ptr<AsyncStackTrace>& asyncCreation, int maxAsyncDepth) { | 67 const std::shared_ptr<AsyncStackTrace>& asyncCreation, int maxAsyncDepth) { |
| 72 std::unique_ptr<protocol::Array<protocol::Runtime::CallFrame>> | 68 std::unique_ptr<protocol::Array<protocol::Runtime::CallFrame>> |
| 73 inspectorFrames = protocol::Array<protocol::Runtime::CallFrame>::create(); | 69 inspectorFrames = protocol::Array<protocol::Runtime::CallFrame>::create(); |
| 74 for (size_t i = 0; i < frames.size(); i++) { | 70 for (size_t i = 0; i < frames.size(); i++) { |
| 75 inspectorFrames->addItem(frames[i].buildInspectorObject()); | 71 inspectorFrames->addItem(frames[i]->buildInspectorObject()); |
| 76 } | 72 } |
| 77 std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = | 73 std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = |
| 78 protocol::Runtime::StackTrace::create() | 74 protocol::Runtime::StackTrace::create() |
| 79 .setCallFrames(std::move(inspectorFrames)) | 75 .setCallFrames(std::move(inspectorFrames)) |
| 80 .build(); | 76 .build(); |
| 81 if (asyncParent && maxAsyncDepth > 0) { | 77 if (asyncParent && maxAsyncDepth > 0) { |
| 82 stackTrace->setParent(asyncParent->buildInspectorObject(asyncCreation.get(), | 78 stackTrace->setParent(asyncParent->buildInspectorObject(asyncCreation.get(), |
| 83 maxAsyncDepth - 1)); | 79 maxAsyncDepth - 1)); |
| 84 } | 80 } |
| 85 return stackTrace; | 81 return stackTrace; |
| 86 } | 82 } |
| 87 | 83 |
| 88 } // namespace | 84 } // namespace |
| 89 | 85 |
| 90 V8StackTraceImpl::Frame::Frame(v8::Local<v8::StackFrame> v8Frame) | 86 StackFrame::StackFrame(v8::Local<v8::StackFrame> v8Frame) |
| 91 : m_functionName(toProtocolString(v8Frame->GetFunctionName())), | 87 : m_functionName(toProtocolString(v8Frame->GetFunctionName())), |
| 92 m_scriptId(String16::fromInteger(v8Frame->GetScriptId())), | 88 m_scriptId(String16::fromInteger(v8Frame->GetScriptId())), |
| 93 m_sourceURL(toProtocolString(v8Frame->GetScriptNameOrSourceURL())), | 89 m_sourceURL(toProtocolString(v8Frame->GetScriptNameOrSourceURL())), |
| 94 m_lineNumber(v8Frame->GetLineNumber() - 1), | 90 m_lineNumber(v8Frame->GetLineNumber() - 1), |
| 95 m_columnNumber(v8Frame->GetColumn() - 1) { | 91 m_columnNumber(v8Frame->GetColumn() - 1) { |
| 96 DCHECK(m_lineNumber + 1 != v8::Message::kNoLineNumberInfo); | 92 DCHECK(m_lineNumber + 1 != v8::Message::kNoLineNumberInfo); |
| 97 DCHECK(m_columnNumber + 1 != v8::Message::kNoColumnInfo); | 93 DCHECK(m_columnNumber + 1 != v8::Message::kNoColumnInfo); |
| 98 } | 94 } |
| 99 | 95 |
| 100 void V8StackTraceImpl::Frame::translate(WasmTranslation* wasmTranslation) { | 96 void StackFrame::translate(WasmTranslation* wasmTranslation) { |
| 101 wasmTranslation->TranslateWasmScriptLocationToProtocolLocation( | 97 wasmTranslation->TranslateWasmScriptLocationToProtocolLocation( |
| 102 &m_scriptId, &m_lineNumber, &m_columnNumber); | 98 &m_scriptId, &m_lineNumber, &m_columnNumber); |
| 103 } | 99 } |
| 104 | 100 |
| 105 const String16& V8StackTraceImpl::Frame::functionName() const { | 101 const String16& StackFrame::functionName() const { return m_functionName; } |
| 106 return m_functionName; | |
| 107 } | |
| 108 | 102 |
| 109 const String16& V8StackTraceImpl::Frame::scriptId() const { return m_scriptId; } | 103 const String16& StackFrame::scriptId() const { return m_scriptId; } |
| 110 | 104 |
| 111 const String16& V8StackTraceImpl::Frame::sourceURL() const { | 105 const String16& StackFrame::sourceURL() const { return m_sourceURL; } |
| 112 return m_sourceURL; | |
| 113 } | |
| 114 | 106 |
| 115 int V8StackTraceImpl::Frame::lineNumber() const { return m_lineNumber; } | 107 int StackFrame::lineNumber() const { return m_lineNumber; } |
| 116 | 108 |
| 117 int V8StackTraceImpl::Frame::columnNumber() const { return m_columnNumber; } | 109 int StackFrame::columnNumber() const { return m_columnNumber; } |
| 118 | 110 |
| 119 std::unique_ptr<protocol::Runtime::CallFrame> | 111 std::unique_ptr<protocol::Runtime::CallFrame> StackFrame::buildInspectorObject() |
| 120 V8StackTraceImpl::Frame::buildInspectorObject() const { | 112 const { |
| 121 return protocol::Runtime::CallFrame::create() | 113 return protocol::Runtime::CallFrame::create() |
| 122 .setFunctionName(m_functionName) | 114 .setFunctionName(m_functionName) |
| 123 .setScriptId(m_scriptId) | 115 .setScriptId(m_scriptId) |
| 124 .setUrl(m_sourceURL) | 116 .setUrl(m_sourceURL) |
| 125 .setLineNumber(m_lineNumber) | 117 .setLineNumber(m_lineNumber) |
| 126 .setColumnNumber(m_columnNumber) | 118 .setColumnNumber(m_columnNumber) |
| 127 .build(); | 119 .build(); |
| 128 } | 120 } |
| 129 | 121 |
| 130 // static | 122 // static |
| 131 void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions( | 123 void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions( |
| 132 v8::Isolate* isolate, bool capture) { | 124 v8::Isolate* isolate, bool capture) { |
| 133 isolate->SetCaptureStackTraceForUncaughtExceptions( | 125 isolate->SetCaptureStackTraceForUncaughtExceptions( |
| 134 capture, V8StackTraceImpl::maxCallStackSizeToCapture); | 126 capture, V8StackTraceImpl::maxCallStackSizeToCapture); |
| 135 } | 127 } |
| 136 | 128 |
| 137 // static | 129 // static |
| 138 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create( | 130 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::create( |
| 139 V8Debugger* debugger, int contextGroupId, | 131 V8Debugger* debugger, int contextGroupId, |
| 140 v8::Local<v8::StackTrace> v8StackTrace, int maxStackSize) { | 132 v8::Local<v8::StackTrace> v8StackTrace, int maxStackSize) { |
| 141 DCHECK(debugger); | 133 DCHECK(debugger); |
| 142 | 134 |
| 143 v8::Isolate* isolate = debugger->isolate(); | 135 v8::Isolate* isolate = debugger->isolate(); |
| 144 v8::HandleScope scope(isolate); | 136 v8::HandleScope scope(isolate); |
| 145 | 137 |
| 146 std::vector<V8StackTraceImpl::Frame> frames; | 138 std::vector<std::shared_ptr<StackFrame>> frames; |
| 147 if (!v8StackTrace.IsEmpty() && v8StackTrace->GetFrameCount()) { | 139 if (!v8StackTrace.IsEmpty() && v8StackTrace->GetFrameCount()) { |
| 148 frames = toFramesVector(debugger, v8StackTrace, maxStackSize); | 140 frames = toFramesVector(debugger, v8StackTrace, maxStackSize); |
| 149 } | 141 } |
| 150 | 142 |
| 151 int maxAsyncDepth = 0; | 143 int maxAsyncDepth = 0; |
| 152 std::shared_ptr<AsyncStackTrace> asyncParent; | 144 std::shared_ptr<AsyncStackTrace> asyncParent; |
| 153 std::shared_ptr<AsyncStackTrace> asyncCreation; | 145 std::shared_ptr<AsyncStackTrace> asyncCreation; |
| 154 calculateAsyncChain(debugger, contextGroupId, &asyncParent, &asyncCreation, | 146 calculateAsyncChain(debugger, contextGroupId, &asyncParent, &asyncCreation, |
| 155 &maxAsyncDepth); | 147 &maxAsyncDepth); |
| 156 if (frames.empty() && !asyncCreation && !asyncParent) return nullptr; | 148 if (frames.empty() && !asyncCreation && !asyncParent) return nullptr; |
| 157 return std::unique_ptr<V8StackTraceImpl>( | 149 return std::unique_ptr<V8StackTraceImpl>(new V8StackTraceImpl( |
| 158 new V8StackTraceImpl(frames, maxAsyncDepth, asyncParent, asyncCreation)); | 150 std::move(frames), maxAsyncDepth, asyncParent, asyncCreation)); |
| 159 } | 151 } |
| 160 | 152 |
| 161 // static | 153 // static |
| 162 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture( | 154 std::unique_ptr<V8StackTraceImpl> V8StackTraceImpl::capture( |
| 163 V8Debugger* debugger, int contextGroupId, int maxStackSize) { | 155 V8Debugger* debugger, int contextGroupId, int maxStackSize) { |
| 164 DCHECK(debugger); | 156 DCHECK(debugger); |
| 165 v8::Isolate* isolate = debugger->isolate(); | 157 v8::Isolate* isolate = debugger->isolate(); |
| 166 v8::HandleScope handleScope(isolate); | 158 v8::HandleScope handleScope(isolate); |
| 167 v8::Local<v8::StackTrace> v8StackTrace; | 159 v8::Local<v8::StackTrace> v8StackTrace; |
| 168 if (isolate->InContext()) { | 160 if (isolate->InContext()) { |
| 169 v8StackTrace = v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, | 161 v8StackTrace = v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, |
| 170 stackTraceOptions); | 162 stackTraceOptions); |
| 171 } | 163 } |
| 172 return V8StackTraceImpl::create(debugger, contextGroupId, v8StackTrace, | 164 return V8StackTraceImpl::create(debugger, contextGroupId, v8StackTrace, |
| 173 maxStackSize); | 165 maxStackSize); |
| 174 } | 166 } |
| 175 | 167 |
| 176 V8StackTraceImpl::V8StackTraceImpl( | 168 V8StackTraceImpl::V8StackTraceImpl( |
| 177 const std::vector<Frame> frames, int maxAsyncDepth, | 169 std::vector<std::shared_ptr<StackFrame>> frames, int maxAsyncDepth, |
| 178 std::shared_ptr<AsyncStackTrace> asyncParent, | 170 std::shared_ptr<AsyncStackTrace> asyncParent, |
| 179 std::shared_ptr<AsyncStackTrace> asyncCreation) | 171 std::shared_ptr<AsyncStackTrace> asyncCreation) |
| 180 : m_frames(frames), | 172 : m_frames(std::move(frames)), |
| 181 m_maxAsyncDepth(maxAsyncDepth), | 173 m_maxAsyncDepth(maxAsyncDepth), |
| 182 m_asyncParent(asyncParent), | 174 m_asyncParent(asyncParent), |
| 183 m_asyncCreation(asyncCreation) {} | 175 m_asyncCreation(asyncCreation) {} |
| 184 | 176 |
| 185 V8StackTraceImpl::~V8StackTraceImpl() {} | 177 V8StackTraceImpl::~V8StackTraceImpl() {} |
| 186 | 178 |
| 187 std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() { | 179 std::unique_ptr<V8StackTrace> V8StackTraceImpl::clone() { |
| 188 return std::unique_ptr<V8StackTrace>( | 180 return std::unique_ptr<V8StackTrace>( |
| 189 new V8StackTraceImpl(m_frames, 0, std::shared_ptr<AsyncStackTrace>(), | 181 new V8StackTraceImpl(m_frames, 0, std::shared_ptr<AsyncStackTrace>(), |
| 190 std::shared_ptr<AsyncStackTrace>())); | 182 std::shared_ptr<AsyncStackTrace>())); |
| 191 } | 183 } |
| 192 | 184 |
| 193 bool V8StackTraceImpl::isEmpty() const { return m_frames.empty(); } | 185 bool V8StackTraceImpl::isEmpty() const { return m_frames.empty(); } |
| 194 | 186 |
| 195 StringView V8StackTraceImpl::topSourceURL() const { | 187 StringView V8StackTraceImpl::topSourceURL() const { |
| 196 return toStringView(m_frames[0].sourceURL()); | 188 return toStringView(m_frames[0]->sourceURL()); |
| 197 } | 189 } |
| 198 | 190 |
| 199 int V8StackTraceImpl::topLineNumber() const { | 191 int V8StackTraceImpl::topLineNumber() const { |
| 200 return m_frames[0].lineNumber() + 1; | 192 return m_frames[0]->lineNumber() + 1; |
| 201 } | 193 } |
| 202 | 194 |
| 203 int V8StackTraceImpl::topColumnNumber() const { | 195 int V8StackTraceImpl::topColumnNumber() const { |
| 204 return m_frames[0].columnNumber() + 1; | 196 return m_frames[0]->columnNumber() + 1; |
| 205 } | 197 } |
| 206 | 198 |
| 207 StringView V8StackTraceImpl::topScriptId() const { | 199 StringView V8StackTraceImpl::topScriptId() const { |
| 208 return toStringView(m_frames[0].scriptId()); | 200 return toStringView(m_frames[0]->scriptId()); |
| 209 } | 201 } |
| 210 | 202 |
| 211 StringView V8StackTraceImpl::topFunctionName() const { | 203 StringView V8StackTraceImpl::topFunctionName() const { |
| 212 return toStringView(m_frames[0].functionName()); | 204 return toStringView(m_frames[0]->functionName()); |
| 213 } | 205 } |
| 214 | 206 |
| 215 std::unique_ptr<protocol::Runtime::StackTrace> | 207 std::unique_ptr<protocol::Runtime::StackTrace> |
| 216 V8StackTraceImpl::buildInspectorObjectImpl() const { | 208 V8StackTraceImpl::buildInspectorObjectImpl() const { |
| 217 return buildInspectorObjectCommon(m_frames, m_asyncParent.lock(), | 209 return buildInspectorObjectCommon(m_frames, m_asyncParent.lock(), |
| 218 m_asyncCreation.lock(), m_maxAsyncDepth); | 210 m_asyncCreation.lock(), m_maxAsyncDepth); |
| 219 } | 211 } |
| 220 | 212 |
| 221 std::unique_ptr<protocol::Runtime::API::StackTrace> | 213 std::unique_ptr<protocol::Runtime::API::StackTrace> |
| 222 V8StackTraceImpl::buildInspectorObject() const { | 214 V8StackTraceImpl::buildInspectorObject() const { |
| 223 return buildInspectorObjectImpl(); | 215 return buildInspectorObjectImpl(); |
| 224 } | 216 } |
| 225 | 217 |
| 226 std::unique_ptr<StringBuffer> V8StackTraceImpl::toString() const { | 218 std::unique_ptr<StringBuffer> V8StackTraceImpl::toString() const { |
| 227 String16Builder stackTrace; | 219 String16Builder stackTrace; |
| 228 for (size_t i = 0; i < m_frames.size(); ++i) { | 220 for (size_t i = 0; i < m_frames.size(); ++i) { |
| 229 const Frame& frame = m_frames[i]; | 221 const StackFrame& frame = *m_frames[i]; |
| 230 stackTrace.append("\n at " + (frame.functionName().length() | 222 stackTrace.append("\n at " + (frame.functionName().length() |
| 231 ? frame.functionName() | 223 ? frame.functionName() |
| 232 : "(anonymous function)")); | 224 : "(anonymous function)")); |
| 233 stackTrace.append(" ("); | 225 stackTrace.append(" ("); |
| 234 stackTrace.append(frame.sourceURL()); | 226 stackTrace.append(frame.sourceURL()); |
| 235 stackTrace.append(':'); | 227 stackTrace.append(':'); |
| 236 stackTrace.append(String16::fromInteger(frame.lineNumber() + 1)); | 228 stackTrace.append(String16::fromInteger(frame.lineNumber() + 1)); |
| 237 stackTrace.append(':'); | 229 stackTrace.append(':'); |
| 238 stackTrace.append(String16::fromInteger(frame.columnNumber() + 1)); | 230 stackTrace.append(String16::fromInteger(frame.columnNumber() + 1)); |
| 239 stackTrace.append(')'); | 231 stackTrace.append(')'); |
| 240 } | 232 } |
| 241 String16 string = stackTrace.toString(); | 233 String16 string = stackTrace.toString(); |
| 242 return StringBufferImpl::adopt(string); | 234 return StringBufferImpl::adopt(string); |
| 243 } | 235 } |
| 244 | 236 |
| 245 // static | 237 // static |
| 246 std::shared_ptr<AsyncStackTrace> AsyncStackTrace::capture( | 238 std::shared_ptr<AsyncStackTrace> AsyncStackTrace::capture( |
| 247 V8Debugger* debugger, int contextGroupId, const String16& description, | 239 V8Debugger* debugger, int contextGroupId, const String16& description, |
| 248 int maxStackSize) { | 240 int maxStackSize) { |
| 249 DCHECK(debugger); | 241 DCHECK(debugger); |
| 250 | 242 |
| 251 v8::Isolate* isolate = debugger->isolate(); | 243 v8::Isolate* isolate = debugger->isolate(); |
| 252 v8::HandleScope handleScope(isolate); | 244 v8::HandleScope handleScope(isolate); |
| 253 | 245 |
| 254 std::vector<V8StackTraceImpl::Frame> frames; | 246 std::vector<std::shared_ptr<StackFrame>> frames; |
| 255 if (isolate->InContext()) { | 247 if (isolate->InContext()) { |
| 256 v8::Local<v8::StackTrace> v8StackTrace = v8::StackTrace::CurrentStackTrace( | 248 v8::Local<v8::StackTrace> v8StackTrace = v8::StackTrace::CurrentStackTrace( |
| 257 isolate, maxStackSize, stackTraceOptions); | 249 isolate, maxStackSize, stackTraceOptions); |
| 258 frames = toFramesVector(debugger, v8StackTrace, maxStackSize); | 250 frames = toFramesVector(debugger, v8StackTrace, maxStackSize); |
| 259 } | 251 } |
| 260 | 252 |
| 261 std::shared_ptr<AsyncStackTrace> asyncParent; | 253 std::shared_ptr<AsyncStackTrace> asyncParent; |
| 262 std::shared_ptr<AsyncStackTrace> asyncCreation; | 254 std::shared_ptr<AsyncStackTrace> asyncCreation; |
| 263 calculateAsyncChain(debugger, contextGroupId, &asyncParent, &asyncCreation, | 255 calculateAsyncChain(debugger, contextGroupId, &asyncParent, &asyncCreation, |
| 264 nullptr); | 256 nullptr); |
| 265 | 257 |
| 266 if (frames.empty() && !asyncCreation && !asyncParent) return nullptr; | 258 if (frames.empty() && !asyncCreation && !asyncParent) return nullptr; |
| 267 | 259 |
| 268 // When async call chain is empty but doesn't contain useful schedule stack | 260 // When async call chain is empty but doesn't contain useful schedule stack |
| 269 // and parent async call chain contains creationg stack but doesn't | 261 // and parent async call chain contains creationg stack but doesn't |
| 270 // synchronous we can merge them together. | 262 // synchronous we can merge them together. |
| 271 // e.g. Promise ThenableJob. | 263 // e.g. Promise ThenableJob. |
| 272 if (asyncParent && frames.empty() && | 264 if (asyncParent && frames.empty() && |
| 273 asyncParent->m_description == description && !asyncCreation) { | 265 asyncParent->m_description == description && !asyncCreation) { |
| 274 return asyncParent; | 266 return asyncParent; |
| 275 } | 267 } |
| 276 | 268 |
| 277 DCHECK(contextGroupId || asyncParent); | 269 DCHECK(contextGroupId || asyncParent); |
| 278 if (!contextGroupId && asyncParent) { | 270 if (!contextGroupId && asyncParent) { |
| 279 contextGroupId = asyncParent->m_contextGroupId; | 271 contextGroupId = asyncParent->m_contextGroupId; |
| 280 } | 272 } |
| 281 return std::shared_ptr<AsyncStackTrace>(new AsyncStackTrace( | 273 return std::shared_ptr<AsyncStackTrace>( |
| 282 contextGroupId, description, frames, asyncParent, asyncCreation)); | 274 new AsyncStackTrace(contextGroupId, description, std::move(frames), |
| 275 asyncParent, asyncCreation)); |
| 283 } | 276 } |
| 284 | 277 |
| 285 AsyncStackTrace::AsyncStackTrace( | 278 AsyncStackTrace::AsyncStackTrace( |
| 286 int contextGroupId, const String16& description, | 279 int contextGroupId, const String16& description, |
| 287 const std::vector<V8StackTraceImpl::Frame>& frames, | 280 std::vector<std::shared_ptr<StackFrame>> frames, |
| 288 std::shared_ptr<AsyncStackTrace> asyncParent, | 281 std::shared_ptr<AsyncStackTrace> asyncParent, |
| 289 std::shared_ptr<AsyncStackTrace> asyncCreation) | 282 std::shared_ptr<AsyncStackTrace> asyncCreation) |
| 290 : m_contextGroupId(contextGroupId), | 283 : m_contextGroupId(contextGroupId), |
| 291 m_description(description), | 284 m_description(description), |
| 292 m_frames(frames), | 285 m_frames(std::move(frames)), |
| 293 m_asyncParent(asyncParent), | 286 m_asyncParent(asyncParent), |
| 294 m_asyncCreation(asyncCreation) { | 287 m_asyncCreation(asyncCreation) { |
| 295 DCHECK(m_contextGroupId); | 288 DCHECK(m_contextGroupId); |
| 296 } | 289 } |
| 297 | 290 |
| 298 std::unique_ptr<protocol::Runtime::StackTrace> | 291 std::unique_ptr<protocol::Runtime::StackTrace> |
| 299 AsyncStackTrace::buildInspectorObject(AsyncStackTrace* asyncCreation, | 292 AsyncStackTrace::buildInspectorObject(AsyncStackTrace* asyncCreation, |
| 300 int maxAsyncDepth) const { | 293 int maxAsyncDepth) const { |
| 301 std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = | 294 std::unique_ptr<protocol::Runtime::StackTrace> stackTrace = |
| 302 buildInspectorObjectCommon(m_frames, m_asyncParent.lock(), | 295 buildInspectorObjectCommon(m_frames, m_asyncParent.lock(), |
| 303 m_asyncCreation.lock(), maxAsyncDepth); | 296 m_asyncCreation.lock(), maxAsyncDepth); |
| 304 if (!m_description.isEmpty()) stackTrace->setDescription(m_description); | 297 if (!m_description.isEmpty()) stackTrace->setDescription(m_description); |
| 305 if (asyncCreation && !asyncCreation->isEmpty()) { | 298 if (asyncCreation && !asyncCreation->isEmpty()) { |
| 306 stackTrace->setPromiseCreationFrame( | 299 stackTrace->setPromiseCreationFrame( |
| 307 asyncCreation->m_frames[0].buildInspectorObject()); | 300 asyncCreation->m_frames[0]->buildInspectorObject()); |
| 308 } | 301 } |
| 309 return stackTrace; | 302 return stackTrace; |
| 310 } | 303 } |
| 311 | 304 |
| 312 int AsyncStackTrace::contextGroupId() const { return m_contextGroupId; } | 305 int AsyncStackTrace::contextGroupId() const { return m_contextGroupId; } |
| 313 | 306 |
| 314 std::weak_ptr<AsyncStackTrace> AsyncStackTrace::parent() const { | 307 std::weak_ptr<AsyncStackTrace> AsyncStackTrace::parent() const { |
| 315 return m_asyncParent; | 308 return m_asyncParent; |
| 316 } | 309 } |
| 317 | 310 |
| 318 std::weak_ptr<AsyncStackTrace> AsyncStackTrace::creation() const { | 311 std::weak_ptr<AsyncStackTrace> AsyncStackTrace::creation() const { |
| 319 return m_asyncCreation; | 312 return m_asyncCreation; |
| 320 } | 313 } |
| 321 | 314 |
| 322 bool AsyncStackTrace::isEmpty() const { return m_frames.empty(); } | 315 bool AsyncStackTrace::isEmpty() const { return m_frames.empty(); } |
| 323 | 316 |
| 324 } // namespace v8_inspector | 317 } // namespace v8_inspector |
| OLD | NEW |