blob: 4e95fc4ba4c2d287ab465e0219ca598068e066ac [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,
28 ScopeTypeModule
29 };
30
31 static const int kScopeDetailsTypeIndex = 0;
32 static const int kScopeDetailsObjectIndex = 1;
33 static const int kScopeDetailsNameIndex = 2;
Ben Murdochda12d292016-06-02 14:46:10 +010034 static const int kScopeDetailsStartPositionIndex = 3;
35 static const int kScopeDetailsEndPositionIndex = 4;
36 static const int kScopeDetailsFunctionIndex = 5;
37 static const int kScopeDetailsSize = 6;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000038
39 enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS };
40
41 ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
42 Option options = DEFAULT);
43
44 ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
45
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails();
47
48 // More scopes?
49 bool Done() {
50 DCHECK(!failed_);
51 return context_.is_null();
52 }
53
54 bool Failed() { return failed_; }
55
56 // Move to the next scope.
57 void Next();
58
59 // Return the type of the current scope.
60 ScopeType Type();
61
62 // Return the JavaScript object with the content of the current scope.
63 MaybeHandle<JSObject> ScopeObject();
64
65 bool HasContext();
66
67 // Set variable value and return true on success.
68 bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value);
69
70 Handle<ScopeInfo> CurrentScopeInfo();
71
72 // Return the context for this scope. For the local context there might not
73 // be an actual context.
74 Handle<Context> CurrentContext();
75
Ben Murdochda12d292016-06-02 14:46:10 +010076 // Populate the set with collected non-local variable names.
77 Handle<StringSet> GetNonLocals();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078
79#ifdef DEBUG
80 // Debug print of the content of the current scope.
81 void DebugPrint();
82#endif
83
84 private:
Ben Murdochda12d292016-06-02 14:46:10 +010085 struct ExtendedScopeInfo {
86 ExtendedScopeInfo(Handle<ScopeInfo> info, int start, int end)
87 : scope_info(info), start_position(start), end_position(end) {}
88 Handle<ScopeInfo> scope_info;
89 int start_position;
90 int end_position;
91 };
92
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000093 Isolate* isolate_;
94 FrameInspector* const frame_inspector_;
95 Handle<Context> context_;
Ben Murdochda12d292016-06-02 14:46:10 +010096 List<ExtendedScopeInfo> nested_scope_chain_;
97 Handle<StringSet> non_locals_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000098 bool seen_script_scope_;
99 bool failed_;
100
101 inline JavaScriptFrame* GetFrame() {
102 return frame_inspector_->GetArgumentsFrame();
103 }
104
105 inline Handle<JSFunction> GetFunction() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100106 return Handle<JSFunction>::cast(frame_inspector_->GetFunction());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 }
108
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000109 void RetrieveScopeChain(Scope* scope);
110
111 void CollectNonLocals(Scope* scope);
112
Ben Murdochda12d292016-06-02 14:46:10 +0100113 void UnwrapEvaluationContext();
114
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000115 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScriptScope();
116 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeLocalScope();
117 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeModuleScope();
118 Handle<JSObject> MaterializeClosure();
119 Handle<JSObject> MaterializeCatchScope();
120 Handle<JSObject> MaterializeBlockScope();
Ben Murdochda12d292016-06-02 14:46:10 +0100121 Handle<JSObject> WithContextExtension();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122
123 bool SetLocalVariableValue(Handle<String> variable_name,
124 Handle<Object> new_value);
125 bool SetBlockVariableValue(Handle<String> variable_name,
126 Handle<Object> new_value);
127 bool SetClosureVariableValue(Handle<String> variable_name,
128 Handle<Object> new_value);
129 bool SetScriptVariableValue(Handle<String> variable_name,
130 Handle<Object> new_value);
131 bool SetCatchVariableValue(Handle<String> variable_name,
132 Handle<Object> new_value);
133 bool SetContextLocalValue(Handle<ScopeInfo> scope_info,
134 Handle<Context> context,
135 Handle<String> variable_name,
136 Handle<Object> new_value);
137
138 void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
139 Handle<Context> context,
140 Handle<JSObject> scope_object);
141 bool CopyContextExtensionToScopeObject(Handle<JSObject> extension,
142 Handle<JSObject> scope_object,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100143 KeyCollectionType type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144
Ben Murdochda12d292016-06-02 14:46:10 +0100145 // Get the chain of nested scopes within this scope for the source statement
146 // position. The scopes will be added to the list from the outermost scope to
147 // the innermost scope. Only nested block, catch or with scopes are tracked
148 // and will be returned, but no inner function scopes.
149 void GetNestedScopeChain(Isolate* isolate, Scope* scope,
150 int statement_position);
151
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
153};
154
155} // namespace internal
156} // namespace v8
157
158#endif // V8_DEBUG_DEBUG_SCOPES_H_