| // Copyright 2015 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef V8_DEBUG_DEBUG_SCOPES_H_ | |
| #define V8_DEBUG_DEBUG_SCOPES_H_ | |
| #include <vector> | |
| #include "src/debug/debug-frames.h" | |
| #include "src/frames.h" | |
| namespace v8 { | |
| namespace internal { | |
| class ParseInfo; | |
| // Iterate over the actual scopes visible from a stack frame or from a closure. | |
| // The iteration proceeds from the innermost visible nested scope outwards. | |
| // All scopes are backed by an actual context except the local scope, | |
| // which is inserted "artificially" in the context chain. | |
| class ScopeIterator { | |
| public: | |
| enum ScopeType { | |
| ScopeTypeGlobal = 0, | |
| ScopeTypeLocal, | |
| ScopeTypeWith, | |
| ScopeTypeClosure, | |
| ScopeTypeCatch, | |
| ScopeTypeBlock, | |
| ScopeTypeScript, | |
| ScopeTypeEval, | |
| ScopeTypeModule | |
| }; | |
| static const int kScopeDetailsTypeIndex = 0; | |
| static const int kScopeDetailsObjectIndex = 1; | |
| static const int kScopeDetailsNameIndex = 2; | |
| static const int kScopeDetailsStartPositionIndex = 3; | |
| static const int kScopeDetailsEndPositionIndex = 4; | |
| static const int kScopeDetailsFunctionIndex = 5; | |
| static const int kScopeDetailsSize = 6; | |
| enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS }; | |
| ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, | |
| Option options = DEFAULT); | |
| ScopeIterator(Isolate* isolate, Handle<JSFunction> function); | |
| ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator); | |
| ~ScopeIterator(); | |
| Handle<JSObject> MaterializeScopeDetails(); | |
| // More scopes? | |
| bool Done() const { return context_.is_null(); } | |
| // Move to the next scope. | |
| void Next(); | |
| // Restart to the first scope and context. | |
| void Restart(); | |
| // Return the type of the current scope. | |
| ScopeType Type() const; | |
| // Indicates which variables should be visited. Either only variables from the | |
| // scope that are available on the stack, or all variables. | |
| enum class Mode { STACK, ALL }; | |
| // Return the JavaScript object with the content of the current scope. | |
| Handle<JSObject> ScopeObject(Mode mode); | |
| // Returns whether the current scope declares any variables. | |
| bool DeclaresLocals(Mode mode) const; | |
| // Set variable value and return true on success. | |
| bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value); | |
| // Populate the set with collected non-local variable names. | |
| Handle<StringSet> GetNonLocals(); | |
| // Similar to JSFunction::GetName return the function's name or it's inferred | |
| // name. | |
| Handle<Object> GetFunctionDebugName() const; | |
| Handle<Script> GetScript() const { return script_; } | |
| bool HasPositionInfo(); | |
| int start_position(); | |
| int end_position(); | |
| #ifdef DEBUG | |
| // Debug print of the content of the current scope. | |
| void DebugPrint(); | |
| #endif | |
| bool InInnerScope() const { return !function_.is_null(); } | |
| bool HasContext() const; | |
| Handle<Context> CurrentContext() const { | |
| DCHECK(HasContext()); | |
| return context_; | |
| } | |
| private: | |
| Isolate* isolate_; | |
| ParseInfo* info_ = nullptr; | |
| FrameInspector* const frame_inspector_ = nullptr; | |
| Handle<JSGeneratorObject> generator_; | |
| Handle<JSFunction> function_; | |
| Handle<Context> context_; | |
| Handle<Script> script_; | |
| Handle<StringSet> non_locals_; | |
| DeclarationScope* closure_scope_ = nullptr; | |
| Scope* start_scope_ = nullptr; | |
| Scope* current_scope_ = nullptr; | |
| bool seen_script_scope_ = false; | |
| inline JavaScriptFrame* GetFrame() const { | |
| return frame_inspector_->javascript_frame(); | |
| } | |
| int GetSourcePosition(); | |
| void TryParseAndRetrieveScopes(ScopeIterator::Option option); | |
| void RetrieveScopeChain(DeclarationScope* scope); | |
| void UnwrapEvaluationContext(); | |
| typedef std::function<bool(Handle<String> name, Handle<Object> value)> | |
| Visitor; | |
| Handle<JSObject> WithContextExtension(); | |
| bool SetLocalVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetContextVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetContextExtensionValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetScriptVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetModuleVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| // Helper functions. | |
| void VisitScope(const Visitor& visitor, Mode mode) const; | |
| void VisitLocalScope(const Visitor& visitor, Mode mode) const; | |
| void VisitScriptScope(const Visitor& visitor) const; | |
| void VisitModuleScope(const Visitor& visitor) const; | |
| bool VisitLocals(const Visitor& visitor, Mode mode) const; | |
| bool VisitContextLocals(const Visitor& visitor, Handle<ScopeInfo> scope_info, | |
| Handle<Context> context) const; | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | |
| }; | |
| } // namespace internal | |
| } // namespace v8 | |
| #endif // V8_DEBUG_DEBUG_SCOPES_H_ |