debug-scopes.h 5.43 KB
Newer Older
1 2 3 4 5 6 7
// 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.

#ifndef V8_DEBUG_DEBUG_SCOPES_H_
#define V8_DEBUG_DEBUG_SCOPES_H_

8 9
#include <vector>

10 11 12 13 14
#include "src/debug/debug-frames.h"

namespace v8 {
namespace internal {

15
class JavaScriptFrame;
16 17
class ParseInfo;

18 19 20 21 22 23 24 25 26 27 28 29 30 31
// Iterate over the actual scopes visible from a stack frame or from a closure.
// The iteration proceeds from the innermost visible nested scope outwards.
// All scopes are backed by an actual context except the local scope,
// which is inserted "artificially" in the context chain.
class ScopeIterator {
 public:
  enum ScopeType {
    ScopeTypeGlobal = 0,
    ScopeTypeLocal,
    ScopeTypeWith,
    ScopeTypeClosure,
    ScopeTypeCatch,
    ScopeTypeBlock,
    ScopeTypeScript,
32
    ScopeTypeEval,
33 34 35 36 37
    ScopeTypeModule
  };

  static const int kScopeDetailsTypeIndex = 0;
  static const int kScopeDetailsObjectIndex = 1;
38
  static const int kScopeDetailsNameIndex = 2;
39 40 41 42
  static const int kScopeDetailsStartPositionIndex = 3;
  static const int kScopeDetailsEndPositionIndex = 4;
  static const int kScopeDetailsFunctionIndex = 5;
  static const int kScopeDetailsSize = 6;
43

44 45 46 47
  enum class ReparseStrategy {
    kScript,
    kFunctionLiteral,
  };
48

49
  ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
50
                ReparseStrategy strategy);
51 52

  ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
53
  ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator);
54
  ~ScopeIterator();
55

56
  Handle<JSObject> MaterializeScopeDetails();
57 58

  // More scopes?
59
  bool Done() const { return context_.is_null(); }
60 61 62 63

  // Move to the next scope.
  void Next();

64 65 66
  // Restart to the first scope and context.
  void Restart();

67
  // Return the type of the current scope.
68 69 70 71 72
  ScopeType Type() const;

  // Indicates which variables should be visited. Either only variables from the
  // scope that are available on the stack, or all variables.
  enum class Mode { STACK, ALL };
73 74

  // Return the JavaScript object with the content of the current scope.
75
  Handle<JSObject> ScopeObject(Mode mode);
76

77 78
  // Returns whether the current scope declares any variables.
  bool DeclaresLocals(Mode mode) const;
79 80 81 82

  // Set variable value and return true on success.
  bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value);

83 84
  bool ClosureScopeHasThisReference() const;

85
  // Populate the set with collected non-local variable names.
86
  Handle<StringSet> GetLocals() { return locals_; }
87

88 89 90 91 92 93 94
  // Similar to JSFunction::GetName return the function's name or it's inferred
  // name.
  Handle<Object> GetFunctionDebugName() const;

  Handle<Script> GetScript() const { return script_; }

  bool HasPositionInfo();
95 96 97
  int start_position();
  int end_position();

98 99 100 101 102
#ifdef DEBUG
  // Debug print of the content of the current scope.
  void DebugPrint();
#endif

103 104
  bool InInnerScope() const { return !function_.is_null(); }
  bool HasContext() const;
105
  bool NeedsAndHasContext() const;
106 107 108 109
  Handle<Context> CurrentContext() const {
    DCHECK(HasContext());
    return context_;
  }
110

111
 private:
112
  Isolate* isolate_;
113
  std::unique_ptr<ParseInfo> info_;
114 115
  FrameInspector* const frame_inspector_ = nullptr;
  Handle<JSGeneratorObject> generator_;
116 117 118

  // The currently-executing function from the inspected frame, or null if this
  // ScopeIterator has already iterated to any Scope outside that function.
119
  Handle<JSFunction> function_;
120

121
  Handle<Context> context_;
122
  Handle<Script> script_;
123
  Handle<StringSet> locals_;
124 125 126 127
  DeclarationScope* closure_scope_ = nullptr;
  Scope* start_scope_ = nullptr;
  Scope* current_scope_ = nullptr;
  bool seen_script_scope_ = false;
128

129 130
  inline JavaScriptFrame* GetFrame() const {
    return frame_inspector_->javascript_frame();
131 132
  }

133 134
  void AdvanceOneScope();
  void AdvanceToNonHiddenScope();
135 136
  void AdvanceContext();
  void CollectLocalsFromCurrentScope();
137

138 139
  int GetSourcePosition();

140
  void TryParseAndRetrieveScopes(ReparseStrategy strategy);
141

142
  void UnwrapEvaluationContext();
143

144 145
  using Visitor = std::function<bool(Handle<String> name, Handle<Object> value,
                                     ScopeType scope_type)>;
146

147
  Handle<JSObject> WithContextExtension();
148 149 150

  bool SetLocalVariableValue(Handle<String> variable_name,
                             Handle<Object> new_value);
151
  bool SetContextVariableValue(Handle<String> variable_name,
152
                               Handle<Object> new_value);
153 154
  bool SetContextExtensionValue(Handle<String> variable_name,
                                Handle<Object> new_value);
155 156
  bool SetScriptVariableValue(Handle<String> variable_name,
                              Handle<Object> new_value);
157 158
  bool SetModuleVariableValue(Handle<String> variable_name,
                              Handle<Object> new_value);
159 160

  // Helper functions.
161
  void VisitScope(const Visitor& visitor, Mode mode) const;
162 163
  void VisitLocalScope(const Visitor& visitor, Mode mode,
                       ScopeType scope_type) const;
164 165
  void VisitScriptScope(const Visitor& visitor) const;
  void VisitModuleScope(const Visitor& visitor) const;
166 167
  bool VisitLocals(const Visitor& visitor, Mode mode,
                   ScopeType scope_type) const;
168
  bool VisitContextLocals(const Visitor& visitor, Handle<ScopeInfo> scope_info,
169
                          Handle<Context> context, ScopeType scope_type) const;
170

171 172 173 174 175 176 177
  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_DEBUG_DEBUG_SCOPES_H_