blob: d4e335a2a542a46f734b20f17b14cf63cb69992a [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() {
99 return Handle<JSFunction>(
100 JSFunction::cast(frame_inspector_->GetFunction()));
101 }
102
103 static bool InternalizedStringMatch(void* key1, void* key2) {
104 Handle<String> s1(reinterpret_cast<String**>(key1));
105 Handle<String> s2(reinterpret_cast<String**>(key2));
106 DCHECK(s1->IsInternalizedString());
107 DCHECK(s2->IsInternalizedString());
108 return s1.is_identical_to(s2);
109 }
110
111 void RetrieveScopeChain(Scope* scope);
112
113 void CollectNonLocals(Scope* scope);
114
115 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();
121
122 bool SetLocalVariableValue(Handle<String> variable_name,
123 Handle<Object> new_value);
124 bool SetBlockVariableValue(Handle<String> variable_name,
125 Handle<Object> new_value);
126 bool SetClosureVariableValue(Handle<String> variable_name,
127 Handle<Object> new_value);
128 bool SetScriptVariableValue(Handle<String> variable_name,
129 Handle<Object> new_value);
130 bool SetCatchVariableValue(Handle<String> variable_name,
131 Handle<Object> new_value);
132 bool SetContextLocalValue(Handle<ScopeInfo> scope_info,
133 Handle<Context> context,
134 Handle<String> variable_name,
135 Handle<Object> new_value);
136
137 void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
138 Handle<Context> context,
139 Handle<JSObject> scope_object);
140 bool CopyContextExtensionToScopeObject(Handle<JSObject> extension,
141 Handle<JSObject> scope_object,
142 JSReceiver::KeyCollectionType type);
143
144 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
145};
146
147} // namespace internal
148} // namespace v8
149
150#endif // V8_DEBUG_DEBUG_SCOPES_H_