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