• 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 #include "src/frames.h"
12 
13 namespace v8 {
14 namespace internal {
15 
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 Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS };
45 
46   ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
47                 Option options = DEFAULT);
48 
49   ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
50   ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator);
51   ~ScopeIterator();
52 
53   Handle<JSObject> MaterializeScopeDetails();
54 
55   // More scopes?
Done()56   bool Done() const { return context_.is_null(); }
57 
58   // Move to the next scope.
59   void Next();
60 
61   // Restart to the first scope and context.
62   void Restart();
63 
64   // Return the type of the current scope.
65   ScopeType Type() const;
66 
67   // Indicates which variables should be visited. Either only variables from the
68   // scope that are available on the stack, or all variables.
69   enum class Mode { STACK, ALL };
70 
71   // Return the JavaScript object with the content of the current scope.
72   Handle<JSObject> ScopeObject(Mode mode);
73 
74   // Returns whether the current scope declares any variables.
75   bool DeclaresLocals(Mode mode) const;
76 
77   // Set variable value and return true on success.
78   bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value);
79 
80   // Populate the set with collected non-local variable names.
81   Handle<StringSet> GetNonLocals();
82 
83   // Similar to JSFunction::GetName return the function's name or it's inferred
84   // name.
85   Handle<Object> GetFunctionDebugName() const;
86 
GetScript()87   Handle<Script> GetScript() const { return script_; }
88 
89   bool HasPositionInfo();
90   int start_position();
91   int end_position();
92 
93 #ifdef DEBUG
94   // Debug print of the content of the current scope.
95   void DebugPrint();
96 #endif
97 
InInnerScope()98   bool InInnerScope() const { return !function_.is_null(); }
99   bool HasContext() const;
CurrentContext()100   Handle<Context> CurrentContext() const {
101     DCHECK(HasContext());
102     return context_;
103   }
104 
105  private:
106   Isolate* isolate_;
107   ParseInfo* info_ = nullptr;
108   FrameInspector* const frame_inspector_ = nullptr;
109   Handle<JSGeneratorObject> generator_;
110   Handle<JSFunction> function_;
111   Handle<Context> context_;
112   Handle<Script> script_;
113   Handle<StringSet> non_locals_;
114   DeclarationScope* closure_scope_ = nullptr;
115   Scope* start_scope_ = nullptr;
116   Scope* current_scope_ = nullptr;
117   bool seen_script_scope_ = false;
118 
GetFrame()119   inline JavaScriptFrame* GetFrame() const {
120     return frame_inspector_->javascript_frame();
121   }
122 
123   int GetSourcePosition();
124 
125   void TryParseAndRetrieveScopes(ScopeIterator::Option option);
126 
127   void RetrieveScopeChain(DeclarationScope* scope);
128 
129   void UnwrapEvaluationContext();
130 
131   typedef std::function<bool(Handle<String> name, Handle<Object> value)>
132       Visitor;
133 
134   Handle<JSObject> WithContextExtension();
135 
136   bool SetLocalVariableValue(Handle<String> variable_name,
137                              Handle<Object> new_value);
138   bool SetContextVariableValue(Handle<String> variable_name,
139                                Handle<Object> new_value);
140   bool SetContextExtensionValue(Handle<String> variable_name,
141                                 Handle<Object> new_value);
142   bool SetScriptVariableValue(Handle<String> variable_name,
143                               Handle<Object> new_value);
144   bool SetModuleVariableValue(Handle<String> variable_name,
145                               Handle<Object> new_value);
146 
147   // Helper functions.
148   void VisitScope(const Visitor& visitor, Mode mode) const;
149   void VisitLocalScope(const Visitor& visitor, Mode mode) const;
150   void VisitScriptScope(const Visitor& visitor) const;
151   void VisitModuleScope(const Visitor& visitor) const;
152   bool VisitLocals(const Visitor& visitor, Mode mode) const;
153   bool VisitContextLocals(const Visitor& visitor, Handle<ScopeInfo> scope_info,
154                           Handle<Context> context) const;
155 
156   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
157 };
158 
159 }  // namespace internal
160 }  // namespace v8
161 
162 #endif  // V8_DEBUG_DEBUG_SCOPES_H_
163