| // 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); |
| |
| MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails(); |
| |
| // More scopes? |
| bool Done() { return context_.is_null(); } |
| |
| // 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(); |
| |
| // Return function which represents closure for current scope. |
| Handle<JSFunction> GetClosure(); |
| int start_position(); |
| int end_position(); |
| |
| #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_ = nullptr; |
| Handle<JSGeneratorObject> generator_; |
| Handle<Context> context_; |
| std::vector<ExtendedScopeInfo> nested_scope_chain_; |
| Handle<StringSet> non_locals_; |
| bool seen_script_scope_; |
| |
| inline JavaScriptFrame* GetFrame() { |
| return frame_inspector_->GetArgumentsFrame(); |
| } |
| |
| Handle<Context> GetContext(); |
| Handle<JSFunction> GetFunction(); |
| int GetSourcePosition(); |
| |
| void MaterializeStackLocals(Handle<JSObject> local_scope, |
| Handle<ScopeInfo> scope_info); |
| |
| void TryParseAndRetrieveScopes(ScopeIterator::Option option); |
| |
| 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); |
| bool SetModuleVariableValue(Handle<String> variable_name, |
| Handle<Object> new_value); |
| |
| // Helper functions. |
| bool SetParameterValue(Handle<ScopeInfo> scope_info, |
| 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); |
| |
| bool HasNestedScopeChain(); |
| ExtendedScopeInfo& LastNestedScopeChain(); |
| |
| DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); |
| }; |
| |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_DEBUG_DEBUG_SCOPES_H_ |