diff --git a/src/debug/debug-evaluate.cc b/src/debug/debug-evaluate.cc
new file mode 100644
index 0000000..e19b93e
--- /dev/null
+++ b/src/debug/debug-evaluate.cc
@@ -0,0 +1,407 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/debug/debug-evaluate.h"
+
+#include "src/accessors.h"
+#include "src/contexts.h"
+#include "src/debug/debug.h"
+#include "src/debug/debug-frames.h"
+#include "src/debug/debug-scopes.h"
+#include "src/frames-inl.h"
+#include "src/isolate-inl.h"
+
+namespace v8 {
+namespace internal {
+
+static inline bool IsDebugContext(Isolate* isolate, Context* context) {
+  return context->native_context() == *isolate->debug()->debug_context();
+}
+
+
+MaybeHandle<Object> DebugEvaluate::Global(
+    Isolate* isolate, Handle<String> source, bool disable_break,
+    Handle<HeapObject> context_extension) {
+  // Handle the processing of break.
+  DisableBreak disable_break_scope(isolate->debug(), disable_break);
+
+  // Enter the top context from before the debugger was invoked.
+  SaveContext save(isolate);
+  SaveContext* top = &save;
+  while (top != NULL && IsDebugContext(isolate, *top->context())) {
+    top = top->prev();
+  }
+  if (top != NULL) isolate->set_context(*top->context());
+
+  // Get the native context now set to the top context from before the
+  // debugger was invoked.
+  Handle<Context> context = isolate->native_context();
+  Handle<JSObject> receiver(context->global_proxy());
+  Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
+  return Evaluate(isolate, outer_info, context, context_extension, receiver,
+                  source);
+}
+
+
+MaybeHandle<Object> DebugEvaluate::Local(Isolate* isolate,
+                                         StackFrame::Id frame_id,
+                                         int inlined_jsframe_index,
+                                         Handle<String> source,
+                                         bool disable_break,
+                                         Handle<HeapObject> context_extension) {
+  // Handle the processing of break.
+  DisableBreak disable_break_scope(isolate->debug(), disable_break);
+
+  // Get the frame where the debugging is performed.
+  JavaScriptFrameIterator it(isolate, frame_id);
+  JavaScriptFrame* frame = it.frame();
+
+  // Traverse the saved contexts chain to find the active context for the
+  // selected frame.
+  SaveContext* save =
+      DebugFrameHelper::FindSavedContextForFrame(isolate, frame);
+  SaveContext savex(isolate);
+  isolate->set_context(*(save->context()));
+
+  // This is not a lot different than DebugEvaluate::Global, except that
+  // variables accessible by the function we are evaluating from are
+  // materialized and included on top of the native context. Changes to
+  // the materialized object are written back afterwards.
+  // Note that the native context is taken from the original context chain,
+  // which may not be the current native context of the isolate.
+  ContextBuilder context_builder(isolate, frame, inlined_jsframe_index);
+  if (isolate->has_pending_exception()) return MaybeHandle<Object>();
+
+  Handle<Context> context = context_builder.native_context();
+  Handle<JSObject> receiver(context->global_proxy());
+  MaybeHandle<Object> maybe_result = Evaluate(
+      isolate, context_builder.outer_info(),
+      context_builder.innermost_context(), context_extension, receiver, source);
+  if (!maybe_result.is_null() && !FLAG_debug_eval_readonly_locals) {
+    context_builder.UpdateValues();
+  }
+  return maybe_result;
+}
+
+
+// Compile and evaluate source for the given context.
+MaybeHandle<Object> DebugEvaluate::Evaluate(
+    Isolate* isolate, Handle<SharedFunctionInfo> outer_info,
+    Handle<Context> context, Handle<HeapObject> context_extension,
+    Handle<Object> receiver, Handle<String> source) {
+  if (context_extension->IsJSObject()) {
+    Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
+    Handle<JSFunction> closure(context->closure(), isolate);
+    context = isolate->factory()->NewWithContext(closure, context, extension);
+  }
+
+  Handle<JSFunction> eval_fun;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_fun,
+                             Compiler::GetFunctionFromEval(
+                                 source, outer_info, context, SLOPPY,
+                                 NO_PARSE_RESTRICTION, RelocInfo::kNoPosition),
+                             Object);
+
+  Handle<Object> result;
+  ASSIGN_RETURN_ON_EXCEPTION(
+      isolate, result, Execution::Call(isolate, eval_fun, receiver, 0, NULL),
+      Object);
+
+  // Skip the global proxy as it has no properties and always delegates to the
+  // real global object.
+  if (result->IsJSGlobalProxy()) {
+    PrototypeIterator iter(isolate, result);
+    // TODO(verwaest): This will crash when the global proxy is detached.
+    result = PrototypeIterator::GetCurrent<JSObject>(iter);
+  }
+
+  return result;
+}
+
+
+DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
+                                              JavaScriptFrame* frame,
+                                              int inlined_jsframe_index)
+    : isolate_(isolate),
+      frame_(frame),
+      inlined_jsframe_index_(inlined_jsframe_index) {
+  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
+  Handle<JSFunction> local_function =
+      handle(JSFunction::cast(frame_inspector.GetFunction()));
+  Handle<Context> outer_context(local_function->context());
+  native_context_ = Handle<Context>(outer_context->native_context());
+  Handle<JSFunction> global_function(native_context_->closure());
+  outer_info_ = handle(global_function->shared());
+  Handle<Context> inner_context;
+
+  bool stop = false;
+
+  // Iterate the original context chain to create a context chain that reflects
+  // our needs. The original context chain may look like this:
+  // <native context> <outer contexts> <function context> <inner contexts>
+  // In the resulting context chain, we want to materialize the receiver,
+  // the parameters of the current function, the stack locals. We only
+  // materialize context variables that the function already references,
+  // because only for those variables we can be sure that they will be resolved
+  // correctly. Variables that are not referenced by the function may be
+  // context-allocated and thus accessible, but may be shadowed by stack-
+  // allocated variables and the resolution would be incorrect.
+  // The result will look like this:
+  // <native context> <receiver context>
+  //     <materialized stack and accessible context vars> <inner contexts>
+  // All contexts use the closure of the native context, since there is no
+  // function context in the chain. Variables that cannot be resolved are
+  // bound to toplevel (script contexts or global object).
+  // Once debug-evaluate has been executed, the changes to the materialized
+  // objects are written back to the original context chain. Any changes to
+  // the original context chain will therefore be overwritten.
+  const ScopeIterator::Option option = ScopeIterator::COLLECT_NON_LOCALS;
+  for (ScopeIterator it(isolate, &frame_inspector, option);
+       !it.Failed() && !it.Done() && !stop; it.Next()) {
+    ScopeIterator::ScopeType scope_type = it.Type();
+    if (scope_type == ScopeIterator::ScopeTypeLocal) {
+      DCHECK_EQ(FUNCTION_SCOPE, it.CurrentScopeInfo()->scope_type());
+      it.GetNonLocals(&non_locals_);
+      Handle<Context> local_context =
+          it.HasContext() ? it.CurrentContext() : outer_context;
+
+      // The "this" binding, if any, can't be bound via "with".  If we need
+      // to, add another node onto the outer context to bind "this".
+      Handle<Context> receiver_context =
+          MaterializeReceiver(native_context_, local_context, local_function,
+                              global_function, it.ThisIsNonLocal());
+
+      Handle<JSObject> materialized_function = NewJSObjectWithNullProto();
+      frame_inspector.MaterializeStackLocals(materialized_function,
+                                             local_function);
+      MaterializeArgumentsObject(materialized_function, local_function);
+      MaterializeContextChain(materialized_function, local_context);
+
+      Handle<Context> with_context = isolate->factory()->NewWithContext(
+          global_function, receiver_context, materialized_function);
+
+      ContextChainElement context_chain_element;
+      context_chain_element.original_context = local_context;
+      context_chain_element.materialized_object = materialized_function;
+      context_chain_element.scope_info = it.CurrentScopeInfo();
+      context_chain_.Add(context_chain_element);
+
+      stop = true;
+      RecordContextsInChain(&inner_context, receiver_context, with_context);
+    } else if (scope_type == ScopeIterator::ScopeTypeCatch ||
+               scope_type == ScopeIterator::ScopeTypeWith) {
+      Handle<Context> cloned_context = Handle<Context>::cast(
+          isolate->factory()->CopyFixedArray(it.CurrentContext()));
+
+      ContextChainElement context_chain_element;
+      context_chain_element.original_context = it.CurrentContext();
+      context_chain_element.cloned_context = cloned_context;
+      context_chain_.Add(context_chain_element);
+
+      RecordContextsInChain(&inner_context, cloned_context, cloned_context);
+    } else if (scope_type == ScopeIterator::ScopeTypeBlock) {
+      Handle<JSObject> materialized_object = NewJSObjectWithNullProto();
+      frame_inspector.MaterializeStackLocals(materialized_object,
+                                             it.CurrentScopeInfo());
+      if (it.HasContext()) {
+        Handle<Context> cloned_context = Handle<Context>::cast(
+            isolate->factory()->CopyFixedArray(it.CurrentContext()));
+        Handle<Context> with_context = isolate->factory()->NewWithContext(
+            global_function, cloned_context, materialized_object);
+
+        ContextChainElement context_chain_element;
+        context_chain_element.original_context = it.CurrentContext();
+        context_chain_element.cloned_context = cloned_context;
+        context_chain_element.materialized_object = materialized_object;
+        context_chain_element.scope_info = it.CurrentScopeInfo();
+        context_chain_.Add(context_chain_element);
+
+        RecordContextsInChain(&inner_context, cloned_context, with_context);
+      } else {
+        Handle<Context> with_context = isolate->factory()->NewWithContext(
+            global_function, outer_context, materialized_object);
+
+        ContextChainElement context_chain_element;
+        context_chain_element.materialized_object = materialized_object;
+        context_chain_element.scope_info = it.CurrentScopeInfo();
+        context_chain_.Add(context_chain_element);
+
+        RecordContextsInChain(&inner_context, with_context, with_context);
+      }
+    } else {
+      stop = true;
+    }
+  }
+  if (innermost_context_.is_null()) {
+    innermost_context_ = outer_context;
+  }
+  DCHECK(!innermost_context_.is_null());
+}
+
+
+void DebugEvaluate::ContextBuilder::UpdateValues() {
+  // TODO(yangguo): remove updating values.
+  for (int i = 0; i < context_chain_.length(); i++) {
+    ContextChainElement element = context_chain_[i];
+    if (!element.original_context.is_null() &&
+        !element.cloned_context.is_null()) {
+      Handle<Context> cloned_context = element.cloned_context;
+      cloned_context->CopyTo(
+          Context::MIN_CONTEXT_SLOTS, *element.original_context,
+          Context::MIN_CONTEXT_SLOTS,
+          cloned_context->length() - Context::MIN_CONTEXT_SLOTS);
+    }
+    if (!element.materialized_object.is_null()) {
+      // Write back potential changes to materialized stack locals to the
+      // stack.
+      FrameInspector(frame_, inlined_jsframe_index_, isolate_)
+          .UpdateStackLocalsFromMaterializedObject(element.materialized_object,
+                                                   element.scope_info);
+      if (element.scope_info->scope_type() == FUNCTION_SCOPE) {
+        DCHECK_EQ(context_chain_.length() - 1, i);
+        UpdateContextChainFromMaterializedObject(element.materialized_object,
+                                                 element.original_context);
+      }
+    }
+  }
+}
+
+
+Handle<JSObject> DebugEvaluate::ContextBuilder::NewJSObjectWithNullProto() {
+  Handle<JSObject> result =
+      isolate_->factory()->NewJSObject(isolate_->object_function());
+  Handle<Map> new_map =
+      Map::Copy(Handle<Map>(result->map()), "ObjectWithNullProto");
+  Map::SetPrototype(new_map, isolate_->factory()->null_value());
+  JSObject::MigrateToMap(result, new_map);
+  return result;
+}
+
+
+void DebugEvaluate::ContextBuilder::RecordContextsInChain(
+    Handle<Context>* inner_context, Handle<Context> first,
+    Handle<Context> last) {
+  if (!inner_context->is_null()) {
+    (*inner_context)->set_previous(*last);
+  } else {
+    innermost_context_ = last;
+  }
+  *inner_context = first;
+}
+
+
+void DebugEvaluate::ContextBuilder::MaterializeArgumentsObject(
+    Handle<JSObject> target, Handle<JSFunction> function) {
+  // Do not materialize the arguments object for eval or top-level code.
+  // Skip if "arguments" is already taken.
+  if (!function->shared()->is_function()) return;
+  Maybe<bool> maybe = JSReceiver::HasOwnProperty(
+      target, isolate_->factory()->arguments_string());
+  DCHECK(maybe.IsJust());
+  if (maybe.FromJust()) return;
+
+  // FunctionGetArguments can't throw an exception.
+  Handle<JSObject> arguments =
+      Handle<JSObject>::cast(Accessors::FunctionGetArguments(function));
+  Handle<String> arguments_str = isolate_->factory()->arguments_string();
+  JSObject::SetOwnPropertyIgnoreAttributes(target, arguments_str, arguments,
+                                           NONE)
+      .Check();
+}
+
+
+MaybeHandle<Object> DebugEvaluate::ContextBuilder::LoadFromContext(
+    Handle<Context> context, Handle<String> name, bool* global) {
+  static const ContextLookupFlags flags = FOLLOW_CONTEXT_CHAIN;
+  int index;
+  PropertyAttributes attributes;
+  BindingFlags binding;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding);
+  if (holder.is_null()) return MaybeHandle<Object>();
+  Handle<Object> value;
+  if (index != Context::kNotFound) {  // Found on context.
+    Handle<Context> context = Handle<Context>::cast(holder);
+    // Do not shadow variables on the script context.
+    *global = context->IsScriptContext();
+    return Handle<Object>(context->get(index), isolate_);
+  } else {  // Found on object.
+    Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
+    // Do not shadow properties on the global object.
+    *global = object->IsJSGlobalObject();
+    return JSReceiver::GetDataProperty(object, name);
+  }
+}
+
+
+void DebugEvaluate::ContextBuilder::MaterializeContextChain(
+    Handle<JSObject> target, Handle<Context> context) {
+  for (const Handle<String>& name : non_locals_) {
+    HandleScope scope(isolate_);
+    Handle<Object> value;
+    bool global;
+    if (!LoadFromContext(context, name, &global).ToHandle(&value) || global) {
+      // If resolving the variable fails, skip it. If it resolves to a global
+      // variable, skip it as well since it's not read-only and can be resolved
+      // within debug-evaluate.
+      continue;
+    }
+    JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check();
+  }
+}
+
+
+void DebugEvaluate::ContextBuilder::StoreToContext(Handle<Context> context,
+                                                   Handle<String> name,
+                                                   Handle<Object> value) {
+  static const ContextLookupFlags flags = FOLLOW_CONTEXT_CHAIN;
+  int index;
+  PropertyAttributes attributes;
+  BindingFlags binding;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding);
+  if (holder.is_null()) return;
+  if (attributes & READ_ONLY) return;
+  if (index != Context::kNotFound) {  // Found on context.
+    Handle<Context> context = Handle<Context>::cast(holder);
+    context->set(index, *value);
+  } else {  // Found on object.
+    Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
+    LookupIterator lookup(object, name);
+    if (lookup.state() != LookupIterator::DATA) return;
+    CHECK(JSReceiver::SetDataProperty(&lookup, value).FromJust());
+  }
+}
+
+
+void DebugEvaluate::ContextBuilder::UpdateContextChainFromMaterializedObject(
+    Handle<JSObject> source, Handle<Context> context) {
+  // TODO(yangguo): check whether overwriting context fields is actually safe
+  //                wrt fields we consider constant.
+  for (const Handle<String>& name : non_locals_) {
+    HandleScope scope(isolate_);
+    Handle<Object> value = JSReceiver::GetDataProperty(source, name);
+    StoreToContext(context, name, value);
+  }
+}
+
+
+Handle<Context> DebugEvaluate::ContextBuilder::MaterializeReceiver(
+    Handle<Context> parent_context, Handle<Context> lookup_context,
+    Handle<JSFunction> local_function, Handle<JSFunction> global_function,
+    bool this_is_non_local) {
+  Handle<Object> receiver = isolate_->factory()->undefined_value();
+  Handle<String> this_string = isolate_->factory()->this_string();
+  if (this_is_non_local) {
+    bool global;
+    LoadFromContext(lookup_context, this_string, &global).ToHandle(&receiver);
+  } else if (local_function->shared()->scope_info()->HasReceiver()) {
+    receiver = handle(frame_->receiver(), isolate_);
+  }
+  return isolate_->factory()->NewCatchContext(global_function, parent_context,
+                                              this_string, receiver);
+}
+
+}  // namespace internal
+}  // namespace v8
