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_EVALUATE_H_
      6 #define V8_DEBUG_DEBUG_EVALUATE_H_
      7 
      8 #include "src/frames.h"
      9 #include "src/objects.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 class DebugEvaluate : public AllStatic {
     15  public:
     16   static MaybeHandle<Object> Global(Isolate* isolate, Handle<String> source,
     17                                     bool disable_break,
     18                                     Handle<HeapObject> context_extension);
     19 
     20   // Evaluate a piece of JavaScript in the context of a stack frame for
     21   // debugging.  Things that need special attention are:
     22   // - Parameters and stack-allocated locals need to be materialized.  Altered
     23   //   values need to be written back to the stack afterwards.
     24   // - The arguments object needs to materialized.
     25   static MaybeHandle<Object> Local(Isolate* isolate, StackFrame::Id frame_id,
     26                                    int inlined_jsframe_index,
     27                                    Handle<String> source, bool disable_break,
     28                                    Handle<HeapObject> context_extension);
     29 
     30  private:
     31   // This class builds a context chain for evaluation of expressions
     32   // in debugger.
     33   // The scope chain leading up to a breakpoint where evaluation occurs
     34   // looks like:
     35   // - [a mix of with, catch and block scopes]
     36   //    - [function stack + context]
     37   //      - [outer context]
     38   // The builder materializes all stack variables into properties of objects;
     39   // the expression is then evaluated as if it is inside a series of 'with'
     40   // statements using those objects. To this end, the builder builds a new
     41   // context chain, based on a scope chain:
     42   //   - every With and Catch scope begets a cloned context
     43   //   - Block scope begets one or two contexts:
     44   //       - if a block has context-allocated varaibles, its context is cloned
     45   //       - stack locals are materizalized as a With context
     46   //   - Local scope begets a With context for materizalized locals, chained to
     47   //     original function context. Original function context is the end of
     48   //     the chain.
     49   class ContextBuilder {
     50    public:
     51     ContextBuilder(Isolate* isolate, JavaScriptFrame* frame,
     52                    int inlined_jsframe_index);
     53 
     54     void UpdateValues();
     55 
     56     Handle<Context> evaluation_context() const { return evaluation_context_; }
     57     Handle<SharedFunctionInfo> outer_info() const { return outer_info_; }
     58 
     59    private:
     60     struct ContextChainElement {
     61       Handle<ScopeInfo> scope_info;
     62       Handle<Context> wrapped_context;
     63       Handle<JSObject> materialized_object;
     64       Handle<StringSet> whitelist;
     65     };
     66 
     67     // Helper function to find or create the arguments object for
     68     // Runtime_DebugEvaluate.
     69     void MaterializeArgumentsObject(Handle<JSObject> target,
     70                                     Handle<JSFunction> function);
     71 
     72     void MaterializeReceiver(Handle<JSObject> target,
     73                              Handle<Context> local_context,
     74                              Handle<JSFunction> local_function,
     75                              Handle<StringSet> non_locals);
     76 
     77     Handle<SharedFunctionInfo> outer_info_;
     78     Handle<Context> evaluation_context_;
     79     List<ContextChainElement> context_chain_;
     80     Isolate* isolate_;
     81     JavaScriptFrame* frame_;
     82     int inlined_jsframe_index_;
     83   };
     84 
     85   static MaybeHandle<Object> Evaluate(Isolate* isolate,
     86                                       Handle<SharedFunctionInfo> outer_info,
     87                                       Handle<Context> context,
     88                                       Handle<HeapObject> context_extension,
     89                                       Handle<Object> receiver,
     90                                       Handle<String> source);
     91 };
     92 
     93 
     94 }  // namespace internal
     95 }  // namespace v8
     96 
     97 #endif  // V8_DEBUG_DEBUG_EVALUATE_H_
     98