• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_DEBUG_DEBUG_SCOPES_H_
6 #define V8_DEBUG_DEBUG_SCOPES_H_
7 
8 #include "src/debug/debug-frames.h"
9 #include "src/parsing/parse-info.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 class JavaScriptFrame;
15 class ParseInfo;
16 
17 // Iterate over the actual scopes visible from a stack frame or from a closure.
18 // The iteration proceeds from the innermost visible nested scope outwards.
19 // All scopes are backed by an actual context except the local scope,
20 // which is inserted "artificially" in the context chain.
21 class ScopeIterator {
22  public:
23   enum ScopeType {
24     ScopeTypeGlobal = 0,
25     ScopeTypeLocal,
26     ScopeTypeWith,
27     ScopeTypeClosure,
28     ScopeTypeCatch,
29     ScopeTypeBlock,
30     ScopeTypeScript,
31     ScopeTypeEval,
32     ScopeTypeModule
33   };
34 
35   static const int kScopeDetailsTypeIndex = 0;
36   static const int kScopeDetailsObjectIndex = 1;
37   static const int kScopeDetailsNameIndex = 2;
38   static const int kScopeDetailsStartPositionIndex = 3;
39   static const int kScopeDetailsEndPositionIndex = 4;
40   static const int kScopeDetailsFunctionIndex = 5;
41   static const int kScopeDetailsSize = 6;
42 
43   enum class ReparseStrategy {
44     kScript,
45     kFunctionLiteral,
46   };
47 
48   ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
49                 ReparseStrategy strategy);
50 
51   ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
52   ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator);
53   ~ScopeIterator();
54 
55   Handle<JSObject> MaterializeScopeDetails();
56 
57   // More scopes?
Done()58   bool Done() const { return context_.is_null(); }
59 
60   // Move to the next scope.
61   void Next();
62 
63   // Restart to the first scope and context.
64   void Restart();
65 
66   // Return the type of the current scope.
67   ScopeType Type() const;
68 
69   // Indicates which variables should be visited. Either only variables from the
70   // scope that are available on the stack, or all variables.
71   enum class Mode { STACK, ALL };
72 
73   // Return the JavaScript object with the content of the current scope.
74   Handle<JSObject> ScopeObject(Mode mode);
75 
76   // Returns whether the current scope declares any variables.
77   bool DeclaresLocals(Mode mode) const;
78 
79   // Set variable value and return true on success.
80   bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value);
81 
82   bool ClosureScopeHasThisReference() const;
83 
84   // Populate the set with collected non-local variable names.
GetLocals()85   Handle<StringSet> GetLocals() { return locals_; }
86 
87   // Similar to JSFunction::GetName return the function's name or it's inferred
88   // name.
89   Handle<Object> GetFunctionDebugName() const;
90 
GetScript()91   Handle<Script> GetScript() const { return script_; }
92 
93   bool HasPositionInfo();
94   int start_position();
95   int end_position();
96 
97 #ifdef DEBUG
98   // Debug print of the content of the current scope.
99   void DebugPrint();
100 #endif
101 
InInnerScope()102   bool InInnerScope() const { return !function_.is_null(); }
103   bool HasContext() const;
104   bool NeedsAndHasContext() const;
CurrentContext()105   Handle<Context> CurrentContext() const {
106     DCHECK(HasContext());
107     return context_;
108   }
109 
110  private:
111   Isolate* isolate_;
112   std::unique_ptr<ReusableUnoptimizedCompileState> reusable_compile_state_;
113   std::unique_ptr<ParseInfo> info_;
114   FrameInspector* const frame_inspector_ = nullptr;
115   Handle<JSGeneratorObject> generator_;
116 
117   // The currently-executing function from the inspected frame, or null if this
118   // 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   DeclarationScope* closure_scope_ = nullptr;
125   Scope* start_scope_ = nullptr;
126   Scope* current_scope_ = nullptr;
127   bool seen_script_scope_ = false;
128 
GetFrame()129   inline JavaScriptFrame* GetFrame() const {
130     return frame_inspector_->javascript_frame();
131   }
132 
133   void AdvanceOneScope();
134   void AdvanceToNonHiddenScope();
135   void AdvanceContext();
136   void CollectLocalsFromCurrentScope();
137 
138   int GetSourcePosition();
139 
140   void TryParseAndRetrieveScopes(ReparseStrategy strategy);
141 
142   void UnwrapEvaluationContext();
143 
144   using Visitor = std::function<bool(Handle<String> name, Handle<Object> value,
145                                      ScopeType scope_type)>;
146 
147   Handle<JSObject> WithContextExtension();
148 
149   bool SetLocalVariableValue(Handle<String> variable_name,
150                              Handle<Object> new_value);
151   bool SetContextVariableValue(Handle<String> variable_name,
152                                Handle<Object> new_value);
153   bool SetContextExtensionValue(Handle<String> variable_name,
154                                 Handle<Object> new_value);
155   bool SetScriptVariableValue(Handle<String> variable_name,
156                               Handle<Object> new_value);
157   bool SetModuleVariableValue(Handle<String> variable_name,
158                               Handle<Object> new_value);
159 
160   // Helper functions.
161   void VisitScope(const Visitor& visitor, Mode mode) const;
162   void VisitLocalScope(const Visitor& visitor, Mode mode,
163                        ScopeType scope_type) const;
164   void VisitScriptScope(const Visitor& visitor) const;
165   void VisitModuleScope(const Visitor& visitor) const;
166   bool VisitLocals(const Visitor& visitor, Mode mode,
167                    ScopeType scope_type) const;
168   bool VisitContextLocals(const Visitor& visitor, Handle<ScopeInfo> scope_info,
169                           Handle<Context> context, ScopeType scope_type) const;
170 
171   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
172 };
173 
174 }  // namespace internal
175 }  // namespace v8
176 
177 #endif  // V8_DEBUG_DEBUG_SCOPES_H_
178