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