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