blob: 1338e7bfcce19a7b7d01e595591412aa25b4915c [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
11namespace v8 {
12namespace 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.
18class ScopeIterator {
19 public:
20 enum ScopeType {
21 ScopeTypeGlobal = 0,
22 ScopeTypeLocal,
23 ScopeTypeWith,
24 ScopeTypeClosure,
25 ScopeTypeCatch,
26 ScopeTypeBlock,
27 ScopeTypeScript,
Ben Murdochc5610432016-08-08 18:44:38 +010028 ScopeTypeEval,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029 ScopeTypeModule
30 };
31
32 static const int kScopeDetailsTypeIndex = 0;
33 static const int kScopeDetailsObjectIndex = 1;
34 static const int kScopeDetailsNameIndex = 2;
Ben Murdochda12d292016-06-02 14:46:10 +010035 static const int kScopeDetailsStartPositionIndex = 3;
36 static const int kScopeDetailsEndPositionIndex = 4;
37 static const int kScopeDetailsFunctionIndex = 5;
38 static const int kScopeDetailsSize = 6;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039
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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails();
48
49 // More scopes?
50 bool Done() {
51 DCHECK(!failed_);
52 return context_.is_null();
53 }
54
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
Ben Murdochda12d292016-06-02 14:46:10 +010077 // Populate the set with collected non-local variable names.
78 Handle<StringSet> GetNonLocals();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079
80#ifdef DEBUG
81 // Debug print of the content of the current scope.
82 void DebugPrint();
83#endif
84
85 private:
Ben Murdochda12d292016-06-02 14:46:10 +010086 struct ExtendedScopeInfo {
87 ExtendedScopeInfo(Handle<ScopeInfo> info, int start, int end)
88 : scope_info(info), start_position(start), end_position(end) {}
Ben Murdochc5610432016-08-08 18:44:38 +010089 explicit ExtendedScopeInfo(Handle<ScopeInfo> info)
90 : scope_info(info), start_position(-1), end_position(-1) {}
Ben Murdochda12d292016-06-02 14:46:10 +010091 Handle<ScopeInfo> scope_info;
92 int start_position;
93 int end_position;
Ben Murdochc5610432016-08-08 18:44:38 +010094 bool is_hidden() { return start_position == -1 && end_position == -1; }
Ben Murdochda12d292016-06-02 14:46:10 +010095 };
96
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097 Isolate* isolate_;
98 FrameInspector* const frame_inspector_;
99 Handle<Context> context_;
Ben Murdochda12d292016-06-02 14:46:10 +0100100 List<ExtendedScopeInfo> nested_scope_chain_;
101 Handle<StringSet> non_locals_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 bool seen_script_scope_;
103 bool failed_;
104
105 inline JavaScriptFrame* GetFrame() {
106 return frame_inspector_->GetArgumentsFrame();
107 }
108
109 inline Handle<JSFunction> GetFunction() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100110 return Handle<JSFunction>::cast(frame_inspector_->GetFunction());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000111 }
112
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000113 void RetrieveScopeChain(Scope* scope);
114
115 void CollectNonLocals(Scope* scope);
116
Ben Murdochda12d292016-06-02 14:46:10 +0100117 void UnwrapEvaluationContext();
118
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119 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();
Ben Murdochc5610432016-08-08 18:44:38 +0100124 Handle<JSObject> MaterializeInnerScope();
Ben Murdochda12d292016-06-02 14:46:10 +0100125 Handle<JSObject> WithContextExtension();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000126
127 bool SetLocalVariableValue(Handle<String> variable_name,
128 Handle<Object> new_value);
Ben Murdochc5610432016-08-08 18:44:38 +0100129 bool SetInnerScopeVariableValue(Handle<String> variable_name,
130 Handle<Object> new_value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000131 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);
Ben Murdochc5610432016-08-08 18:44:38 +0100137
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);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000150
151 void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
152 Handle<Context> context,
153 Handle<JSObject> scope_object);
Ben Murdochc5610432016-08-08 18:44:38 +0100154 void CopyContextExtensionToScopeObject(Handle<Context> context,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 Handle<JSObject> scope_object,
Ben Murdoch61f157c2016-09-16 13:49:30 +0100156 KeyCollectionMode mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000157
Ben Murdochda12d292016-06-02 14:46:10 +0100158 // 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000165 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
166};
167
168} // namespace internal
169} // namespace v8
170
171#endif // V8_DEBUG_DEBUG_SCOPES_H_