• 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/frames.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 // Iterate over the actual scopes visible from a stack frame or from a closure.
15 // The iteration proceeds from the innermost visible nested scope outwards.
16 // All scopes are backed by an actual context except the local scope,
17 // which is inserted "artificially" in the context chain.
18 class ScopeIterator {
19  public:
20   enum ScopeType {
21     ScopeTypeGlobal = 0,
22     ScopeTypeLocal,
23     ScopeTypeWith,
24     ScopeTypeClosure,
25     ScopeTypeCatch,
26     ScopeTypeBlock,
27     ScopeTypeScript,
28     ScopeTypeEval,
29     ScopeTypeModule
30   };
31 
32   static const int kScopeDetailsTypeIndex = 0;
33   static const int kScopeDetailsObjectIndex = 1;
34   static const int kScopeDetailsNameIndex = 2;
35   static const int kScopeDetailsStartPositionIndex = 3;
36   static const int kScopeDetailsEndPositionIndex = 4;
37   static const int kScopeDetailsFunctionIndex = 5;
38   static const int kScopeDetailsSize = 6;
39 
40   enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS };
41 
42   ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
43                 Option options = DEFAULT);
44 
45   ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
46 
47   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails();
48 
49   // More scopes?
Done()50   bool Done() {
51     DCHECK(!failed_);
52     return context_.is_null();
53   }
54 
Failed()55   bool Failed() { return failed_; }
56 
57   // Move to the next scope.
58   void Next();
59 
60   // Return the type of the current scope.
61   ScopeType Type();
62 
63   // Return the JavaScript object with the content of the current scope.
64   MaybeHandle<JSObject> ScopeObject();
65 
66   bool HasContext();
67 
68   // Set variable value and return true on success.
69   bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value);
70 
71   Handle<ScopeInfo> CurrentScopeInfo();
72 
73   // Return the context for this scope. For the local context there might not
74   // be an actual context.
75   Handle<Context> CurrentContext();
76 
77   // Populate the set with collected non-local variable names.
78   Handle<StringSet> GetNonLocals();
79 
80 #ifdef DEBUG
81   // Debug print of the content of the current scope.
82   void DebugPrint();
83 #endif
84 
85  private:
86   struct ExtendedScopeInfo {
ExtendedScopeInfoExtendedScopeInfo87     ExtendedScopeInfo(Handle<ScopeInfo> info, int start, int end)
88         : scope_info(info), start_position(start), end_position(end) {}
ExtendedScopeInfoExtendedScopeInfo89     explicit ExtendedScopeInfo(Handle<ScopeInfo> info)
90         : scope_info(info), start_position(-1), end_position(-1) {}
91     Handle<ScopeInfo> scope_info;
92     int start_position;
93     int end_position;
is_hiddenExtendedScopeInfo94     bool is_hidden() { return start_position == -1 && end_position == -1; }
95   };
96 
97   Isolate* isolate_;
98   FrameInspector* const frame_inspector_;
99   Handle<Context> context_;
100   List<ExtendedScopeInfo> nested_scope_chain_;
101   Handle<StringSet> non_locals_;
102   bool seen_script_scope_;
103   bool failed_;
104 
GetFrame()105   inline JavaScriptFrame* GetFrame() {
106     return frame_inspector_->GetArgumentsFrame();
107   }
108 
GetFunction()109   inline Handle<JSFunction> GetFunction() {
110     return Handle<JSFunction>::cast(frame_inspector_->GetFunction());
111   }
112 
113   void RetrieveScopeChain(Scope* scope);
114 
115   void CollectNonLocals(Scope* scope);
116 
117   void UnwrapEvaluationContext();
118 
119   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScriptScope();
120   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeLocalScope();
121   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeModuleScope();
122   Handle<JSObject> MaterializeClosure();
123   Handle<JSObject> MaterializeCatchScope();
124   Handle<JSObject> MaterializeInnerScope();
125   Handle<JSObject> WithContextExtension();
126 
127   bool SetLocalVariableValue(Handle<String> variable_name,
128                              Handle<Object> new_value);
129   bool SetInnerScopeVariableValue(Handle<String> variable_name,
130                                   Handle<Object> new_value);
131   bool SetClosureVariableValue(Handle<String> variable_name,
132                                Handle<Object> new_value);
133   bool SetScriptVariableValue(Handle<String> variable_name,
134                               Handle<Object> new_value);
135   bool SetCatchVariableValue(Handle<String> variable_name,
136                              Handle<Object> new_value);
137 
138   // Helper functions.
139   bool SetParameterValue(Handle<ScopeInfo> scope_info, JavaScriptFrame* frame,
140                          Handle<String> parameter_name,
141                          Handle<Object> new_value);
142   bool SetStackVariableValue(Handle<ScopeInfo> scope_info,
143                              JavaScriptFrame* frame,
144                              Handle<String> variable_name,
145                              Handle<Object> new_value);
146   bool SetContextVariableValue(Handle<ScopeInfo> scope_info,
147                                Handle<Context> context,
148                                Handle<String> variable_name,
149                                Handle<Object> new_value);
150 
151   void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
152                                       Handle<Context> context,
153                                       Handle<JSObject> scope_object);
154   void CopyContextExtensionToScopeObject(Handle<Context> context,
155                                          Handle<JSObject> scope_object,
156                                          KeyCollectionMode mode);
157 
158   // Get the chain of nested scopes within this scope for the source statement
159   // position. The scopes will be added to the list from the outermost scope to
160   // the innermost scope. Only nested block, catch or with scopes are tracked
161   // and will be returned, but no inner function scopes.
162   void GetNestedScopeChain(Isolate* isolate, Scope* scope,
163                            int statement_position);
164 
165   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
166 };
167 
168 }  // namespace internal
169 }  // namespace v8
170 
171 #endif  // V8_DEBUG_DEBUG_SCOPES_H_
172