| // 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 "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); | |
| MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails(); | |
| // More scopes? | |
| bool Done() { | |
| DCHECK(!failed_); | |
| return context_.is_null(); | |
| } | |
| bool Failed() { return failed_; } | |
| // Move to the next scope. | |
| void Next(); | |
| // Return the type of the current scope. | |
| ScopeType Type(); | |
| // Return the JavaScript object with the content of the current scope. | |
| MaybeHandle<JSObject> ScopeObject(); | |
| bool HasContext(); | |
| // Set variable value and return true on success. | |
| bool SetVariableValue(Handle<String> variable_name, Handle<Object> new_value); | |
| Handle<ScopeInfo> CurrentScopeInfo(); | |
| // Return the context for this scope. For the local context there might not | |
| // be an actual context. | |
| Handle<Context> CurrentContext(); | |
| // Populate the set with collected non-local variable names. | |
| Handle<StringSet> GetNonLocals(); | |
| #ifdef DEBUG | |
| // Debug print of the content of the current scope. | |
| void DebugPrint(); | |
| #endif | |
| private: | |
| struct ExtendedScopeInfo { | |
| ExtendedScopeInfo(Handle<ScopeInfo> info, int start, int end) | |
| : scope_info(info), start_position(start), end_position(end) {} | |
| explicit ExtendedScopeInfo(Handle<ScopeInfo> info) | |
| : scope_info(info), start_position(-1), end_position(-1) {} | |
| Handle<ScopeInfo> scope_info; | |
| int start_position; | |
| int end_position; | |
| bool is_hidden() { return start_position == -1 && end_position == -1; } | |
| }; | |
| Isolate* isolate_; | |
| FrameInspector* const frame_inspector_; | |
| Handle<Context> context_; | |
| List<ExtendedScopeInfo> nested_scope_chain_; | |
| Handle<StringSet> non_locals_; | |
| bool seen_script_scope_; | |
| bool failed_; | |
| inline JavaScriptFrame* GetFrame() { | |
| return frame_inspector_->GetArgumentsFrame(); | |
| } | |
| inline Handle<JSFunction> GetFunction() { | |
| return frame_inspector_->GetFunction(); | |
| } | |
| void RetrieveScopeChain(DeclarationScope* scope); | |
| void CollectNonLocals(ParseInfo* info, DeclarationScope* scope); | |
| void UnwrapEvaluationContext(); | |
| MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScriptScope(); | |
| MUST_USE_RESULT MaybeHandle<JSObject> MaterializeLocalScope(); | |
| MUST_USE_RESULT MaybeHandle<JSObject> MaterializeModuleScope(); | |
| Handle<JSObject> MaterializeClosure(); | |
| Handle<JSObject> MaterializeCatchScope(); | |
| Handle<JSObject> MaterializeInnerScope(); | |
| Handle<JSObject> WithContextExtension(); | |
| bool SetLocalVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetInnerScopeVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetClosureVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetScriptVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetCatchVariableValue(Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| // Helper functions. | |
| bool SetParameterValue(Handle<ScopeInfo> scope_info, JavaScriptFrame* frame, | |
| Handle<String> parameter_name, | |
| Handle<Object> new_value); | |
| bool SetStackVariableValue(Handle<ScopeInfo> scope_info, | |
| Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| bool SetContextVariableValue(Handle<ScopeInfo> scope_info, | |
| Handle<Context> context, | |
| Handle<String> variable_name, | |
| Handle<Object> new_value); | |
| void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info, | |
| Handle<Context> context, | |
| Handle<JSObject> scope_object); | |
| void CopyModuleVarsToScopeObject(Handle<ScopeInfo> scope_info, | |
| Handle<Context> context, | |
| Handle<JSObject> scope_object); | |
| void CopyContextExtensionToScopeObject(Handle<Context> context, | |
| Handle<JSObject> scope_object, | |
| KeyCollectionMode mode); | |
| // Get the chain of nested scopes within this scope for the source statement | |
| // position. The scopes will be added to the list from the outermost scope to | |
| // the innermost scope. Only nested block, catch or with scopes are tracked | |
| // and will be returned, but no inner function scopes. | |
| void GetNestedScopeChain(Isolate* isolate, Scope* scope, | |
| int statement_position); | |
| DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); | |
| }; | |
| } // namespace internal | |
| } // namespace v8 | |
| #endif // V8_DEBUG_DEBUG_SCOPES_H_ |