1f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Copyright 2016 the V8 project authors. All rights reserved.
2f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// found in the LICENSE file.
4f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-debugger.h"
6f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
7f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/debugger-script.h"
862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/inspector/inspected-context.h"
9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/protocol/Protocol.h"
10f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/script-breakpoint.h"
11f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/string-util.h"
12f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-debugger-agent-impl.h"
13f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-inspector-impl.h"
14f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-internal-value-type.h"
15f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-stack-trace-impl.h"
16f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-value-copier.h"
17f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
18c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "include/v8-util.h"
19c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
20f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace v8_inspector {
21f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
22f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace {
2362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Based on DevTools frontend measurement, with asyncCallStackDepth = 4,
2562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// average async call stack tail requires ~1 Kb. Let's reserve ~ 128 Mb
2662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// for async stacks.
2762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic const int kMaxAsyncTaskStacks = 128 * 1024;
28f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
29f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochinline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) {
30f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return value ? v8::True(isolate) : v8::False(isolate);
31f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
32f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochV8DebuggerAgentImpl* agentForScript(V8InspectorImpl* inspector,
3462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    v8::Local<v8::debug::Script> script) {
3562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Value> contextData;
3662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) {
3762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return nullptr;
3862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
3962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value());
4062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int contextGroupId = inspector->contextGroupId(contextId);
4162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!contextGroupId) return nullptr;
4262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return inspector->enabledDebuggerAgentForGroup(contextGroupId);
4362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
4562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochv8::MaybeLocal<v8::Array> collectionsEntries(v8::Local<v8::Context> context,
4662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                             v8::Local<v8::Value> value) {
4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Isolate* isolate = context->GetIsolate();
4862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Array> entries;
4962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool isKeyValue = false;
5062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!v8::debug::EntriesPreview(isolate, value, &isKeyValue).ToLocal(&entries))
5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Array>();
5262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
5362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Array> wrappedEntries = v8::Array::New(isolate);
5462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CHECK(!isKeyValue || wrappedEntries->Length() % 2 == 0);
5562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!wrappedEntries->SetPrototype(context, v8::Null(isolate))
5662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           .FromMaybe(false))
5762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Array>();
5862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for (uint32_t i = 0; i < entries->Length(); i += isKeyValue ? 2 : 1) {
5962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Value> item;
6062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!entries->Get(context, i).ToLocal(&item)) continue;
6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Value> value;
6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (isKeyValue && !entries->Get(context, i + 1).ToLocal(&value)) continue;
6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Object> wrapper = v8::Object::New(isolate);
6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!wrapper->SetPrototype(context, v8::Null(isolate)).FromMaybe(false))
6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      continue;
6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    createDataProperty(
6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        context, wrapper,
6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        toV8StringInternalized(isolate, isKeyValue ? "key" : "value"), item);
6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (isKeyValue) {
7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      createDataProperty(context, wrapper,
7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         toV8StringInternalized(isolate, "value"), value);
7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    createDataProperty(context, wrappedEntries, wrappedEntries->Length(),
7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       wrapper);
7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!markArrayEntriesAsInternal(context, wrappedEntries,
7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  V8InternalValueType::kEntry)) {
7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Array>();
7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return wrappedEntries;
8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochv8::MaybeLocal<v8::Object> buildLocation(v8::Local<v8::Context> context,
8462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         int scriptId, int lineNumber,
8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         int columnNumber) {
8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (scriptId == v8::UnboundScript::kNoScriptId)
8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Object>();
8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (lineNumber == v8::Function::kLineOffsetNotFound ||
8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      columnNumber == v8::Function::kLineOffsetNotFound) {
9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Object>();
9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Isolate* isolate = context->GetIsolate();
9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Object> location = v8::Object::New(isolate);
9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!location->SetPrototype(context, v8::Null(isolate)).FromMaybe(false)) {
9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Object>();
9662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!createDataProperty(context, location,
9862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          toV8StringInternalized(isolate, "scriptId"),
9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          toV8String(isolate, String16::fromInteger(scriptId)))
10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           .FromMaybe(false)) {
10162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Object>();
10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!createDataProperty(context, location,
10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          toV8StringInternalized(isolate, "lineNumber"),
10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          v8::Integer::New(isolate, lineNumber))
10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           .FromMaybe(false)) {
10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Object>();
10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
10962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!createDataProperty(context, location,
11062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          toV8StringInternalized(isolate, "columnNumber"),
11162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          v8::Integer::New(isolate, columnNumber))
11262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           .FromMaybe(false)) {
11362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Object>();
11462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
11562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!markAsInternal(context, location, V8InternalValueType::kLocation)) {
11662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Object>();
11762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
11862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return location;
11962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
12062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
12162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochv8::MaybeLocal<v8::Object> generatorObjectLocation(
12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Context> context, v8::Local<v8::Value> value) {
12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!value->IsGeneratorObject()) return v8::MaybeLocal<v8::Object>();
12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::debug::GeneratorObject> generatorObject =
12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      v8::debug::GeneratorObject::Cast(value);
12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!generatorObject->IsSuspended()) {
12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Function> func = generatorObject->Function();
12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return buildLocation(context, func->ScriptId(), func->GetScriptLineNumber(),
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         func->GetScriptColumnNumber());
13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::debug::Script> script;
13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!generatorObject->Script().ToLocal(&script))
13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return v8::MaybeLocal<v8::Object>();
13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::Location suspendedLocation = generatorObject->SuspendedLocation();
13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return buildLocation(context, script->Id(), suspendedLocation.GetLineNumber(),
13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       suspendedLocation.GetColumnNumber());
13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}  // namespace
140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic bool inLiveEditScope = false;
142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochv8::MaybeLocal<v8::Value> V8Debugger::callDebuggerMethod(
14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    const char* functionName, int argc, v8::Local<v8::Value> argv[],
14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool catchExceptions) {
146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::MicrotasksScope microtasks(m_isolate,
147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 v8::MicrotasksScope::kDoNotRunMicrotasks);
148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(m_isolate->InContext());
149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Object> debuggerScript = m_debuggerScript.Get(m_isolate);
151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
152f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      debuggerScript
153f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ->Get(context, toV8StringInternalized(m_isolate, functionName))
154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .ToLocalChecked());
15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (catchExceptions) {
15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::TryCatch try_catch(m_isolate);
15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return function->Call(context, debuggerScript, argc, argv);
15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return function->Call(context, debuggerScript, argc, argv);
160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochV8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector)
163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    : m_isolate(isolate),
164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      m_inspector(inspector),
165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      m_enableCount(0),
166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      m_breakpointsActivated(true),
167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      m_runningNestedMessageLoop(false),
168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      m_ignoreScriptParsedEventsCounter(0),
16962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      m_maxAsyncCallStacks(kMaxAsyncTaskStacks),
17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      m_lastTaskId(0),
171c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      m_maxAsyncCallStackDepth(0),
17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      m_pauseOnExceptionsState(v8::debug::NoBreakOnException),
17362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      m_wasmTranslation(isolate) {}
174f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
175f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochV8Debugger::~V8Debugger() {}
176f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
177f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::enable() {
178f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (m_enableCount++) return;
179f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!enabled());
180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::SetDebugDelegate(m_isolate, this);
18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::SetOutOfMemoryCallback(m_isolate, &V8Debugger::v8OOMCallback,
18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                    this);
18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate));
18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException);
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_pauseOnExceptionsState = v8::debug::NoBreakOnException;
187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  compileDebuggerScript();
188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
190f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::disable() {
191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (--m_enableCount) return;
192f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(enabled());
193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  clearBreakpoints();
194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_debuggerScript.Reset();
195f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_debuggerContext.Reset();
196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  allAsyncTasksCanceled();
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_wasmTranslation.Clear();
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::SetDebugDelegate(m_isolate, nullptr);
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr);
20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_isolate->RestoreOriginalHeapLimit();
201f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
203f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); }
204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
205f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::getCompiledScripts(
206f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int contextGroupId,
207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    std::vector<std::unique_ptr<V8DebuggerScript>>& result) {
208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::PersistentValueVector<v8::debug::Script> scripts(m_isolate);
21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::GetLoadedScripts(m_isolate, scripts);
211c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  for (size_t i = 0; i < scripts.Size(); ++i) {
21262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::debug::Script> script = scripts.Get(i);
213c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (!script->WasCompiled()) continue;
21462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Value> contextData;
21562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32())
21662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      continue;
21762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value());
21862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (m_inspector->contextGroupId(contextId) != contextGroupId) continue;
21962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    result.push_back(V8DebuggerScript::Create(m_isolate, script, false));
220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
222f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochString16 V8Debugger::setBreakpoint(const ScriptBreakpoint& breakpoint,
224f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   int* actualLineNumber,
225f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   int* actualColumnNumber) {
226f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
227f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Context> context = debuggerContext();
228f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Context::Scope contextScope(context);
229f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
230f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Object> info = v8::Object::New(m_isolate);
231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool success = false;
232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  success = info->Set(context, toV8StringInternalized(m_isolate, "sourceID"),
23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      toV8String(m_isolate, breakpoint.script_id))
234f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                .FromMaybe(false);
235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(success);
236f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  success = info->Set(context, toV8StringInternalized(m_isolate, "lineNumber"),
23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      v8::Integer::New(m_isolate, breakpoint.line_number))
238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                .FromMaybe(false);
239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(success);
240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  success =
241f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      info->Set(context, toV8StringInternalized(m_isolate, "columnNumber"),
24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                v8::Integer::New(m_isolate, breakpoint.column_number))
243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .FromMaybe(false);
244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(success);
245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  success = info->Set(context, toV8StringInternalized(m_isolate, "condition"),
24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      toV8String(m_isolate, breakpoint.condition))
247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                .FromMaybe(false);
248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(success);
24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  USE(success);
250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Function> setBreakpointFunction = v8::Local<v8::Function>::Cast(
252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      m_debuggerScript.Get(m_isolate)
253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ->Get(context, toV8StringInternalized(m_isolate, "setBreakpoint"))
254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .ToLocalChecked());
255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Value> breakpointId =
25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      v8::debug::Call(debuggerContext(), setBreakpointFunction, info)
257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .ToLocalChecked();
258f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!breakpointId->IsString()) return "";
259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  *actualLineNumber =
260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      info->Get(context, toV8StringInternalized(m_isolate, "lineNumber"))
261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .ToLocalChecked()
262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ->Int32Value(context)
263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .FromJust();
264f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  *actualColumnNumber =
265f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      info->Get(context, toV8StringInternalized(m_isolate, "columnNumber"))
266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .ToLocalChecked()
267f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ->Int32Value(context)
268f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .FromJust();
269f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return toProtocolString(breakpointId.As<v8::String>());
270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::removeBreakpoint(const String16& breakpointId) {
273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Context> context = debuggerContext();
275f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Context::Scope contextScope(context);
276f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Object> info = v8::Object::New(m_isolate);
278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool success = false;
279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  success =
280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      info->Set(context, toV8StringInternalized(m_isolate, "breakpointId"),
281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                toV8String(m_isolate, breakpointId))
282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .FromMaybe(false);
283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(success);
28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  USE(success);
285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Function> removeBreakpointFunction =
287f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      v8::Local<v8::Function>::Cast(
288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          m_debuggerScript.Get(m_isolate)
289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              ->Get(context,
290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                    toV8StringInternalized(m_isolate, "removeBreakpoint"))
291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              .ToLocalChecked());
29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::Call(debuggerContext(), removeBreakpointFunction, info)
293f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      .ToLocalChecked();
294f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
296f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::clearBreakpoints() {
297f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Context> context = debuggerContext();
299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Context::Scope contextScope(context);
300f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Function> clearBreakpoints = v8::Local<v8::Function>::Cast(
302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      m_debuggerScript.Get(m_isolate)
303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          ->Get(context, toV8StringInternalized(m_isolate, "clearBreakpoints"))
304f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .ToLocalChecked());
30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::Call(debuggerContext(), clearBreakpoints).ToLocalChecked();
306f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::setBreakpointsActivated(bool activated) {
309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!enabled()) {
310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    UNREACHABLE();
311f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return;
312f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::SetBreakPointsActive(m_isolate, activated);
314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_breakpointsActivated = activated;
315f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
316f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochv8::debug::ExceptionBreakState V8Debugger::getPauseOnExceptionsState() {
318f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(enabled());
319c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return m_pauseOnExceptionsState;
320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
322f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::setPauseOnExceptionsState(
32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::debug::ExceptionBreakState pauseOnExceptionsState) {
324f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(enabled());
325c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (m_pauseOnExceptionsState == pauseOnExceptionsState) return;
32662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::ChangeBreakOnException(m_isolate, pauseOnExceptionsState);
327c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  m_pauseOnExceptionsState = pauseOnExceptionsState;
328f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
329f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
330f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::setPauseOnNextStatement(bool pause) {
33162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (isPaused()) return;
332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (pause)
33362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::debug::DebugBreak(m_isolate);
334f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  else
33562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::debug::CancelDebugBreak(m_isolate);
336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool V8Debugger::canBreakProgram() {
339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_breakpointsActivated) return false;
34062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return v8::debug::HasNonBlackboxedFrameOnStack(m_isolate);
341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
342f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
343f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::breakProgram() {
34462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Don't allow nested breaks.
34562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (isPaused()) return;
346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!canBreakProgram()) return;
347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
348f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
349f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Function> breakFunction;
350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!v8::Function::New(m_isolate->GetCurrentContext(),
351f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         &V8Debugger::breakProgramCallback,
352f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         v8::External::New(m_isolate, this), 0,
353f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         v8::ConstructorBehavior::kThrow)
354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           .ToLocal(&breakFunction))
355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return;
35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::Call(debuggerContext(), breakFunction).ToLocalChecked();
357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::continueProgram() {
360f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (isPaused()) m_inspector->client()->quitMessageLoopOnPause();
361f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_pausedContext.Clear();
362f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_executionState.Clear();
363f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
364f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
365f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::stepIntoStatement() {
366f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(isPaused());
367f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!m_executionState.IsEmpty());
36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::PrepareStep(m_isolate, v8::debug::StepIn);
369f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  continueProgram();
370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
372f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::stepOverStatement() {
373f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(isPaused());
374f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!m_executionState.IsEmpty());
37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::PrepareStep(m_isolate, v8::debug::StepNext);
376f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  continueProgram();
377f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
378f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
379f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::stepOutOfFunction() {
380f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(isPaused());
381f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!m_executionState.IsEmpty());
38262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::debug::PrepareStep(m_isolate, v8::debug::StepOut);
383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  continueProgram();
384f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
385f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
386c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8Debugger::setScriptSource(
387f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun,
388f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails,
389c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    JavaScriptCallFrames* newCallFrames, Maybe<bool>* stackChanged,
390c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    bool* compileError) {
391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class EnableLiveEditScope {
392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch   public:
393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate) {
39462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      v8::debug::SetLiveEditEnabled(m_isolate, true);
395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      inLiveEditScope = true;
396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ~EnableLiveEditScope() {
39862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      v8::debug::SetLiveEditEnabled(m_isolate, false);
399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      inLiveEditScope = false;
400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
401f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
402f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch   private:
403f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Isolate* m_isolate;
404f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
405f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
406c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  *compileError = false;
407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(enabled());
408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  std::unique_ptr<v8::Context::Scope> contextScope;
411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!isPaused())
41262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    contextScope.reset(new v8::Context::Scope(debuggerContext()));
413f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
414f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Value> argv[] = {toV8String(m_isolate, sourceID), newSource,
415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 v8Boolean(dryRun, m_isolate)};
416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Value> v8result;
418f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  {
419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    EnableLiveEditScope enableLiveEditScope(m_isolate);
420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::TryCatch tryCatch(m_isolate);
421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    tryCatch.SetVerbose(false);
422f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::MaybeLocal<v8::Value> maybeResult =
42362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        callDebuggerMethod("liveEditScriptSource", 3, argv, false);
424f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (tryCatch.HasCaught()) {
425f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      v8::Local<v8::Message> message = tryCatch.Message();
426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!message.IsEmpty())
427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        return Response::Error(toProtocolStringWithTypeCheck(message->Get()));
428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      else
429c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        return Response::InternalError();
430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8result = maybeResult.ToLocalChecked();
432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!v8result.IsEmpty());
434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Object> resultTuple =
436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      v8result->ToObject(context).ToLocalChecked();
437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int code = static_cast<int>(resultTuple->Get(context, 0)
438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  .ToLocalChecked()
439f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  ->ToInteger(context)
440f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  .ToLocalChecked()
441f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  ->Value());
442f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (code) {
443f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case 0: {
444f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *stackChanged = resultTuple->Get(context, 1)
445f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          .ToLocalChecked()
446f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          ->BooleanValue(context)
447f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          .FromJust();
448f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Call stack may have changed after if the edited function was on the
449f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // stack.
450f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (!dryRun && isPaused()) {
451f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        JavaScriptCallFrames frames = currentCallFrames();
452f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        newCallFrames->swap(frames);
453f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
454c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return Response::OK();
455f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
456f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Compile error.
457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case 1: {
458f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      *exceptionDetails =
459f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          protocol::Runtime::ExceptionDetails::create()
460f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              .setExceptionId(m_inspector->nextExceptionId())
461f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              .setText(toProtocolStringWithTypeCheck(
462f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  resultTuple->Get(context, 2).ToLocalChecked()))
463f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              .setLineNumber(static_cast<int>(resultTuple->Get(context, 3)
464f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                  .ToLocalChecked()
465f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                  ->ToInteger(context)
466f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                  .ToLocalChecked()
467f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                  ->Value()) -
468f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                             1)
469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              .setColumnNumber(static_cast<int>(resultTuple->Get(context, 4)
470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                    .ToLocalChecked()
471f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                    ->ToInteger(context)
472f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                    .ToLocalChecked()
473f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                    ->Value()) -
474f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               1)
475f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              .build();
476c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      *compileError = true;
477c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return Response::OK();
478f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
480c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return Response::InternalError();
481f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
482f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochJavaScriptCallFrames V8Debugger::currentCallFrames(int limit) {
48462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!isPaused()) return JavaScriptCallFrames();
485f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Value> currentCallFramesV8;
48662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Value> argv[] = {m_executionState,
48762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 v8::Integer::New(m_isolate, limit)};
48862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!callDebuggerMethod("currentCallFrames", arraysize(argv), argv, true)
48962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           .ToLocal(&currentCallFramesV8)) {
49062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return JavaScriptCallFrames();
49162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
492f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!currentCallFramesV8->IsArray()) return JavaScriptCallFrames();
493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Array> callFramesArray = currentCallFramesV8.As<v8::Array>();
494f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  JavaScriptCallFrames callFrames;
495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (uint32_t i = 0; i < callFramesArray->Length(); ++i) {
496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Local<v8::Value> callFrameValue;
497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!callFramesArray->Get(debuggerContext(), i).ToLocal(&callFrameValue))
498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return JavaScriptCallFrames();
499f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!callFrameValue->IsObject()) return JavaScriptCallFrames();
500f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Local<v8::Object> callFrameObject = callFrameValue.As<v8::Object>();
501f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    callFrames.push_back(JavaScriptCallFrame::create(
502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        debuggerContext(), v8::Local<v8::Object>::Cast(callFrameObject)));
503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return callFrames;
505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
506f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
507f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic V8Debugger* toV8Debugger(v8::Local<v8::Value> data) {
508f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void* p = v8::Local<v8::External>::Cast(data)->Value();
509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return static_cast<V8Debugger*>(p);
510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
512f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::breakProgramCallback(
513f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    const v8::FunctionCallbackInfo<v8::Value>& info) {
514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_EQ(info.Length(), 2);
515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  V8Debugger* thisPtr = toV8Debugger(info.Data());
516f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!thisPtr->enabled()) return;
517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Context> pausedContext =
518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      thisPtr->m_isolate->GetCurrentContext();
519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Value> exception;
520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Array> hitBreakpoints;
521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  thisPtr->handleProgramBreak(pausedContext,
522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              v8::Local<v8::Object>::Cast(info[0]), exception,
523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              hitBreakpoints);
524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext,
527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    v8::Local<v8::Object> executionState,
528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    v8::Local<v8::Value> exception,
529f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    v8::Local<v8::Array> hitBreakpointNumbers,
530c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                    bool isPromiseRejection, bool isUncaught) {
531f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Don't allow nested breaks.
53262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (isPaused()) return;
533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
53462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(
53562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      m_inspector->contextGroupId(pausedContext));
53662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!agent || (agent->skipAllPauses() && !m_scheduledOOMBreak)) return;
537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  std::vector<String16> breakpointIds;
539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!hitBreakpointNumbers.IsEmpty()) {
540f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    breakpointIds.reserve(hitBreakpointNumbers->Length());
541f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) {
542f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      v8::Local<v8::Value> hitBreakpointNumber =
543f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked();
544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(hitBreakpointNumber->IsInt32());
545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      breakpointIds.push_back(String16::fromInteger(
546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          hitBreakpointNumber->Int32Value(debuggerContext()).FromJust()));
547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
548f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
549f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
550f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_pausedContext = pausedContext;
551f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_executionState = executionState;
55262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_runningNestedMessageLoop = true;
55362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  agent->didPause(InspectedContext::contextId(pausedContext), exception,
55462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  breakpointIds, isPromiseRejection, isUncaught,
55562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  m_scheduledOOMBreak);
55662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int groupId = m_inspector->contextGroupId(pausedContext);
55762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(groupId);
55862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  {
55962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Context::Scope scope(pausedContext);
56062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
56162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CHECK(!context.IsEmpty() &&
56262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          context != v8::debug::GetDebugContext(m_isolate));
563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    m_inspector->client()->runMessageLoopOnPause(groupId);
564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    m_runningNestedMessageLoop = false;
565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
56662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // The agent may have been removed in the nested loop.
56762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  agent = m_inspector->enabledDebuggerAgentForGroup(groupId);
56862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (agent) agent->didContinue();
56962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit();
57062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_scheduledOOMBreak = false;
571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_pausedContext.Clear();
572f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_executionState.Clear();
573f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
574f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
57562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8Debugger::v8OOMCallback(void* data) {
57662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V8Debugger* thisPtr = static_cast<V8Debugger*>(data);
57762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  thisPtr->m_isolate->IncreaseHeapLimitForDebugging();
57862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  thisPtr->m_scheduledOOMBreak = true;
57962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  thisPtr->setPauseOnNextStatement(true);
580f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
581f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
58262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
58362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                bool has_compile_error) {
58462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script);
58562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!agent) return;
58662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (script->IsWasm()) {
58762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent);
58862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (m_ignoreScriptParsedEventsCounter == 0) {
58962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    agent->didParseSource(
59062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        V8DebuggerScript::Create(m_isolate, script, inLiveEditScope),
59162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        !has_compile_error);
59262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
593f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
594f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
59562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8Debugger::BreakProgramRequested(v8::Local<v8::Context> pausedContext,
59662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       v8::Local<v8::Object> execState,
59762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                       v8::Local<v8::Value> breakPointsHit) {
59862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Value> argv[] = {breakPointsHit};
59962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Value> hitBreakpoints;
60062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!callDebuggerMethod("getBreakpointNumbers", 1, argv, true)
60162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch           .ToLocal(&hitBreakpoints)) {
602f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return;
603f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
60462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DCHECK(hitBreakpoints->IsArray());
60562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  handleProgramBreak(pausedContext, execState, v8::Local<v8::Value>(),
60662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                     hitBreakpoints.As<v8::Array>());
60762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
60962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext,
61062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 v8::Local<v8::Object> execState,
61162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 v8::Local<v8::Value> exception,
61262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 v8::Local<v8::Value> promise,
61362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 bool isUncaught) {
61462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool isPromiseRejection = promise->IsPromise();
61562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  handleProgramBreak(pausedContext, execState, exception,
61662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                     v8::Local<v8::Array>(), isPromiseRejection, isUncaught);
617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
618f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
61962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
62062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      const v8::debug::Location& start,
62162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      const v8::debug::Location& end) {
62262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script);
62362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!agent) return false;
62462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start,
62562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     end);
62662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
627f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
62862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type,
62962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      int id, int parentId) {
63062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!m_maxAsyncCallStackDepth) return;
631f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Async task events from Promises are given misaligned pointers to prevent
632f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // from overlapping with other Blink task identifiers. There is a single
633f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // namespace of such ids, managed by src/js/promise.js.
634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void* ptr = reinterpret_cast<void*>(id * 2 + 1);
63562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (type) {
63662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case v8::debug::kDebugPromiseCreated:
63762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      asyncTaskCreated(
63862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          ptr, parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr);
63962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
64062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case v8::debug::kDebugEnqueueAsyncFunction:
64162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      asyncTaskScheduled("async function", ptr, true);
64262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
64362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case v8::debug::kDebugEnqueuePromiseResolve:
64462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      asyncTaskScheduled("Promise.resolve", ptr, true);
64562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
64662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case v8::debug::kDebugEnqueuePromiseReject:
64762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      asyncTaskScheduled("Promise.reject", ptr, true);
64862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
64962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case v8::debug::kDebugPromiseCollected:
65062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      asyncTaskCanceled(ptr);
65162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
65262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case v8::debug::kDebugWillHandle:
65362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      asyncTaskStarted(ptr);
65462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
65562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case v8::debug::kDebugDidHandle:
65662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      asyncTaskFinished(ptr);
65762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
65862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
661f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochV8StackTraceImpl* V8Debugger::currentAsyncCallChain() {
662f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_currentStacks.size()) return nullptr;
663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return m_currentStacks.back().get();
664f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
666f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::compileDebuggerScript() {
667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_debuggerScript.IsEmpty()) {
668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    UNREACHABLE();
669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return;
670f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
673f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Context::Scope contextScope(debuggerContext());
674f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
675f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::String> scriptValue =
676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      v8::String::NewFromUtf8(m_isolate, DebuggerScript_js,
677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              v8::NewStringType::kInternalized,
678f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              sizeof(DebuggerScript_js))
679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          .ToLocalChecked();
680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Value> value;
681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_inspector->compileAndRunInternalScript(debuggerContext(), scriptValue)
682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           .ToLocal(&value)) {
683f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    UNREACHABLE();
684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return;
685f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(value->IsObject());
687f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_debuggerScript.Reset(m_isolate, value.As<v8::Object>());
688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
689f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
690f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochv8::Local<v8::Context> V8Debugger::debuggerContext() const {
691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(!m_debuggerContext.IsEmpty());
692f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return m_debuggerContext.Get(m_isolate);
693f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
69562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochv8::MaybeLocal<v8::Value> V8Debugger::getTargetScopes(
69662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Context> context, v8::Local<v8::Value> value,
69762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ScopeTargetKind kind) {
698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!enabled()) {
699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    UNREACHABLE();
700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return v8::Local<v8::Value>::New(m_isolate, v8::Undefined(m_isolate));
701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
70262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Value> argv[] = {value};
703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Value> scopesValue;
70462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
70562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const char* debuggerMethod = nullptr;
70662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (kind) {
70762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case FUNCTION:
70862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      debuggerMethod = "getFunctionScopes";
70962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
71062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case GENERATOR:
71162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      debuggerMethod = "getGeneratorScopes";
71262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
71362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
71462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
71562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!callDebuggerMethod(debuggerMethod, 1, argv, true).ToLocal(&scopesValue))
716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return v8::MaybeLocal<v8::Value>();
717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Value> copied;
718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!copyValueFromDebuggerContext(m_isolate, debuggerContext(), context,
719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    scopesValue)
720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch           .ToLocal(&copied) ||
721f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      !copied->IsArray())
722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return v8::MaybeLocal<v8::Value>();
723f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!markAsInternal(context, v8::Local<v8::Array>::Cast(copied),
724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                      V8InternalValueType::kScopeList))
725f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return v8::MaybeLocal<v8::Value>();
726f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!markArrayEntriesAsInternal(context, v8::Local<v8::Array>::Cast(copied),
727f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  V8InternalValueType::kScope))
728f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return v8::MaybeLocal<v8::Value>();
729f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return copied;
730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
73262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochv8::MaybeLocal<v8::Value> V8Debugger::functionScopes(
73362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Context> context, v8::Local<v8::Function> function) {
73462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return getTargetScopes(context, function, FUNCTION);
73562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
73662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
73762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochv8::MaybeLocal<v8::Value> V8Debugger::generatorScopes(
73862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Context> context, v8::Local<v8::Value> generator) {
73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return getTargetScopes(context, generator, GENERATOR);
74062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
74162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochv8::MaybeLocal<v8::Array> V8Debugger::internalProperties(
743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Local<v8::Context> context, v8::Local<v8::Value> value) {
744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::Local<v8::Array> properties;
74562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!v8::debug::GetInternalProperties(m_isolate, value).ToLocal(&properties))
746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return v8::MaybeLocal<v8::Array>();
747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (value->IsFunction()) {
748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Local<v8::Function> function = value.As<v8::Function>();
74962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Object> location;
75062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (buildLocation(context, function->ScriptId(),
75162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      function->GetScriptLineNumber(),
75262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      function->GetScriptColumnNumber())
75362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            .ToLocal(&location)) {
754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      createDataProperty(
755f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          context, properties, properties->Length(),
756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          toV8StringInternalized(m_isolate, "[[FunctionLocation]]"));
757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      createDataProperty(context, properties, properties->Length(), location);
758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (function->IsGeneratorFunction()) {
760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      createDataProperty(context, properties, properties->Length(),
761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         toV8StringInternalized(m_isolate, "[[IsGenerator]]"));
762f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      createDataProperty(context, properties, properties->Length(),
763f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         v8::True(m_isolate));
764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
76662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::Local<v8::Array> entries;
76762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (collectionsEntries(context, value).ToLocal(&entries)) {
76862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    createDataProperty(context, properties, properties->Length(),
76962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                       toV8StringInternalized(m_isolate, "[[Entries]]"));
77062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    createDataProperty(context, properties, properties->Length(), entries);
771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
772f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (value->IsGeneratorObject()) {
77362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Object> location;
77462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (generatorObjectLocation(context, value).ToLocal(&location)) {
775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      createDataProperty(
776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          context, properties, properties->Length(),
777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          toV8StringInternalized(m_isolate, "[[GeneratorLocation]]"));
778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      createDataProperty(context, properties, properties->Length(), location);
779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
78062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!enabled()) return properties;
78162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    v8::Local<v8::Value> scopes;
78262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (generatorScopes(context, value).ToLocal(&scopes)) {
78362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      createDataProperty(context, properties, properties->Length(),
78462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         toV8StringInternalized(m_isolate, "[[Scopes]]"));
78562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      createDataProperty(context, properties, properties->Length(), scopes);
78662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
78862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!enabled()) return properties;
789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (value->IsFunction()) {
790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Local<v8::Function> function = value.As<v8::Function>();
791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Local<v8::Value> boundFunction = function->GetBoundFunction();
792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Local<v8::Value> scopes;
793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (boundFunction->IsUndefined() &&
794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        functionScopes(context, function).ToLocal(&scopes)) {
795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      createDataProperty(context, properties, properties->Length(),
796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         toV8StringInternalized(m_isolate, "[[Scopes]]"));
797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      createDataProperty(context, properties, properties->Length(), scopes);
798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
799f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
800f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return properties;
801f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
802f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
803f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstd::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(
804f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    v8::Local<v8::StackTrace> stackTrace) {
805f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int contextGroupId =
80662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      m_isolate->InContext()
80762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
80862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          : 0;
809f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return V8StackTraceImpl::create(this, contextGroupId, stackTrace,
810f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  V8StackTraceImpl::maxCallStackSizeToCapture);
811f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
812f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
813f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) {
814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (depth <= 0)
815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    m_maxAsyncCallStackDepthMap.erase(agent);
816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  else
817f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    m_maxAsyncCallStackDepthMap[agent] = depth;
818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
819f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int maxAsyncCallStackDepth = 0;
820f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  for (const auto& pair : m_maxAsyncCallStackDepthMap) {
821f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (pair.second > maxAsyncCallStackDepth)
822f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      maxAsyncCallStackDepth = pair.second;
823f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
824f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) return;
826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_maxAsyncCallStackDepth = maxAsyncCallStackDepth;
827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!maxAsyncCallStackDepth) allAsyncTasksCanceled();
828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
83062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8Debugger::registerAsyncTaskIfNeeded(void* task) {
83162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (m_taskToId.find(task) != m_taskToId.end()) return;
83262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
83362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int id = ++m_lastTaskId;
83462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_taskToId[task] = id;
83562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_idToTask[id] = task;
83662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) {
83762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void* taskToRemove = m_idToTask.begin()->second;
83862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    asyncTaskCanceled(taskToRemove);
83962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
84062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
84162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
84262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8Debugger::asyncTaskCreated(void* task, void* parentTask) {
84362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (!m_maxAsyncCallStackDepth) return;
84462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (parentTask) m_parentTask[task] = parentTask;
84562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  v8::HandleScope scope(m_isolate);
84662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // We don't need to pass context group id here because we gets this callback
84762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // from V8 for promise events only.
84862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Passing one as maxStackSize forces no async chain for the new stack and
84962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // allows us to not grow exponentially.
85062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  std::unique_ptr<V8StackTraceImpl> creationStack =
85162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      V8StackTraceImpl::capture(this, 0, 1, String16());
85262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (creationStack && !creationStack->isEmpty()) {
85362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    m_asyncTaskCreationStacks[task] = std::move(creationStack);
85462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    registerAsyncTaskIfNeeded(task);
85562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
85662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
85762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
858f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task,
859f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    bool recurring) {
860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_maxAsyncCallStackDepth) return;
861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  asyncTaskScheduled(toString16(taskName), task, recurring);
862f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
863f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::asyncTaskScheduled(const String16& taskName, void* task,
865f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    bool recurring) {
866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_maxAsyncCallStackDepth) return;
867f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope scope(m_isolate);
868f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int contextGroupId =
86962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      m_isolate->InContext()
87062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
87162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          : 0;
872f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(
873f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture,
874f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      taskName);
875f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (chain) {
876f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    m_asyncTaskStacks[task] = std::move(chain);
877f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (recurring) m_recurringTasks.insert(task);
87862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    registerAsyncTaskIfNeeded(task);
879f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
880f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
881f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
882f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::asyncTaskCanceled(void* task) {
883f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_maxAsyncCallStackDepth) return;
884f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_asyncTaskStacks.erase(task);
885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_recurringTasks.erase(task);
88662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_parentTask.erase(task);
88762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_asyncTaskCreationStacks.erase(task);
88862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto it = m_taskToId.find(task);
88962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (it == m_taskToId.end()) return;
89062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_idToTask.erase(it->second);
89162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_taskToId.erase(it);
892f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
893f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
894f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::asyncTaskStarted(void* task) {
895f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_maxAsyncCallStackDepth) return;
896f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_currentTasks.push_back(task);
89762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto parentIt = m_parentTask.find(task);
89862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(
89962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      parentIt == m_parentTask.end() ? task : parentIt->second);
900f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Needs to support following order of events:
901f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - asyncTaskScheduled
902f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   <-- attached here -->
903f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - asyncTaskStarted
904f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - asyncTaskCanceled <-- canceled before finished
905f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  //   <-- async stack requested here -->
906f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // - asyncTaskFinished
907f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  std::unique_ptr<V8StackTraceImpl> stack;
908f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (stackIt != m_asyncTaskStacks.end() && stackIt->second)
909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    stack = stackIt->second->cloneImpl();
91062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto itCreation = m_asyncTaskCreationStacks.find(task);
91162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (stack && itCreation != m_asyncTaskCreationStacks.end()) {
91262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    stack->setCreation(itCreation->second->cloneImpl());
91362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
914f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_currentStacks.push_back(std::move(stack));
915f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
916f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
917f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::asyncTaskFinished(void* task) {
918f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_maxAsyncCallStackDepth) return;
919f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // We could start instrumenting half way and the stack is empty.
920f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_currentStacks.size()) return;
921f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
922f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(m_currentTasks.back() == task);
923f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_currentTasks.pop_back();
924f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
925f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_currentStacks.pop_back();
92662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (m_recurringTasks.find(task) == m_recurringTasks.end()) {
92762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    asyncTaskCanceled(task);
92862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
929f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
930f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
931f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::allAsyncTasksCanceled() {
932f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_asyncTaskStacks.clear();
933f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_recurringTasks.clear();
934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_currentStacks.clear();
935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  m_currentTasks.clear();
93662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_parentTask.clear();
93762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_asyncTaskCreationStacks.clear();
93862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_idToTask.clear();
93962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_taskToId.clear();
94062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  m_lastTaskId = 0;
941f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
942f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
943f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::muteScriptParsedEvents() {
944f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ++m_ignoreScriptParsedEventsCounter;
945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
946f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8Debugger::unmuteScriptParsedEvents() {
948f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  --m_ignoreScriptParsedEventsCounter;
949f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0);
950f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
951f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
952f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstd::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
953f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bool fullStack) {
954f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!m_isolate->InContext()) return nullptr;
955f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
956f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  v8::HandleScope handles(m_isolate);
95762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int contextGroupId =
95862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      m_inspector->contextGroupId(m_isolate->GetCurrentContext());
959f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (!contextGroupId) return nullptr;
960f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  size_t stackSize =
962f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
963f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
964f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
965f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
966f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
967f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
968f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
969f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}  // namespace v8_inspector
970