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