1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug-evaluate.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/accessors.h" 8f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/compiler.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/contexts.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug-frames.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug-scopes.h" 12f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/debug/debug.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h" 14f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/globals.h" 1562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/interpreter/bytecode-array-iterator.h" 1662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/interpreter/bytecodes.h" 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic inline bool IsDebugContext(Isolate* isolate, Context* context) { 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return context->native_context() == *isolate->debug()->debug_context(); 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochMaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate, 2762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<String> source) { 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Handle the processing of break. 2962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DisableBreak disable_break_scope(isolate->debug()); 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Enter the top context from before the debugger was invoked. 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveContext save(isolate); 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveContext* top = &save; 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (top != NULL && IsDebugContext(isolate, *top->context())) { 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch top = top->prev(); 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (top != NULL) isolate->set_context(*top->context()); 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get the native context now set to the top context from before the 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // debugger was invoked. 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> context = isolate->native_context(); 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> receiver(context->global_proxy()); 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate); 4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Evaluate(isolate, outer_info, context, receiver, source, false); 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMaybeHandle<Object> DebugEvaluate::Local(Isolate* isolate, 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StackFrame::Id frame_id, 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int inlined_jsframe_index, 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> source, 5162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool throw_on_side_effect) { 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Handle the processing of break. 5362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DisableBreak disable_break_scope(isolate->debug()); 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get the frame where the debugging is performed. 56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StackTraceFrameIterator it(isolate, frame_id); 57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (!it.is_javascript()) return isolate->factory()->undefined_value(); 58f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch JavaScriptFrame* frame = it.javascript_frame(); 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Traverse the saved contexts chain to find the active context for the 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // selected frame. 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveContext* save = 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DebugFrameHelper::FindSavedContextForFrame(isolate, frame); 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SaveContext savex(isolate); 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate->set_context(*(save->context())); 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This is not a lot different than DebugEvaluate::Global, except that 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // variables accessible by the function we are evaluating from are 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // materialized and included on top of the native context. Changes to 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the materialized object are written back afterwards. 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Note that the native context is taken from the original context chain, 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // which may not be the current native context of the isolate. 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextBuilder context_builder(isolate, frame, inlined_jsframe_index); 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isolate->has_pending_exception()) return MaybeHandle<Object>(); 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Context> context = context_builder.evaluation_context(); 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> receiver(context->global_proxy()); 783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MaybeHandle<Object> maybe_result = 7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Evaluate(isolate, context_builder.outer_info(), context, receiver, source, 8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch throw_on_side_effect); 813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!maybe_result.is_null()) context_builder.UpdateValues(); 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return maybe_result; 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Compile and evaluate source for the given context. 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMaybeHandle<Object> DebugEvaluate::Evaluate( 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Handle<SharedFunctionInfo> outer_info, 8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<Context> context, Handle<Object> receiver, Handle<String> source, 9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool throw_on_side_effect) { 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSFunction> eval_fun; 92bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch ASSIGN_RETURN_ON_EXCEPTION( 93bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch isolate, eval_fun, 94f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Compiler::GetFunctionFromEval(source, outer_info, context, SLOPPY, 95f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch NO_PARSE_RESTRICTION, kNoSourcePosition, 9662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kNoSourcePosition, kNoSourcePosition), 97bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Object); 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> result; 10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch { 10162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch NoSideEffectScope no_side_effect(isolate, throw_on_side_effect); 10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ASSIGN_RETURN_ON_EXCEPTION( 10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isolate, result, Execution::Call(isolate, eval_fun, receiver, 0, NULL), 10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Object); 10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Skip the global proxy as it has no properties and always delegates to the 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // real global object. 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (result->IsJSGlobalProxy()) { 110109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PrototypeIterator iter(isolate, Handle<JSGlobalProxy>::cast(result)); 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(verwaest): This will crash when the global proxy is detached. 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch result = PrototypeIterator::GetCurrent<JSObject>(iter); 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return result; 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate, 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JavaScriptFrame* frame, 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int inlined_jsframe_index) 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : isolate_(isolate), 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch frame_(frame), 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inlined_jsframe_index_(inlined_jsframe_index) { 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); 126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<JSFunction> local_function = frame_inspector.GetFunction(); 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> outer_context(local_function->context()); 1283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch evaluation_context_ = outer_context; 1293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch outer_info_ = handle(local_function->shared()); 1303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Factory* factory = isolate->factory(); 1313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // To evaluate as if we were running eval at the point of the debug break, 1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // we reconstruct the context chain as follows: 1343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // - To make stack-allocated variables visible, we materialize them and 1353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // use a debug-evaluate context to wrap both the materialized object and 1363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the original context. 1373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // - We use the original context chain from the function context to the 1383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // native context. 1393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // - Between the function scope and the native context, we only resolve 1403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // variable names that the current function already uses. Only for these 1413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // names we can be sure that they will be correctly resolved. For the 1423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // rest, we only resolve to with, script, and native contexts. We use a 1433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // whitelist to implement that. 1443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Context::Lookup has special handling for debug-evaluate contexts: 1453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // - Look up in the materialized stack variables. 1463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // - Look up in the original context. 1473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // - Check the whitelist to find out whether to skip contexts during lookup. 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ScopeIterator::Option option = ScopeIterator::COLLECT_NON_LOCALS; 14962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (ScopeIterator it(isolate, &frame_inspector, option); !it.Done(); 15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it.Next()) { 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ScopeIterator::ScopeType scope_type = it.Type(); 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scope_type == ScopeIterator::ScopeTypeLocal) { 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(FUNCTION_SCOPE, it.CurrentScopeInfo()->scope_type()); 1543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> materialized = factory->NewJSObjectWithNullProto(); 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Context> local_context = 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it.HasContext() ? it.CurrentContext() : outer_context; 1573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<StringSet> non_locals = it.GetNonLocals(); 1583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MaterializeReceiver(materialized, local_context, local_function, 1593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch non_locals); 1603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch frame_inspector.MaterializeStackLocals(materialized, local_function); 1613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MaterializeArgumentsObject(materialized, local_function); 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextChainElement context_chain_element; 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context_chain_element.scope_info = it.CurrentScopeInfo(); 1643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_element.materialized_object = materialized; 1653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Non-locals that are already being referenced by the current function 1663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // are guaranteed to be correctly resolved. 1673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_element.whitelist = non_locals; 1683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (it.HasContext()) { 1693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_element.wrapped_context = it.CurrentContext(); 1703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context_chain_.Add(context_chain_element); 1723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch evaluation_context_ = outer_context; 1733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (scope_type == ScopeIterator::ScopeTypeCatch || 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scope_type == ScopeIterator::ScopeTypeWith) { 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextChainElement context_chain_element; 1773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Context> current_context = it.CurrentContext(); 1783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (!current_context->IsDebugEvaluateContext()) { 1793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_element.wrapped_context = current_context; 1803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch context_chain_.Add(context_chain_element); 182bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (scope_type == ScopeIterator::ScopeTypeBlock || 183bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch scope_type == ScopeIterator::ScopeTypeEval) { 1843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> materialized = factory->NewJSObjectWithNullProto(); 1853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch frame_inspector.MaterializeStackLocals(materialized, 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it.CurrentScopeInfo()); 1873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ContextChainElement context_chain_element; 1883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_element.scope_info = it.CurrentScopeInfo(); 1893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_element.materialized_object = materialized; 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (it.HasContext()) { 1913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_element.wrapped_context = it.CurrentContext(); 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_.Add(context_chain_element); 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch break; 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 1993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch for (int i = context_chain_.length() - 1; i >= 0; i--) { 200f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Handle<ScopeInfo> scope_info(ScopeInfo::CreateForWithScope( 201f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isolate, evaluation_context_->IsNativeContext() 202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ? Handle<ScopeInfo>::null() 203f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : Handle<ScopeInfo>(evaluation_context_->scope_info()))); 204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch scope_info->SetIsDebugEvaluateScope(); 2053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch evaluation_context_ = factory->NewDebugEvaluateContext( 206f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch evaluation_context_, scope_info, context_chain_[i].materialized_object, 2073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch context_chain_[i].wrapped_context, context_chain_[i].whitelist); 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid DebugEvaluate::ContextBuilder::UpdateValues() { 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(yangguo): remove updating values. 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < context_chain_.length(); i++) { 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextChainElement element = context_chain_[i]; 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!element.materialized_object.is_null()) { 2173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Write back potential changes to materialized stack locals to the stack. 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameInspector(frame_, inlined_jsframe_index_, isolate_) 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch .UpdateStackLocalsFromMaterializedObject(element.materialized_object, 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch element.scope_info); 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid DebugEvaluate::ContextBuilder::MaterializeArgumentsObject( 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> target, Handle<JSFunction> function) { 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Do not materialize the arguments object for eval or top-level code. 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Skip if "arguments" is already taken. 23062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (function->shared()->is_toplevel()) return; 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Maybe<bool> maybe = JSReceiver::HasOwnProperty( 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch target, isolate_->factory()->arguments_string()); 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(maybe.IsJust()); 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (maybe.FromJust()) return; 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // FunctionGetArguments can't throw an exception. 237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> arguments = Accessors::FunctionGetArguments(function); 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<String> arguments_str = isolate_->factory()->arguments_string(); 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject::SetOwnPropertyIgnoreAttributes(target, arguments_str, arguments, 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NONE) 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch .Check(); 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid DebugEvaluate::ContextBuilder::MaterializeReceiver( 2453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSObject> target, Handle<Context> local_context, 2463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<JSFunction> local_function, Handle<StringSet> non_locals) { 2473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<Object> recv = isolate_->factory()->undefined_value(); 2483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<String> name = isolate_->factory()->this_string(); 2493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (non_locals->Has(name)) { 2503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // 'this' is allocated in an outer context and is is already being 2513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // referenced by the current function, so it can be correctly resolved. 2523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return; 253bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else if (local_function->shared()->scope_info()->HasReceiver() && 25413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch !frame_->receiver()->IsTheHole(isolate_)) { 2553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch recv = handle(frame_->receiver(), isolate_); 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JSObject::SetOwnPropertyIgnoreAttributes(target, name, recv, NONE).Check(); 258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace { 26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { 26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch switch (id) { 26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Whitelist for intrinsics amd runtime functions. 26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Conversions. 26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kToInteger: 26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineToInteger: 26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kToObject: 26962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineToObject: 27062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kToString: 27162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineToString: 27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kToLength: 27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineToLength: 27462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kToNumber: 27562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Type checks. 27662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kIsJSReceiver: 27762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineIsJSReceiver: 27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kIsSmi: 27962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineIsSmi: 28062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kIsArray: 28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineIsArray: 28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kIsFunction: 28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kIsDate: 28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kIsJSProxy: 28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kIsRegExp: 28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kIsTypedArray: 28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Loads. 28862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kLoadLookupSlotForCall: 28962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Arrays. 29062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kArraySpeciesConstructor: 29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kNormalizeElements: 29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kGetArrayKeys: 29362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kHasComplexElements: 29462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kEstimateNumberOfElements: 29562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Errors. 29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kReThrow: 29762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kThrowReferenceError: 29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kThrowSymbolIteratorInvalid: 29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kThrowIteratorResultNotAnObject: 30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kNewTypeError: 30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Strings. 30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineStringCharCodeAt: 30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kStringCharCodeAt: 30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kStringIndexOf: 30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kStringReplaceOneCharWithString: 30662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kSubString: 30762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineSubString: 30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kRegExpInternalReplace: 30962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Literals. 31062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kCreateArrayLiteral: 31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kCreateObjectLiteral: 31262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kCreateRegExpLiteral: 31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Misc. 31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kForInPrepare: 31562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineCall: 31662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kCall: 31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kInlineMaxSmi: 31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Runtime::kMaxSmi: 31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return true; 32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch default: 32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_trace_side_effect_free_debug_evaluate) { 32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrintF("[debug-evaluate] intrinsic %s may cause side effect.\n", 32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Runtime::FunctionForId(id)->name); 32462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 32562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 32662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 32762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 32862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 32962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) { 33062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch typedef interpreter::Bytecode Bytecode; 33162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch typedef interpreter::Bytecodes Bytecodes; 33262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (Bytecodes::IsWithoutExternalSideEffects(bytecode)) return true; 33362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (Bytecodes::IsCallOrConstruct(bytecode)) return true; 33462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (Bytecodes::WritesBooleanToAccumulator(bytecode)) return true; 33562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (Bytecodes::IsJumpIfToBoolean(bytecode)) return true; 33662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (Bytecodes::IsPrefixScalingBytecode(bytecode)) return true; 33762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch switch (bytecode) { 33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Whitelist for bytecodes. 33962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Loads. 34062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kLdaLookupSlot: 34162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kLdaGlobal: 34262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kLdaNamedProperty: 34362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kLdaKeyedProperty: 34462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Arithmetics. 34562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kAdd: 34662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kAddSmi: 34762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kSub: 34862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kSubSmi: 34962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kMul: 35062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kDiv: 35162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kMod: 35262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kBitwiseAnd: 35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kBitwiseAndSmi: 35462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kBitwiseOr: 35562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kBitwiseOrSmi: 35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kBitwiseXor: 35762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kShiftLeft: 35862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kShiftLeftSmi: 35962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kShiftRight: 36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kShiftRightSmi: 36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kShiftRightLogical: 36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kInc: 36362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kDec: 36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kLogicalNot: 36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kToBooleanLogicalNot: 36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kTypeOf: 36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Contexts. 36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateBlockContext: 36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateCatchContext: 37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateFunctionContext: 37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateEvalContext: 37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateWithContext: 37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Literals. 37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateArrayLiteral: 37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateObjectLiteral: 37662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateRegExpLiteral: 37762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Allocations. 37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateClosure: 37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCreateUnmappedArguments: 38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Conversions. 38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kToObject: 38262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kToNumber: 38362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Misc. 38462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kForInPrepare: 38562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kForInContinue: 38662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kForInNext: 38762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kForInStep: 38862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kThrow: 38962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kReThrow: 39062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kIllegal: 39162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kCallJSRuntime: 39262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kStackCheck: 39362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kReturn: 39462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Bytecode::kSetPendingMessage: 39562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return true; 39662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch default: 39762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_trace_side_effect_free_debug_evaluate) { 39862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrintF("[debug-evaluate] bytecode %s may cause side effect.\n", 39962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Bytecodes::ToString(bytecode)); 40062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 40162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 40262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 40362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 40462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 40562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool BuiltinHasNoSideEffect(Builtins::Name id) { 40662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch switch (id) { 40762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Whitelist for builtins. 40862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Array builtins. 40962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kArrayCode: 41062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kArrayIndexOf: 41162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kArrayPrototypeValues: 41262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kArrayIncludes: 41362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kArrayPrototypeEntries: 41462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kArrayPrototypeKeys: 41562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kArrayForEach: 41662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Math builtins. 41762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathAbs: 41862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathAcos: 41962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathAcosh: 42062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathAsin: 42162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathAsinh: 42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathAtan: 42362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathAtanh: 42462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathAtan2: 42562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathCeil: 42662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathCbrt: 42762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathExpm1: 42862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathClz32: 42962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathCos: 43062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathCosh: 43162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathExp: 43262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathFloor: 43362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathFround: 43462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathHypot: 43562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathImul: 43662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathLog: 43762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathLog1p: 43862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathLog2: 43962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathLog10: 44062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathMax: 44162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathMin: 44262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathPow: 44362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathRandom: 44462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathRound: 44562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathSign: 44662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathSin: 44762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathSinh: 44862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathSqrt: 44962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathTan: 45062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathTanh: 45162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMathTrunc: 45262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Number builtins. 45362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberConstructor: 45462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberIsFinite: 45562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberIsInteger: 45662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberIsNaN: 45762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberIsSafeInteger: 45862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberParseFloat: 45962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberParseInt: 46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberPrototypeToExponential: 46162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberPrototypeToFixed: 46262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberPrototypeToPrecision: 46362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberPrototypeToString: 46462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kNumberPrototypeValueOf: 46562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // String builtins. Strings are immutable. 46662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringFromCharCode: 46762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringFromCodePoint: 46862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringConstructor: 46962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeCharAt: 47062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeCharCodeAt: 47162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeEndsWith: 47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeIncludes: 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeIndexOf: 47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeLastIndexOf: 47562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeStartsWith: 47662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeSubstr: 47762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeSubstring: 47862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeToString: 47962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeToLowerCase: 48062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeToUpperCase: 48162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeTrim: 48262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeTrimLeft: 48362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeTrimRight: 48462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kStringPrototypeValueOf: 48562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // JSON builtins. 48662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kJsonParse: 48762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kJsonStringify: 48862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Error builtins. 48962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMakeError: 49062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMakeTypeError: 49162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMakeSyntaxError: 49262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMakeRangeError: 49362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch case Builtins::kMakeURIError: 49462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return true; 49562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch default: 49662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_trace_side_effect_free_debug_evaluate) { 49762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrintF("[debug-evaluate] built-in %s may cause side effect.\n", 49862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Builtins::name(id)); 49962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 50062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 50162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 50262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 50362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 50462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic const Address accessors_with_no_side_effect[] = { 50562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Whitelist for accessors. 50662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FUNCTION_ADDR(Accessors::StringLengthGetter), 50762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FUNCTION_ADDR(Accessors::ArrayLengthGetter)}; 50862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 50962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} // anonymous namespace 51062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 51162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// static 51262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool DebugEvaluate::FunctionHasNoSideEffect(Handle<SharedFunctionInfo> info) { 51362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_trace_side_effect_free_debug_evaluate) { 51462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrintF("[debug-evaluate] Checking function %s for side effect.\n", 51562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch info->DebugName()->ToCString().get()); 51662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 51762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 51862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(info->is_compiled()); 51962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 52062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (info->HasBytecodeArray()) { 52162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Check bytecodes against whitelist. 52262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<BytecodeArray> bytecode_array(info->bytecode_array()); 52362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_trace_side_effect_free_debug_evaluate) bytecode_array->Print(); 52462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done(); 52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it.Advance()) { 52662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch interpreter::Bytecode bytecode = it.current_bytecode(); 52762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 52862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (interpreter::Bytecodes::IsCallRuntime(bytecode)) { 52962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Runtime::FunctionId id = 53062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch (bytecode == interpreter::Bytecode::kInvokeIntrinsic) 53162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ? it.GetIntrinsicIdOperand(0) 53262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : it.GetRuntimeIdOperand(0); 53362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (IntrinsicHasNoSideEffect(id)) continue; 53462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 53562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 53662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 53762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (BytecodeHasNoSideEffect(bytecode)) continue; 53862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 53962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Did not match whitelist. 54062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 54162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 54262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return true; 54362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 54462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Check built-ins against whitelist. 54562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int builtin_index = info->code()->builtin_index(); 54662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (builtin_index >= 0 && builtin_index < Builtins::builtin_count && 54762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch BuiltinHasNoSideEffect(static_cast<Builtins::Name>(builtin_index))) { 54862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return true; 54962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 55062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 55162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 55262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 55362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 55462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 55562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// static 55662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool DebugEvaluate::CallbackHasNoSideEffect(Address function_addr) { 55762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t i = 0; i < arraysize(accessors_with_no_side_effect); i++) { 55862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (function_addr == accessors_with_no_side_effect[i]) return true; 55962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 56062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 56162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (FLAG_trace_side_effect_free_debug_evaluate) { 56262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch PrintF("[debug-evaluate] API Callback at %p may cause side effect.\n", 56362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch reinterpret_cast<void*>(function_addr)); 56462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 56562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return false; 56662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 56762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 570