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