blob: fbdf632687320ba0c47c3ce7d982a8623aad1f86 [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;
34 static const int kScopeDetailsSize = 3;
35
36 enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS };
37
38 ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
39 Option options = DEFAULT);
40
41 ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
42
43 ~ScopeIterator() { delete non_locals_; }
44
45 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails();
46
47 // More scopes?
48 bool Done() {
49 DCHECK(!failed_);
50 return context_.is_null();
51 }
52
53 bool Failed() { return failed_; }
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 list with collected non-local variable names.
76 void GetNonLocals(List<Handle<String> >* list_out);
77
78 bool ThisIsNonLocal();
79
80#ifdef DEBUG
81 // Debug print of the content of the current scope.
82 void DebugPrint();
83#endif
84
85 private:
86 Isolate* isolate_;
87 FrameInspector* const frame_inspector_;
88 Handle<Context> context_;
89 List<Handle<ScopeInfo> > nested_scope_chain_;
90 HashMap* non_locals_;
91 bool seen_script_scope_;
92 bool failed_;
93
94 inline JavaScriptFrame* GetFrame() {
95 return frame_inspector_->GetArgumentsFrame();
96 }
97
98 inline Handle<JSFunction> GetFunction() {
Ben Murdoch097c5b22016-05-18 11:27:45 +010099 return Handle<JSFunction>::cast(frame_inspector_->GetFunction());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100 }
101
102 static bool InternalizedStringMatch(void* key1, void* key2) {
103 Handle<String> s1(reinterpret_cast<String**>(key1));
104 Handle<String> s2(reinterpret_cast<String**>(key2));
105 DCHECK(s1->IsInternalizedString());
106 DCHECK(s2->IsInternalizedString());
107 return s1.is_identical_to(s2);
108 }
109
110 void RetrieveScopeChain(Scope* scope);
111
112 void CollectNonLocals(Scope* scope);
113
114 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScriptScope();
115 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeLocalScope();
116 MUST_USE_RESULT MaybeHandle<JSObject> MaterializeModuleScope();
117 Handle<JSObject> MaterializeClosure();
118 Handle<JSObject> MaterializeCatchScope();
119 Handle<JSObject> MaterializeBlockScope();
120
121 bool SetLocalVariableValue(Handle<String> variable_name,
122 Handle<Object> new_value);
123 bool SetBlockVariableValue(Handle<String> variable_name,
124 Handle<Object> new_value);
125 bool SetClosureVariableValue(Handle<String> variable_name,
126 Handle<Object> new_value);
127 bool SetScriptVariableValue(Handle<String> variable_name,
128 Handle<Object> new_value);
129 bool SetCatchVariableValue(Handle<String> variable_name,
130 Handle<Object> new_value);
131 bool SetContextLocalValue(Handle<ScopeInfo> scope_info,
132 Handle<Context> context,
133 Handle<String> variable_name,
134 Handle<Object> new_value);
135
136 void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
137 Handle<Context> context,
138 Handle<JSObject> scope_object);
139 bool CopyContextExtensionToScopeObject(Handle<JSObject> extension,
140 Handle<JSObject> scope_object,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100141 KeyCollectionType type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142
143 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
144};
145
146} // namespace internal
147} // namespace v8
148
149#endif // V8_DEBUG_DEBUG_SCOPES_H_