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 // Iterate over the actual scopes visible from a stack frame or from a closure.
     15 // The iteration proceeds from the innermost visible nested scope outwards.
     16 // All scopes are backed by an actual context except the local scope,
     17 // which is inserted "artificially" in the context chain.
     18 class ScopeIterator {
     19  public:
     20   enum ScopeType {
     21     ScopeTypeGlobal = 0,
     22     ScopeTypeLocal,
     23     ScopeTypeWith,
     24     ScopeTypeClosure,
     25     ScopeTypeCatch,
     26     ScopeTypeBlock,
     27     ScopeTypeScript,
     28     ScopeTypeModule
     29   };
     30 
     31   static const int kScopeDetailsTypeIndex = 0;
     32   static const int kScopeDetailsObjectIndex = 1;
     33   static const int kScopeDetailsNameIndex = 2;
     34   static const int kScopeDetailsSize = 3;
     35 
     36   enum Option { DEFAULT, IGNORE_NESTED_SCOPES, COLLECT_NON_LOCALS };
     37 
     38   ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector,
     39                 Option options = DEFAULT);
     40 
     41   ScopeIterator(Isolate* isolate, Handle<JSFunction> function);
     42 
     43   ~ScopeIterator() { delete non_locals_; }
     44 
     45   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScopeDetails();
     46 
     47   // More scopes?
     48   bool Done() {
     49     DCHECK(!failed_);
     50     return context_.is_null();
     51   }
     52 
     53   bool Failed() { return failed_; }
     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 list with collected non-local variable names.
     76   void GetNonLocals(List<Handle<String> >* list_out);
     77 
     78   bool ThisIsNonLocal();
     79 
     80 #ifdef DEBUG
     81   // Debug print of the content of the current scope.
     82   void DebugPrint();
     83 #endif
     84 
     85  private:
     86   Isolate* isolate_;
     87   FrameInspector* const frame_inspector_;
     88   Handle<Context> context_;
     89   List<Handle<ScopeInfo> > nested_scope_chain_;
     90   HashMap* non_locals_;
     91   bool seen_script_scope_;
     92   bool failed_;
     93 
     94   inline JavaScriptFrame* GetFrame() {
     95     return frame_inspector_->GetArgumentsFrame();
     96   }
     97 
     98   inline Handle<JSFunction> GetFunction() {
     99     return Handle<JSFunction>(
    100         JSFunction::cast(frame_inspector_->GetFunction()));
    101   }
    102 
    103   static bool InternalizedStringMatch(void* key1, void* key2) {
    104     Handle<String> s1(reinterpret_cast<String**>(key1));
    105     Handle<String> s2(reinterpret_cast<String**>(key2));
    106     DCHECK(s1->IsInternalizedString());
    107     DCHECK(s2->IsInternalizedString());
    108     return s1.is_identical_to(s2);
    109   }
    110 
    111   void RetrieveScopeChain(Scope* scope);
    112 
    113   void CollectNonLocals(Scope* scope);
    114 
    115   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeScriptScope();
    116   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeLocalScope();
    117   MUST_USE_RESULT MaybeHandle<JSObject> MaterializeModuleScope();
    118   Handle<JSObject> MaterializeClosure();
    119   Handle<JSObject> MaterializeCatchScope();
    120   Handle<JSObject> MaterializeBlockScope();
    121 
    122   bool SetLocalVariableValue(Handle<String> variable_name,
    123                              Handle<Object> new_value);
    124   bool SetBlockVariableValue(Handle<String> variable_name,
    125                              Handle<Object> new_value);
    126   bool SetClosureVariableValue(Handle<String> variable_name,
    127                                Handle<Object> new_value);
    128   bool SetScriptVariableValue(Handle<String> variable_name,
    129                               Handle<Object> new_value);
    130   bool SetCatchVariableValue(Handle<String> variable_name,
    131                              Handle<Object> new_value);
    132   bool SetContextLocalValue(Handle<ScopeInfo> scope_info,
    133                             Handle<Context> context,
    134                             Handle<String> variable_name,
    135                             Handle<Object> new_value);
    136 
    137   void CopyContextLocalsToScopeObject(Handle<ScopeInfo> scope_info,
    138                                       Handle<Context> context,
    139                                       Handle<JSObject> scope_object);
    140   bool CopyContextExtensionToScopeObject(Handle<JSObject> extension,
    141                                          Handle<JSObject> scope_object,
    142                                          JSReceiver::KeyCollectionType type);
    143 
    144   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
    145 };
    146 
    147 }  // namespace internal
    148 }  // namespace v8
    149 
    150 #endif  // V8_DEBUG_DEBUG_SCOPES_H_
    151