<commit_before>// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/debug/debug-scopes.h"

#include "src/debug/debug.h"
#include "src/globals.h"
#include "src/parser.h"
#include "src/scopes.h"

namespace v8 {
namespace internal {

ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
                             bool ignore_nested_scopes)
    : isolate_(isolate),
      frame_inspector_(frame_inspector),
      nested_scope_chain_(4),
      seen_script_scope_(false),
      failed_(false) {
  if (!frame_inspector->GetContext()->IsContext() ||
      !frame_inspector->GetFunction()->IsJSFunction()) {
    // Optimized frame, context or function cannot be materialized. Give up.
    return;
  }

  context_ = Handle<Context>(Context::cast(frame_inspector->GetContext()));

  // Catch the case when the debugger stops in an internal function.
  Handle<JSFunction> function = GetFunction();
  Handle<SharedFunctionInfo> shared_info(function->shared());
  Handle<ScopeInfo> scope_info(shared_info->scope_info());
  if (shared_info->script() == isolate->heap()->undefined_value()) {
    while (context_->closure() == *function) {
      context_ = Handle<Context>(context_->previous(), isolate_);
    }
    return;
  }

  // Currently it takes too much time to find nested scopes due to script
  // parsing. Sometimes we want to run the ScopeIterator as fast as possible
  // (for example, while collecting async call stacks on every
  // addEventListener call), even if we drop some nested scopes.
  // Later we may optimize getting the nested scopes (cache the result?)
  // and include nested scopes into the "fast" iteration case as well.

  if (!ignore_nested_scopes && shared_info->HasDebugInfo()) {
    // The source position at return is always the end of the function,
    // which is not consistent with the current scope chain. Therefore all
    // nested with, catch and block contexts are skipped, and we can only
    // inspect the function scope.
    // This can only happen if we set a break point inside right before the
    // return, which requires a debug info to be available.
    Handle<DebugInfo> debug_info(shared_info->GetDebugInfo());

    // PC points to the instruction after the current one, possibly a break
    // location as well. So the "- 1" to exclude it from the search.
    Address call_pc = GetFrame()->pc() - 1;

    // Find the break point where execution has stopped.
    BreakLocation location =
        BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);

    ignore_nested_scopes = location.IsReturn();
  }

  if (ignore_nested_scopes) {
    if (scope_info->HasContext()) {
      context_ = Handle<Context>(context_->declaration_context(), isolate_);
    } else {
      while (context_->closure() == *function) {
        context_ = Handle<Context>(context_->previous(), isolate_);
      }
    }
    if (scope_info->scope_type() == FUNCTION_SCOPE ||
        scope_info->scope_type() == ARROW_SCOPE) {
      nested_scope_chain_.Add(scope_info);
    }
  } else {
    // Reparse the code and analyze the scopes.
    Handle<Script> script(Script::cast(shared_info->script()));
    Scope* scope = NULL;

    // Check whether we are in global, eval or function code.
    Handle<ScopeInfo> scope_info(shared_info->scope_info());
    Zone zone;
    if (scope_info->scope_type() != FUNCTION_SCOPE &&
        scope_info->scope_type() != ARROW_SCOPE) {
      // Global or eval code.
      ParseInfo info(&zone, script);
      if (scope_info->scope_type() == SCRIPT_SCOPE) {
        info.set_global();
      } else {
        DCHECK(scope_info->scope_type() == EVAL_SCOPE);
        info.set_eval();
        info.set_context(Handle<Context>(function->context()));
      }
      if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) {
        scope = info.function()->scope();
      }<commit_msg>Remove redundant handle in ScopeIterator constructor.<commit_after>// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/debug/debug-scopes.h"

#include "src/debug/debug.h"
#include "src/globals.h"
#include "src/parser.h"
#include "src/scopes.h"

namespace v8 {
namespace internal {

ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
                             bool ignore_nested_scopes)
    : isolate_(isolate),
      frame_inspector_(frame_inspector),
      nested_scope_chain_(4),
      seen_script_scope_(false),
      failed_(false) {
  if (!frame_inspector->GetContext()->IsContext() ||
      !frame_inspector->GetFunction()->IsJSFunction()) {
    // Optimized frame, context or function cannot be materialized. Give up.
    return;
  }

  context_ = Handle<Context>(Context::cast(frame_inspector->GetContext()));

  // Catch the case when the debugger stops in an internal function.
  Handle<JSFunction> function = GetFunction();
  Handle<SharedFunctionInfo> shared_info(function->shared());
  Handle<ScopeInfo> scope_info(shared_info->scope_info());
  if (shared_info->script() == isolate->heap()->undefined_value()) {
    while (context_->closure() == *function) {
      context_ = Handle<Context>(context_->previous(), isolate_);
    }
    return;
  }

  // Currently it takes too much time to find nested scopes due to script
  // parsing. Sometimes we want to run the ScopeIterator as fast as possible
  // (for example, while collecting async call stacks on every
  // addEventListener call), even if we drop some nested scopes.
  // Later we may optimize getting the nested scopes (cache the result?)
  // and include nested scopes into the "fast" iteration case as well.

  if (!ignore_nested_scopes && shared_info->HasDebugInfo()) {
    // The source position at return is always the end of the function,
    // which is not consistent with the current scope chain. Therefore all
    // nested with, catch and block contexts are skipped, and we can only
    // inspect the function scope.
    // This can only happen if we set a break point inside right before the
    // return, which requires a debug info to be available.
    Handle<DebugInfo> debug_info(shared_info->GetDebugInfo());

    // PC points to the instruction after the current one, possibly a break
    // location as well. So the "- 1" to exclude it from the search.
    Address call_pc = GetFrame()->pc() - 1;

    // Find the break point where execution has stopped.
    BreakLocation location =
        BreakLocation::FromAddress(debug_info, ALL_BREAK_LOCATIONS, call_pc);

    ignore_nested_scopes = location.IsReturn();
  }

  if (ignore_nested_scopes) {
    if (scope_info->HasContext()) {
      context_ = Handle<Context>(context_->declaration_context(), isolate_);
    } else {
      while (context_->closure() == *function) {
        context_ = Handle<Context>(context_->previous(), isolate_);
      }
    }
    if (scope_info->scope_type() == FUNCTION_SCOPE ||
        scope_info->scope_type() == ARROW_SCOPE) {
      nested_scope_chain_.Add(scope_info);
    }
  } else {
    // Reparse the code and analyze the scopes.
    Handle<Script> script(Script::cast(shared_info->script()));
    Scope* scope = NULL;

    // Check whether we are in global, eval or function code.
    Zone zone;
    if (scope_info->scope_type() != FUNCTION_SCOPE &&
        scope_info->scope_type() != ARROW_SCOPE) {
      // Global or eval code.
      ParseInfo info(&zone, script);
      if (scope_info->scope_type() == SCRIPT_SCOPE) {
        info.set_global();
      } else {
        DCHECK(scope_info->scope_type() == EVAL_SCOPE);
        info.set_eval();
        info.set_context(Handle<Context>(function->context()));
      }
      if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) {
        scope = info.function()->scope();
      }
{'fraction_non_alphanumeric': 0.11717475849956091, 'fraction_numerical': 0.002258185923974407, 'mean_word_length': 3.351528384279476, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3188393', 'n_tokens_mistral': 2315, 'n_tokens_neox': 2227, 'n_words': 697}