• 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 <vector>
9 
10 #include "src/debug/debug-frames.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 class JavaScriptFrame;
16 class ParseInfo;
17 
18 // Iterate over the actual scopes visible from a stack frame or from a closure.
19 // The iteration proceeds from the innermost visible nested scope outwards.
20 // All scopes are backed by an actual context except the local scope,
21 // which is inserted "artificially" in the context chain.
22 class ScopeIterator {
23  public:
24   enum ScopeType {
25     ScopeTypeGlobal = 0,
26     ScopeTypeLocal,
27     ScopeTypeWith,
28     ScopeTypeClosure,
29     ScopeTypeCatch,
30     ScopeTypeBlock,
31     ScopeTypeScript,
32     ScopeTypeEval,
33     ScopeTypeModule
34   };
35 
36   static const int kScopeDetailsTypeIndex = 0;
37   static const int kScopeDetailsObjectIndex = 1;
38   static const int kScopeDetailsNameIndex = 2;
39   static const int kScopeDetailsStartPositionIndex = 3;
40   static const int kScopeDetailsEndPositionIndex = 4;
41   static const int kScopeDetailsFunctionIndex = 5;
42   static const int kScopeDetailsSize = 6;
43 
44   enum class ReparseStrategy {
45     kScript,
46     kFunctionLiteral,
47   };
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?
Done()59   bool Done() const { return context_.is_null(); }
60 
61   // Move to the next scope.
62   void Next();
63 
64   // Restart to the first scope and context.
65   void Restart();
66 
67   // Return the type of the current scope.
68   ScopeType Type() const;
69 
70   // Indicates which variables should be visited. Either only variables from the
71   // scope that are available on the stack, or all variables.
72   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   // Returns whether the current scope declares any variables.
78   bool DeclaresLocals(Mode mode) const;
79 
80   // Set variable value and return true on success.
81   bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value);
82 
83   bool ClosureScopeHasThisReference() const;
84 
85   // Populate the set with collected non-local variable names.
GetLocals()86   Handle<StringSet> GetLocals() { return locals_; }
87 
88   // Similar to JSFunction::GetName return the function's name or it's inferred
89   // name.
90   Handle<Object> GetFunctionDebugName() const;
91 
GetScript()92   Handle<Script> GetScript() const { return script_; }
93 
94   bool HasPositionInfo();
95   int start_position();
96   int end_position();
97 
98 #ifdef DEBUG
99   // Debug print of the content of the current scope.
100   void DebugPrint();
101 #endif
102 
InInnerScope()103   bool InInnerScope() const { return !function_.is_null(); }
104   bool HasContext() const;
105   bool NeedsAndHasContext() const;
CurrentContext()106   Handle<Context> CurrentContext() const {
107     DCHECK(HasContext());
108     return context_;
109   }
110 
111  private:
112   Isolate* isolate_;
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