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 "src/debug/debug-frames.h"
      9 #include "src/frames.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 class ParseInfo;
     15 
     16 // Iterate over the actual scopes visible from a stack frame or from a closure.
     17 // The iteration proceeds from the innermost visible nested scope outwards.
     18 // All scopes are backed by an actual context except the local scope,
     19 // which is inserted "artificially" in the context chain.
     20 class ScopeIterator {
     21  public:
     22   enum ScopeType {
     23     ScopeTypeGlobal = 0,
     24     ScopeTypeLocal,
     25     ScopeTypeWith,
     26     ScopeTypeClosure,
     27     ScopeTypeCatch,
     28     ScopeTypeBlock,
     29     ScopeTypeScript,
     30     ScopeTypeEval,
     31     ScopeTypeModule
     32   };
     33 
     34   static const int kScopeDetailsTypeIndex = 0;
     35   static const int kScopeDetailsObjectIndex = 1;
     36   static const int kScopeDetailsNameIndex = 2;
     37   static const int kScopeDetailsStartPositionIndex = 3;
     38   static const int kScopeDetailsEndPositionIndex = 4;
     39   static const int kScopeDetailsFunctionIndex = 5;
     40   static const int kScopeDetailsSize = 6;
     41 
     42   enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS };
     43 
     44   ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
     45                 Option options = DEFAULT);
     46 
     47   ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
     48   ScopeIterator(Isolate* isolate, Handle<JSGeneratorObject> generator);
     49 
     50   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails();
     51 
     52   // More scopes?
     53   bool Done() { return context_.is_null(); }
     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 set with collected non-local variable names.
     76   Handle<StringSet> GetNonLocals();
     77 
     78 #ifdef DEBUG
     79   // Debug print of the content of the current scope.
     80   void DebugPrint();
     81 #endif
     82 
     83  private:
     84   struct ExtendedScopeInfo {
     85     ExtendedScopeInfo(Handle<ScopeInfo> info, int start, int end)
     86         : scope_info(info), start_position(start), end_position(end) {}
     87     explicit ExtendedScopeInfo(Handle<ScopeInfo> info)
     88         : scope_info(info), start_position(-1), end_position(-1) {}
     89     Handle<ScopeInfo> scope_info;
     90     int start_position;
     91     int end_position;
     92     bool is_hidden() { return start_position == -1 && end_position == -1; }
     93   };
     94 
     95   Isolate* isolate_;
     96   FrameInspector* const frame_inspector_;
     97   Handle<Context> context_;
     98   List<ExtendedScopeInfo> nested_scope_chain_;
     99   Handle<StringSet> non_locals_;
    100   bool seen_script_scope_;
    101 
    102   inline JavaScriptFrame* GetFrame() {
    103     return frame_inspector_->GetArgumentsFrame();
    104   }
    105 
    106   inline Handle<JSFunction> GetFunction() {
    107     return frame_inspector_->GetFunction();
    108   }
    109 
    110   void RetrieveScopeChain(DeclarationScope* scope);
    111 
    112   void CollectNonLocals(ParseInfo* info, DeclarationScope* scope);
    113 
    114   void UnwrapEvaluationContext();
    115 
    116   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScriptScope();
    117   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeLocalScope();
    118   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeModuleScope();
    119   Handle<JSObject> MaterializeClosure();
    120   Handle<JSObject> MaterializeCatchScope();
    121   Handle<JSObject> MaterializeInnerScope();
    122   Handle<JSObject> WithContextExtension();
    123 
    124   bool SetLocalVariableValue(Handle<String> variable_name,
    125                              Handle<Object> new_value);
    126   bool SetInnerScopeVariableValue(Handle<String> variable_name,
    127                                   Handle<Object> new_value);
    128   bool SetClosureVariableValue(Handle<String> variable_name,
    129                                Handle<Object> new_value);
    130   bool SetScriptVariableValue(Handle<String> variable_name,
    131                               Handle<Object> new_value);
    132   bool SetCatchVariableValue(Handle<String> variable_name,
    133                              Handle<Object> new_value);
    134 
    135   // Helper functions.
    136   bool SetParameterValue(Handle<ScopeInfo> scope_info, JavaScriptFrame* frame,
    137                          Handle<String> parameter_name,
    138                          Handle<Object> new_value);
    139   bool SetStackVariableValue(Handle<ScopeInfo> scope_info,
    140                              Handle<String> variable_name,
    141                              Handle<Object> new_value);
    142   bool SetContextVariableValue(Handle<ScopeInfo> scope_info,
    143                                Handle<Context> context,
    144                                Handle<String> variable_name,
    145                                Handle<Object> new_value);
    146 
    147   void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
    148                                       Handle<Context> context,
    149                                       Handle<JSObject> scope_object);
    150   void CopyModuleVarsToScopeObject(Handle<ScopeInfo> scope_info,
    151                                    Handle<Context> context,
    152                                    Handle<JSObject> scope_object);
    153   void CopyContextExtensionToScopeObject(Handle<Context> context,
    154                                          Handle<JSObject> scope_object,
    155                                          KeyCollectionMode mode);
    156 
    157   // Get the chain of nested scopes within this scope for the source statement
    158   // position. The scopes will be added to the list from the outermost scope to
    159   // the innermost scope. Only nested block, catch or with scopes are tracked
    160   // and will be returned, but no inner function scopes.
    161   void GetNestedScopeChain(Isolate* isolate, Scope* scope,
    162                            int statement_position);
    163 
    164   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
    165 };
    166 
    167 }  // namespace internal
    168 }  // namespace v8
    169 
    170 #endif  // V8_DEBUG_DEBUG_SCOPES_H_
    171