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