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/parsing/parse-info.h" 10 11 namespace v8 { 12 namespace internal { 13 14 class JavaScriptFrame; 15 class ParseInfo; 16 17 // Iterate over the actual scopes visible from a stack frame or from a closure. 18 // The iteration proceeds from the innermost visible nested scope outwards. 19 // All scopes are backed by an actual context except the local scope, 20 // which is inserted "artificially" in the context chain. 21 class ScopeIterator { 22 public: 23 enum ScopeType { 24 ScopeTypeGlobal = 0, 25 ScopeTypeLocal, 26 ScopeTypeWith, 27 ScopeTypeClosure, 28 ScopeTypeCatch, 29 ScopeTypeBlock, 30 ScopeTypeScript, 31 ScopeTypeEval, 32 ScopeTypeModule 33 }; 34 35 static const int kScopeDetailsTypeIndex = 0; 36 static const int kScopeDetailsObjectIndex = 1; 37 static const int kScopeDetailsNameIndex = 2; 38 static const int kScopeDetailsStartPositionIndex = 3; 39 static const int kScopeDetailsEndPositionIndex = 4; 40 static const int kScopeDetailsFunctionIndex = 5; 41 static const int kScopeDetailsSize = 6; 42 43 enum class ReparseStrategy { 44 kScript, 45 kFunctionLiteral, 46 }; 47 48 ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, 49 ReparseStrategy strategy); 50 51 ScopeIterator(Isolate* isolate, Handle<JSFunction> function); 52 ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator); 53 ~ScopeIterator(); 54 55 Handle<JSObject> MaterializeScopeDetails(); 56 57 // More scopes? Done()58 bool Done() const { return context_.is_null(); } 59 60 // Move to the next scope. 61 void Next(); 62 63 // Restart to the first scope and context. 64 void Restart(); 65 66 // Return the type of the current scope. 67 ScopeType Type() const; 68 69 // Indicates which variables should be visited. Either only variables from the 70 // scope that are available on the stack, or all variables. 71 enum class Mode { STACK, ALL }; 72 73 // Return the JavaScript object with the content of the current scope. 74 Handle<JSObject> ScopeObject(Mode mode); 75 76 // Returns whether the current scope declares any variables. 77 bool DeclaresLocals(Mode mode) const; 78 79 // Set variable value and return true on success. 80 bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value); 81 82 bool ClosureScopeHasThisReference() const; 83 84 // Populate the set with collected non-local variable names. GetLocals()85 Handle<StringSet> GetLocals() { return locals_; } 86 87 // Similar to JSFunction::GetName return the function's name or it's inferred 88 // name. 89 Handle<Object> GetFunctionDebugName() const; 90 GetScript()91 Handle<Script> GetScript() const { return script_; } 92 93 bool HasPositionInfo(); 94 int start_position(); 95 int end_position(); 96 97 #ifdef DEBUG 98 // Debug print of the content of the current scope. 99 void DebugPrint(); 100 #endif 101 InInnerScope()102 bool InInnerScope() const { return !function_.is_null(); } 103 bool HasContext() const; 104 bool NeedsAndHasContext() const; CurrentContext()105 Handle<Context> CurrentContext() const { 106 DCHECK(HasContext()); 107 return context_; 108 } 109 110 private: 111 Isolate* isolate_; 112 std::unique_ptr<ReusableUnoptimizedCompileState> reusable_compile_state_; 113 std::unique_ptr<ParseInfo> info_; 114 FrameInspector* const frame_inspector_ = nullptr; 115 Handle<JSGeneratorObject> generator_; 116 117 // The currently-executing function from the inspected frame, or null if this 118 // ScopeIterator has already iterated to any Scope outside that function. 119 Handle<JSFunction> function_; 120 121 Handle<Context> context_; 122 Handle<Script> script_; 123 Handle<StringSet> locals_; 124 DeclarationScope* closure_scope_ = nullptr; 125 Scope* start_scope_ = nullptr; 126 Scope* current_scope_ = nullptr; 127 bool seen_script_scope_ = false; 128 GetFrame()129 inline JavaScriptFrame* GetFrame() const { 130 return frame_inspector_->javascript_frame(); 131 } 132 133 void AdvanceOneScope(); 134 void AdvanceToNonHiddenScope(); 135 void AdvanceContext(); 136 void CollectLocalsFromCurrentScope(); 137 138 int GetSourcePosition(); 139 140 void TryParseAndRetrieveScopes(ReparseStrategy strategy); 141 142 void UnwrapEvaluationContext(); 143 144 using Visitor = std::function<bool(Handle<String> name, Handle<Object> value, 145 ScopeType scope_type)>; 146 147 Handle<JSObject> WithContextExtension(); 148 149 bool SetLocalVariableValue(Handle<String> variable_name, 150 Handle<Object> new_value); 151 bool SetContextVariableValue(Handle<String> variable_name, 152 Handle<Object> new_value); 153 bool SetContextExtensionValue(Handle<String> variable_name, 154 Handle<Object> new_value); 155 bool SetScriptVariableValue(Handle<String> variable_name, 156 Handle<Object> new_value); 157 bool SetModuleVariableValue(Handle<String> variable_name, 158 Handle<Object> new_value); 159 160 // Helper functions. 161 void VisitScope(const Visitor& visitor, Mode mode) const; 162 void VisitLocalScope(const Visitor& visitor, Mode mode, 163 ScopeType scope_type) const; 164 void VisitScriptScope(const Visitor& visitor) const; 165 void VisitModuleScope(const Visitor& visitor) const; 166 bool VisitLocals(const Visitor& visitor, Mode mode, 167 ScopeType scope_type) const; 168 bool VisitContextLocals(const Visitor& visitor, Handle<ScopeInfo> scope_info, 169 Handle<Context> context, ScopeType scope_type) const; 170 171 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); 172 }; 173 174 } // namespace internal 175 } // namespace v8 176 177 #endif // V8_DEBUG_DEBUG_SCOPES_H_ 178