debug-evaluate.h 4.66 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_DEBUG_DEBUG_EVALUATE_H_
#define V8_DEBUG_DEBUG_EVALUATE_H_

8 9
#include <vector>

10
#include "src/base/macros.h"
11
#include "src/common/globals.h"
12 13
#include "src/debug/debug-frames.h"
#include "src/debug/debug-scopes.h"
14 15
#include "src/debug/debug.h"
#include "src/execution/frames.h"
16
#include "src/objects/objects.h"
17
#include "src/objects/shared-function-info.h"
18
#include "src/objects/string-set.h"
19 20 21 22

namespace v8 {
namespace internal {

23 24
class FrameInspector;

25 26
class DebugEvaluate : public AllStatic {
 public:
27 28 29
  static V8_EXPORT_PRIVATE MaybeHandle<Object> Global(
      Isolate* isolate, Handle<String> source, debug::EvaluateGlobalMode mode,
      REPLMode repl_mode = REPLMode::kNo);
Simon Zünd's avatar
Simon Zünd committed
30

31 32 33 34
  static V8_EXPORT_PRIVATE MaybeHandle<Object> Global(
      Isolate* isolate, Handle<JSFunction> function,
      debug::EvaluateGlobalMode mode, REPLMode repl_mode = REPLMode::kNo);

35 36 37 38 39
  // Evaluate a piece of JavaScript in the context of a stack frame for
  // debugging.  Things that need special attention are:
  // - Parameters and stack-allocated locals need to be materialized.  Altered
  //   values need to be written back to the stack afterwards.
  // - The arguments object needs to materialized.
40 41 42
  // The stack frame can be either a JavaScript stack frame or a Wasm
  // stack frame. In the latter case, a special Debug Proxy API is
  // provided to peek into the Wasm state.
43 44 45 46 47
  static V8_EXPORT_PRIVATE MaybeHandle<Object> Local(Isolate* isolate,
                                                     StackFrameId frame_id,
                                                     int inlined_jsframe_index,
                                                     Handle<String> source,
                                                     bool throw_on_side_effect);
48

49 50 51 52 53 54
  // This is used for break-at-entry for builtins and API functions.
  // Evaluate a piece of JavaScript in the native context, but with the
  // materialized arguments object and receiver of the current call.
  static MaybeHandle<Object> WithTopmostArguments(Isolate* isolate,
                                                  Handle<String> source);

55
  static DebugInfo::SideEffectState FunctionGetSideEffectState(
56
      Isolate* isolate, Handle<SharedFunctionInfo> info);
57
  static void ApplySideEffectChecks(Handle<BytecodeArray> bytecode_array);
58
  static bool IsSideEffectFreeIntrinsic(Runtime::FunctionId id);
59

60 61 62 63
#ifdef DEBUG
  static void VerifyTransitiveBuiltins(Isolate* isolate);
#endif  // DEBUG

64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
 private:
  // This class builds a context chain for evaluation of expressions
  // in debugger.
  // The scope chain leading up to a breakpoint where evaluation occurs
  // looks like:
  // - [a mix of with, catch and block scopes]
  //    - [function stack + context]
  //      - [outer context]
  // The builder materializes all stack variables into properties of objects;
  // the expression is then evaluated as if it is inside a series of 'with'
  // statements using those objects. To this end, the builder builds a new
  // context chain, based on a scope chain:
  //   - every With and Catch scope begets a cloned context
  //   - Block scope begets one or two contexts:
  //       - if a block has context-allocated varaibles, its context is cloned
  //       - stack locals are materizalized as a With context
  //   - Local scope begets a With context for materizalized locals, chained to
  //     original function context. Original function context is the end of
  //     the chain.
  class ContextBuilder {
   public:
    ContextBuilder(Isolate* isolate, JavaScriptFrame* frame,
                   int inlined_jsframe_index);

    void UpdateValues();

90
    Handle<Context> evaluation_context() const { return evaluation_context_; }
91
    Handle<SharedFunctionInfo> outer_info() const;
92 93 94

   private:
    struct ContextChainElement {
95 96
      Handle<Context> wrapped_context;
      Handle<JSObject> materialized_object;
Dan Elphick's avatar
Dan Elphick committed
97
      Handle<StringSet> blocklist;
98 99
    };

100
    Handle<Context> evaluation_context_;
101
    std::vector<ContextChainElement> context_chain_;
102
    Isolate* isolate_;
103 104
    FrameInspector frame_inspector_;
    ScopeIterator scope_iterator_;
105 106 107 108 109 110
  };

  static MaybeHandle<Object> Evaluate(Isolate* isolate,
                                      Handle<SharedFunctionInfo> outer_info,
                                      Handle<Context> context,
                                      Handle<Object> receiver,
111 112
                                      Handle<String> source,
                                      bool throw_on_side_effect);
113 114 115 116 117 118
};

}  // namespace internal
}  // namespace v8

#endif  // V8_DEBUG_DEBUG_EVALUATE_H_