• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/base/macros.h"
11 #include "src/common/globals.h"
12 #include "src/debug/debug-frames.h"
13 #include "src/debug/debug-scopes.h"
14 #include "src/debug/debug.h"
15 #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 namespace v8 {
21 namespace internal {
22 
23 class FrameInspector;
24 
25 class DebugEvaluate : public AllStatic {
26  public:
27   static V8_EXPORT_PRIVATE MaybeHandle<Object> Global(
28       Isolate* isolate, Handle<String> source, debug::EvaluateGlobalMode mode,
29       REPLMode repl_mode = REPLMode::kNo);
30 
31   static V8_EXPORT_PRIVATE MaybeHandle<Object> Global(
32       Isolate* isolate, Handle<JSFunction> function,
33       debug::EvaluateGlobalMode mode, REPLMode repl_mode = REPLMode::kNo);
34 
35   // Evaluate a piece of JavaScript in the context of a stack frame for
36   // debugging.  Things that need special attention are:
37   // - Parameters and stack-allocated locals need to be materialized.  Altered
38   //   values need to be written back to the stack afterwards.
39   // - The arguments object needs to materialized.
40   // The stack frame can be either a JavaScript stack frame or a Wasm
41   // stack frame. In the latter case, a special Debug Proxy API is
42   // provided to peek into the Wasm state.
43   static V8_EXPORT_PRIVATE MaybeHandle<Object> Local(Isolate* isolate,
44                                                      StackFrameId frame_id,
45                                                      int inlined_jsframe_index,
46                                                      Handle<String> source,
47                                                      bool throw_on_side_effect);
48 
49   // This is used for break-at-entry for builtins and API functions.
50   // Evaluate a piece of JavaScript in the native context, but with the
51   // materialized arguments object and receiver of the current call.
52   static MaybeHandle<Object> WithTopmostArguments(Isolate* isolate,
53                                                   Handle<String> source);
54 
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 #ifdef DEBUG
61   static void VerifyTransitiveBuiltins(Isolate* isolate);
62 #endif  // DEBUG
63 
64  private:
65   // This class builds a context chain for evaluation of expressions
66   // in debugger.
67   // The scope chain leading up to a breakpoint where evaluation occurs
68   // looks like:
69   // - [a mix of with, catch and block scopes]
70   //    - [function stack + context]
71   //      - [outer context]
72   // The builder materializes all stack variables into properties of objects;
73   // the expression is then evaluated as if it is inside a series of 'with'
74   // statements using those objects. To this end, the builder builds a new
75   // context chain, based on a scope chain:
76   //   - every With and Catch scope begets a cloned context
77   //   - Block scope begets one or two contexts:
78   //       - if a block has context-allocated varaibles, its context is cloned
79   //       - stack locals are materizalized as a With context
80   //   - Local scope begets a With context for materizalized locals, chained to
81   //     original function context. Original function context is the end of
82   //     the chain.
83   class ContextBuilder {
84    public:
85     ContextBuilder(Isolate* isolate, JavaScriptFrame* frame,
86                    int inlined_jsframe_index);
87 
88     void UpdateValues();
89 
evaluation_context()90     Handle<Context> evaluation_context() const { return evaluation_context_; }
91     Handle<SharedFunctionInfo> outer_info() const;
92 
93    private:
94     struct ContextChainElement {
95       Handle<Context> wrapped_context;
96       Handle<JSObject> materialized_object;
97       Handle<StringSet> blocklist;
98     };
99 
100     Handle<Context> evaluation_context_;
101     std::vector<ContextChainElement> context_chain_;
102     Isolate* isolate_;
103     FrameInspector frame_inspector_;
104     ScopeIterator scope_iterator_;
105   };
106 
107   static MaybeHandle<Object> Evaluate(Isolate* isolate,
108                                       Handle<SharedFunctionInfo> outer_info,
109                                       Handle<Context> context,
110                                       Handle<Object> receiver,
111                                       Handle<String> source,
112                                       bool throw_on_side_effect);
113 };
114 
115 }  // namespace internal
116 }  // namespace v8
117 
118 #endif  // V8_DEBUG_DEBUG_EVALUATE_H_
119