Line data Source code
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 void ApplySideEffectChecks(Handle<BytecodeArray> bytecode_array);
45 :
46 : #ifdef DEBUG
47 : static void VerifyTransitiveBuiltins(Isolate* isolate);
48 : #endif // DEBUG
49 :
50 : private:
51 : // This class builds a context chain for evaluation of expressions
52 : // in debugger.
53 : // The scope chain leading up to a breakpoint where evaluation occurs
54 : // looks like:
55 : // - [a mix of with, catch and block scopes]
56 : // - [function stack + context]
57 : // - [outer context]
58 : // The builder materializes all stack variables into properties of objects;
59 : // the expression is then evaluated as if it is inside a series of 'with'
60 : // statements using those objects. To this end, the builder builds a new
61 : // context chain, based on a scope chain:
62 : // - every With and Catch scope begets a cloned context
63 : // - Block scope begets one or two contexts:
64 : // - if a block has context-allocated varaibles, its context is cloned
65 : // - stack locals are materizalized as a With context
66 : // - Local scope begets a With context for materizalized locals, chained to
67 : // original function context. Original function context is the end of
68 : // the chain.
69 24334 : class ContextBuilder {
70 : public:
71 : ContextBuilder(Isolate* isolate, JavaScriptFrame* frame,
72 : int inlined_jsframe_index);
73 :
74 : void UpdateValues();
75 :
76 : Handle<Context> evaluation_context() const { return evaluation_context_; }
77 : Handle<SharedFunctionInfo> outer_info() const;
78 :
79 : private:
80 : struct ContextChainElement {
81 : Handle<Context> wrapped_context;
82 : Handle<JSObject> materialized_object;
83 : Handle<StringSet> whitelist;
84 : };
85 :
86 : Handle<Context> evaluation_context_;
87 : std::vector<ContextChainElement> context_chain_;
88 : Isolate* isolate_;
89 : FrameInspector frame_inspector_;
90 : ScopeIterator scope_iterator_;
91 : };
92 :
93 : static MaybeHandle<Object> Evaluate(Isolate* isolate,
94 : Handle<SharedFunctionInfo> outer_info,
95 : Handle<Context> context,
96 : Handle<Object> receiver,
97 : Handle<String> source,
98 : bool throw_on_side_effect);
99 : };
100 :
101 :
102 : } // namespace internal
103 : } // namespace v8
104 :
105 : #endif // V8_DEBUG_DEBUG_EVALUATE_H_
|