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