Home | History | Annotate | Download | only in debug
      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?
     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 
     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 
     98   bool InInnerScope() const { return !function_.is_null(); }
     99   bool HasContext() const;
    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 
    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