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/frames.h" 10 11 namespace v8 { 12 namespace 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. 18 class 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_ 151