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