Split more runtime functions into seperate files.
authoryangguo@chromium.org <yangguo@chromium.org>
Mon, 29 Sep 2014 09:32:38 +0000 (09:32 +0000)
committeryangguo@chromium.org <yangguo@chromium.org>
Mon, 29 Sep 2014 09:32:38 +0000 (09:32 +0000)
R=bmeurer@chromium.org
BUG=

Review URL: https://codereview.chromium.org/598913004

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24274 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

BUILD.gn
src/runtime/runtime-collections.cc [new file with mode: 0644]
src/runtime/runtime-compiler.cc [new file with mode: 0644]
src/runtime/runtime-maths.cc [new file with mode: 0644]
src/runtime/runtime-numbers.cc [new file with mode: 0644]
src/runtime/runtime-strings.cc
src/runtime/runtime-test.cc [new file with mode: 0644]
src/runtime/runtime-typedarray.cc [new file with mode: 0644]
src/runtime/runtime.cc
tools/gyp/v8.gyp

index 8ee3a95..bfe4439 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -824,10 +824,16 @@ source_set("v8_base") {
     "src/rewriter.h",
     "src/runtime-profiler.cc",
     "src/runtime-profiler.h",
+    "src/runtime/runtime-collections.cc",
+    "src/runtime/runtime-compiler.cc",
     "src/runtime/runtime-i18n.cc",
     "src/runtime/runtime-json.cc",
+    "src/runtime/runtime-maths.cc",
+    "src/runtime/runtime-numbers.cc",
     "src/runtime/runtime-regexp.cc",
     "src/runtime/runtime-strings.cc",
+    "src/runtime/runtime-test.cc",
+    "src/runtime/runtime-typedarray.cc",
     "src/runtime/runtime-uri.cc",
     "src/runtime/runtime-utils.h",
     "src/runtime/runtime.cc",
diff --git a/src/runtime/runtime-collections.cc b/src/runtime/runtime-collections.cc
new file mode 100644 (file)
index 0000000..d0d6aa6
--- /dev/null
@@ -0,0 +1,347 @@
+// Copyright 2014 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/v8.h"
+
+#include "src/arguments.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_SetInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
+  holder->set_table(*table);
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetAdd) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  table = OrderedHashSet::Add(table, key);
+  holder->set_table(*table);
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetHas) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  return isolate->heap()->ToBoolean(table->Contains(key));
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetDelete) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  bool was_present = false;
+  table = OrderedHashSet::Remove(table, key, &was_present);
+  holder->set_table(*table);
+  return isolate->heap()->ToBoolean(was_present);
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetClear) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  table = OrderedHashSet::Clear(table);
+  holder->set_table(*table);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetGetSize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  return Smi::FromInt(table->NumberOfElements());
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
+  CONVERT_SMI_ARG_CHECKED(kind, 2)
+  RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
+                 kind == JSSetIterator::kKindEntries);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
+  holder->set_table(*table);
+  holder->set_index(Smi::FromInt(0));
+  holder->set_kind(Smi::FromInt(kind));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSSetIterator, holder, 0);
+  CONVERT_ARG_CHECKED(JSArray, value_array, 1);
+  return holder->Next(value_array);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
+  holder->set_table(*table);
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapGet) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  Handle<Object> lookup(table->Lookup(key), isolate);
+  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapHas) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  Handle<Object> lookup(table->Lookup(key), isolate);
+  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapDelete) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  bool was_present = false;
+  Handle<OrderedHashMap> new_table =
+      OrderedHashMap::Remove(table, key, &was_present);
+  holder->set_table(*new_table);
+  return isolate->heap()->ToBoolean(was_present);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapClear) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  table = OrderedHashMap::Clear(table);
+  holder->set_table(*table);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapSet) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
+  holder->set_table(*new_table);
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapGetSize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  return Smi::FromInt(table->NumberOfElements());
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
+  CONVERT_SMI_ARG_CHECKED(kind, 2)
+  RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys ||
+                 kind == JSMapIterator::kKindValues ||
+                 kind == JSMapIterator::kKindEntries);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
+  holder->set_table(*table);
+  holder->set_index(Smi::FromInt(0));
+  holder->set_kind(Smi::FromInt(kind));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
+  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+  Handle<FixedArray> entries =
+      isolate->factory()->NewFixedArray(table->NumberOfElements() * 2);
+  {
+    DisallowHeapAllocation no_gc;
+    int number_of_non_hole_elements = 0;
+    for (int i = 0; i < table->Capacity(); i++) {
+      Handle<Object> key(table->KeyAt(i), isolate);
+      if (table->IsKey(*key)) {
+        entries->set(number_of_non_hole_elements++, *key);
+        Object* value = table->Lookup(key);
+        entries->set(number_of_non_hole_elements++, value);
+      }
+    }
+    DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
+  }
+  return *isolate->factory()->NewJSArrayWithElements(entries);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
+  CONVERT_ARG_CHECKED(JSArray, value_array, 1);
+  return holder->Next(value_array);
+}
+
+
+static Handle<JSWeakCollection> WeakCollectionInitialize(
+    Isolate* isolate, Handle<JSWeakCollection> weak_collection) {
+  DCHECK(weak_collection->map()->inobject_properties() == 0);
+  Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
+  weak_collection->set_table(*table);
+  return weak_collection;
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  return *WeakCollectionInitialize(isolate, weak_collection);
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
+  Handle<ObjectHashTable> table(
+      ObjectHashTable::cast(weak_collection->table()));
+  RUNTIME_ASSERT(table->IsKey(*key));
+  Handle<Object> lookup(table->Lookup(key), isolate);
+  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
+  Handle<ObjectHashTable> table(
+      ObjectHashTable::cast(weak_collection->table()));
+  RUNTIME_ASSERT(table->IsKey(*key));
+  Handle<Object> lookup(table->Lookup(key), isolate);
+  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
+  Handle<ObjectHashTable> table(
+      ObjectHashTable::cast(weak_collection->table()));
+  RUNTIME_ASSERT(table->IsKey(*key));
+  bool was_present = false;
+  Handle<ObjectHashTable> new_table =
+      ObjectHashTable::Remove(table, key, &was_present);
+  weak_collection->set_table(*new_table);
+  return isolate->heap()->ToBoolean(was_present);
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  Handle<ObjectHashTable> table(
+      ObjectHashTable::cast(weak_collection->table()));
+  RUNTIME_ASSERT(table->IsKey(*key));
+  Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
+  weak_collection->set_table(*new_table);
+  return *weak_collection;
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
+  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+  Handle<FixedArray> values =
+      isolate->factory()->NewFixedArray(table->NumberOfElements());
+  {
+    DisallowHeapAllocation no_gc;
+    int number_of_non_hole_elements = 0;
+    for (int i = 0; i < table->Capacity(); i++) {
+      Handle<Object> key(table->KeyAt(i), isolate);
+      if (table->IsKey(*key)) {
+        values->set(number_of_non_hole_elements++, *key);
+      }
+    }
+    DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements);
+  }
+  return *isolate->factory()->NewJSArrayWithElements(values);
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  // TODO(adamk): Currently this runtime function is only called three times per
+  // isolate. If it's called more often, the map should be moved into the
+  // strong root list.
+  Handle<Map> map =
+      isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
+  Handle<JSWeakMap> weakmap =
+      Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
+  return *WeakCollectionInitialize(isolate, weakmap);
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-compiler.cc b/src/runtime/runtime-compiler.cc
new file mode 100644 (file)
index 0000000..3f7e936
--- /dev/null
@@ -0,0 +1,441 @@
+// Copyright 2014 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/v8.h"
+
+#include "src/arguments.h"
+#include "src/compiler.h"
+#include "src/deoptimizer.h"
+#include "src/frames.h"
+#include "src/full-codegen.h"
+#include "src/isolate.h"
+#include "src/isolate-inl.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+#include "src/v8threads.h"
+#include "src/vm-state.h"
+#include "src/vm-state-inl.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_CompileLazy) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+#ifdef DEBUG
+  if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
+    PrintF("[unoptimized: ");
+    function->PrintName();
+    PrintF("]\n");
+  }
+#endif
+
+  // Compile the target function.
+  DCHECK(function->shared()->allows_lazy_compilation());
+
+  Handle<Code> code;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
+                                     Compiler::GetLazyCode(function));
+  DCHECK(code->kind() == Code::FUNCTION ||
+         code->kind() == Code::OPTIMIZED_FUNCTION);
+  function->ReplaceCode(*code);
+  return *code;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CompileOptimized) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
+
+  Handle<Code> unoptimized(function->shared()->code());
+  if (!isolate->use_crankshaft() ||
+      function->shared()->optimization_disabled() ||
+      isolate->DebuggerHasBreakPoints()) {
+    // If the function is not optimizable or debugger is active continue
+    // using the code from the full compiler.
+    if (FLAG_trace_opt) {
+      PrintF("[failed to optimize ");
+      function->PrintName();
+      PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
+             function->shared()->optimization_disabled() ? "F" : "T",
+             isolate->DebuggerHasBreakPoints() ? "T" : "F");
+    }
+    function->ReplaceCode(*unoptimized);
+    return function->code();
+  }
+
+  Compiler::ConcurrencyMode mode =
+      concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
+  Handle<Code> code;
+  if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) {
+    function->ReplaceCode(*code);
+  } else {
+    function->ReplaceCode(function->shared()->code());
+  }
+
+  DCHECK(function->code()->kind() == Code::FUNCTION ||
+         function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
+         function->IsInOptimizationQueue());
+  return function->code();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
+  DCHECK(AllowHeapAllocation::IsAllowed());
+  delete deoptimizer;
+  return isolate->heap()->undefined_value();
+}
+
+
+class ActivationsFinder : public ThreadVisitor {
+ public:
+  Code* code_;
+  bool has_code_activations_;
+
+  explicit ActivationsFinder(Code* code)
+      : code_(code), has_code_activations_(false) {}
+
+  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
+    JavaScriptFrameIterator it(isolate, top);
+    VisitFrames(&it);
+  }
+
+  void VisitFrames(JavaScriptFrameIterator* it) {
+    for (; !it->done(); it->Advance()) {
+      JavaScriptFrame* frame = it->frame();
+      if (code_->contains(frame->pc())) has_code_activations_ = true;
+    }
+  }
+};
+
+
+RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_SMI_ARG_CHECKED(type_arg, 0);
+  Deoptimizer::BailoutType type =
+      static_cast<Deoptimizer::BailoutType>(type_arg);
+  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
+  DCHECK(AllowHeapAllocation::IsAllowed());
+
+  Handle<JSFunction> function = deoptimizer->function();
+  Handle<Code> optimized_code = deoptimizer->compiled_code();
+
+  DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
+  DCHECK(type == deoptimizer->bailout_type());
+
+  // Make sure to materialize objects before causing any allocation.
+  JavaScriptFrameIterator it(isolate);
+  deoptimizer->MaterializeHeapObjects(&it);
+  delete deoptimizer;
+
+  JavaScriptFrame* frame = it.frame();
+  RUNTIME_ASSERT(frame->function()->IsJSFunction());
+  DCHECK(frame->function() == *function);
+
+  // Avoid doing too much work when running with --always-opt and keep
+  // the optimized code around.
+  if (FLAG_always_opt || type == Deoptimizer::LAZY) {
+    return isolate->heap()->undefined_value();
+  }
+
+  // Search for other activations of the same function and code.
+  ActivationsFinder activations_finder(*optimized_code);
+  activations_finder.VisitFrames(&it);
+  isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
+
+  if (!activations_finder.has_code_activations_) {
+    if (function->code() == *optimized_code) {
+      if (FLAG_trace_deopt) {
+        PrintF("[removing optimized code for: ");
+        function->PrintName();
+        PrintF("]\n");
+      }
+      function->ReplaceCode(function->shared()->code());
+      // Evict optimized code for this function from the cache so that it
+      // doesn't get used for new closures.
+      function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
+                                                    "notify deoptimized");
+    }
+  } else {
+    // TODO(titzer): we should probably do DeoptimizeCodeList(code)
+    // unconditionally if the code is not already marked for deoptimization.
+    // If there is an index by shared function info, all the better.
+    Deoptimizer::DeoptimizeFunction(*function);
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
+static bool IsSuitableForOnStackReplacement(Isolate* isolate,
+                                            Handle<JSFunction> function,
+                                            Handle<Code> current_code) {
+  // Keep track of whether we've succeeded in optimizing.
+  if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
+  // If we are trying to do OSR when there are already optimized
+  // activations of the function, it means (a) the function is directly or
+  // indirectly recursive and (b) an optimized invocation has been
+  // deoptimized so that we are currently in an unoptimized activation.
+  // Check for optimized activations of this function.
+  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
+    JavaScriptFrame* frame = it.frame();
+    if (frame->is_optimized() && frame->function() == *function) return false;
+  }
+
+  return true;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  Handle<Code> caller_code(function->shared()->code());
+
+  // We're not prepared to handle a function with arguments object.
+  DCHECK(!function->shared()->uses_arguments());
+
+  RUNTIME_ASSERT(FLAG_use_osr);
+
+  // Passing the PC in the javascript frame from the caller directly is
+  // not GC safe, so we walk the stack to get it.
+  JavaScriptFrameIterator it(isolate);
+  JavaScriptFrame* frame = it.frame();
+  if (!caller_code->contains(frame->pc())) {
+    // Code on the stack may not be the code object referenced by the shared
+    // function info.  It may have been replaced to include deoptimization data.
+    caller_code = Handle<Code>(frame->LookupCode());
+  }
+
+  uint32_t pc_offset =
+      static_cast<uint32_t>(frame->pc() - caller_code->instruction_start());
+
+#ifdef DEBUG
+  DCHECK_EQ(frame->function(), *function);
+  DCHECK_EQ(frame->LookupCode(), *caller_code);
+  DCHECK(caller_code->contains(frame->pc()));
+#endif  // DEBUG
+
+
+  BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
+  DCHECK(!ast_id.IsNone());
+
+  Compiler::ConcurrencyMode mode =
+      isolate->concurrent_osr_enabled() &&
+              (function->shared()->ast_node_count() > 512)
+          ? Compiler::CONCURRENT
+          : Compiler::NOT_CONCURRENT;
+  Handle<Code> result = Handle<Code>::null();
+
+  OptimizedCompileJob* job = NULL;
+  if (mode == Compiler::CONCURRENT) {
+    // Gate the OSR entry with a stack check.
+    BackEdgeTable::AddStackCheck(caller_code, pc_offset);
+    // Poll already queued compilation jobs.
+    OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
+    if (thread->IsQueuedForOSR(function, ast_id)) {
+      if (FLAG_trace_osr) {
+        PrintF("[OSR - Still waiting for queued: ");
+        function->PrintName();
+        PrintF(" at AST id %d]\n", ast_id.ToInt());
+      }
+      return NULL;
+    }
+
+    job = thread->FindReadyOSRCandidate(function, ast_id);
+  }
+
+  if (job != NULL) {
+    if (FLAG_trace_osr) {
+      PrintF("[OSR - Found ready: ");
+      function->PrintName();
+      PrintF(" at AST id %d]\n", ast_id.ToInt());
+    }
+    result = Compiler::GetConcurrentlyOptimizedCode(job);
+  } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
+    if (FLAG_trace_osr) {
+      PrintF("[OSR - Compiling: ");
+      function->PrintName();
+      PrintF(" at AST id %d]\n", ast_id.ToInt());
+    }
+    MaybeHandle<Code> maybe_result =
+        Compiler::GetOptimizedCode(function, caller_code, mode, ast_id);
+    if (maybe_result.ToHandle(&result) &&
+        result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
+      // Optimization is queued.  Return to check later.
+      return NULL;
+    }
+  }
+
+  // Revert the patched back edge table, regardless of whether OSR succeeds.
+  BackEdgeTable::Revert(isolate, *caller_code);
+
+  // Check whether we ended up with usable optimized code.
+  if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
+    DeoptimizationInputData* data =
+        DeoptimizationInputData::cast(result->deoptimization_data());
+
+    if (data->OsrPcOffset()->value() >= 0) {
+      DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
+      if (FLAG_trace_osr) {
+        PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
+               ast_id.ToInt(), data->OsrPcOffset()->value());
+      }
+      // TODO(titzer): this is a massive hack to make the deopt counts
+      // match. Fix heuristics for reenabling optimizations!
+      function->shared()->increment_deopt_count();
+
+      // TODO(titzer): Do not install code into the function.
+      function->ReplaceCode(*result);
+      return *result;
+    }
+  }
+
+  // Failed.
+  if (FLAG_trace_osr) {
+    PrintF("[OSR - Failed: ");
+    function->PrintName();
+    PrintF(" at AST id %d]\n", ast_id.ToInt());
+  }
+
+  if (!function->IsOptimized()) {
+    function->ReplaceCode(function->shared()->code());
+  }
+  return NULL;
+}
+
+
+RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
+  // First check if this is a real stack overflow.
+  StackLimitCheck check(isolate);
+  if (check.JsHasOverflowed()) {
+    SealHandleScope shs(isolate);
+    return isolate->StackOverflow();
+  }
+
+  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+  return (function->IsOptimized()) ? function->code()
+                                   : function->shared()->code();
+}
+
+
+bool CodeGenerationFromStringsAllowed(Isolate* isolate,
+                                      Handle<Context> context) {
+  DCHECK(context->allow_code_gen_from_strings()->IsFalse());
+  // Check with callback if set.
+  AllowCodeGenerationFromStringsCallback callback =
+      isolate->allow_code_gen_callback();
+  if (callback == NULL) {
+    // No callback set and code generation disallowed.
+    return false;
+  } else {
+    // Callback set. Let it decide if code generation is allowed.
+    VMState<EXTERNAL> state(isolate);
+    return callback(v8::Utils::ToLocal(context));
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_CompileString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
+
+  // Extract native context.
+  Handle<Context> context(isolate->native_context());
+
+  // Check if native context allows code generation from
+  // strings. Throw an exception if it doesn't.
+  if (context->allow_code_gen_from_strings()->IsFalse() &&
+      !CodeGenerationFromStringsAllowed(isolate, context)) {
+    Handle<Object> error_message =
+        context->ErrorMessageForCodeGenerationFromStrings();
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewEvalError("code_gen_from_strings",
+                              HandleVector<Object>(&error_message, 1)));
+  }
+
+  // Compile source string in the native context.
+  ParseRestriction restriction = function_literal_only
+                                     ? ONLY_SINGLE_FUNCTION_LITERAL
+                                     : NO_PARSE_RESTRICTION;
+  Handle<JSFunction> fun;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, fun,
+      Compiler::GetFunctionFromEval(source, context, SLOPPY, restriction,
+                                    RelocInfo::kNoPosition));
+  return *fun;
+}
+
+
+static ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source,
+                                    Handle<Object> receiver,
+                                    StrictMode strict_mode,
+                                    int scope_position) {
+  Handle<Context> context = Handle<Context>(isolate->context());
+  Handle<Context> native_context = Handle<Context>(context->native_context());
+
+  // Check if native context allows code generation from
+  // strings. Throw an exception if it doesn't.
+  if (native_context->allow_code_gen_from_strings()->IsFalse() &&
+      !CodeGenerationFromStringsAllowed(isolate, native_context)) {
+    Handle<Object> error_message =
+        native_context->ErrorMessageForCodeGenerationFromStrings();
+    Handle<Object> error;
+    MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
+        "code_gen_from_strings", HandleVector<Object>(&error_message, 1));
+    if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
+    return MakePair(isolate->heap()->exception(), NULL);
+  }
+
+  // Deal with a normal eval call with a string argument. Compile it
+  // and return the compiled function bound in the local context.
+  static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
+  Handle<JSFunction> compiled;
+  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+      isolate, compiled,
+      Compiler::GetFunctionFromEval(source, context, strict_mode, restriction,
+                                    scope_position),
+      MakePair(isolate->heap()->exception(), NULL));
+  return MakePair(*compiled, *receiver);
+}
+
+
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 5);
+
+  Handle<Object> callee = args.at<Object>(0);
+
+  // If "eval" didn't refer to the original GlobalEval, it's not a
+  // direct call to eval.
+  // (And even if it is, but the first argument isn't a string, just let
+  // execution default to an indirect call to eval, which will also return
+  // the first argument without doing anything).
+  if (*callee != isolate->native_context()->global_eval_fun() ||
+      !args[1]->IsString()) {
+    return MakePair(*callee, isolate->heap()->undefined_value());
+  }
+
+  DCHECK(args[3]->IsSmi());
+  DCHECK(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
+  StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
+  DCHECK(args[4]->IsSmi());
+  return CompileGlobalEval(isolate, args.at<String>(1), args.at<Object>(2),
+                           strict_mode, args.smi_at(4));
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-maths.cc b/src/runtime/runtime-maths.cc
new file mode 100644 (file)
index 0000000..16acb39
--- /dev/null
@@ -0,0 +1,247 @@
+// Copyright 2014 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/v8.h"
+
+#include "src/arguments.h"
+#include "src/assembler.h"
+#include "src/codegen.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+#include "third_party/fdlibm/fdlibm.h"
+
+
+namespace v8 {
+namespace internal {
+
+#define RUNTIME_UNARY_MATH(Name, name)                       \
+  RUNTIME_FUNCTION(Runtime_Math##Name) {                     \
+    HandleScope scope(isolate);                              \
+    DCHECK(args.length() == 1);                              \
+    isolate->counters()->math_##name()->Increment();         \
+    CONVERT_DOUBLE_ARG_CHECKED(x, 0);                        \
+    return *isolate->factory()->NewHeapNumber(std::name(x)); \
+  }
+
+RUNTIME_UNARY_MATH(Acos, acos)
+RUNTIME_UNARY_MATH(Asin, asin)
+RUNTIME_UNARY_MATH(Atan, atan)
+RUNTIME_UNARY_MATH(LogRT, log)
+#undef RUNTIME_UNARY_MATH
+
+
+RUNTIME_FUNCTION(Runtime_DoubleHi) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  uint64_t integer = double_to_uint64(x);
+  integer = (integer >> 32) & 0xFFFFFFFFu;
+  return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
+}
+
+
+RUNTIME_FUNCTION(Runtime_DoubleLo) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  return *isolate->factory()->NewNumber(
+      static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ConstructDouble) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
+  CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
+  uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
+  return *isolate->factory()->NewNumber(uint64_to_double(result));
+}
+
+
+RUNTIME_FUNCTION(Runtime_RemPiO2) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  Factory* factory = isolate->factory();
+  double y[2];
+  int n = fdlibm::rempio2(x, y);
+  Handle<FixedArray> array = factory->NewFixedArray(3);
+  Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
+  Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
+  array->set(0, Smi::FromInt(n));
+  array->set(1, *y0);
+  array->set(2, *y1);
+  return *factory->NewJSArrayWithElements(array);
+}
+
+
+static const double kPiDividedBy4 = 0.78539816339744830962;
+
+
+RUNTIME_FUNCTION(Runtime_MathAtan2) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  isolate->counters()->math_atan2()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  double result;
+  if (std::isinf(x) && std::isinf(y)) {
+    // Make sure that the result in case of two infinite arguments
+    // is a multiple of Pi / 4. The sign of the result is determined
+    // by the first argument (x) and the sign of the second argument
+    // determines the multiplier: one or three.
+    int multiplier = (x < 0) ? -1 : 1;
+    if (y < 0) multiplier *= 3;
+    result = multiplier * kPiDividedBy4;
+  } else {
+    result = std::atan2(x, y);
+  }
+  return *isolate->factory()->NewNumber(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MathExpRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  isolate->counters()->math_exp()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  lazily_initialize_fast_exp();
+  return *isolate->factory()->NewNumber(fast_exp(x));
+}
+
+
+RUNTIME_FUNCTION(Runtime_MathFloorRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  isolate->counters()->math_floor()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  return *isolate->factory()->NewNumber(Floor(x));
+}
+
+
+// Slow version of Math.pow.  We check for fast paths for special cases.
+// Used if VFP3 is not available.
+RUNTIME_FUNCTION(Runtime_MathPowSlow) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  isolate->counters()->math_pow()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+
+  // If the second argument is a smi, it is much faster to call the
+  // custom powi() function than the generic pow().
+  if (args[1]->IsSmi()) {
+    int y = args.smi_at(1);
+    return *isolate->factory()->NewNumber(power_double_int(x, y));
+  }
+
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  double result = power_helper(x, y);
+  if (std::isnan(result)) return isolate->heap()->nan_value();
+  return *isolate->factory()->NewNumber(result);
+}
+
+
+// Fast version of Math.pow if we know that y is not an integer and y is not
+// -0.5 or 0.5.  Used as slow case from full codegen.
+RUNTIME_FUNCTION(Runtime_MathPowRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  isolate->counters()->math_pow()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  if (y == 0) {
+    return Smi::FromInt(1);
+  } else {
+    double result = power_double_double(x, y);
+    if (std::isnan(result)) return isolate->heap()->nan_value();
+    return *isolate->factory()->NewNumber(result);
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_RoundNumber) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
+  isolate->counters()->math_round()->Increment();
+
+  if (!input->IsHeapNumber()) {
+    DCHECK(input->IsSmi());
+    return *input;
+  }
+
+  Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
+
+  double value = number->value();
+  int exponent = number->get_exponent();
+  int sign = number->get_sign();
+
+  if (exponent < -1) {
+    // Number in range ]-0.5..0.5[. These always round to +/-zero.
+    if (sign) return isolate->heap()->minus_zero_value();
+    return Smi::FromInt(0);
+  }
+
+  // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
+  // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
+  // argument holds for 32-bit smis).
+  if (!sign && exponent < kSmiValueSize - 2) {
+    return Smi::FromInt(static_cast<int>(value + 0.5));
+  }
+
+  // If the magnitude is big enough, there's no place for fraction part. If we
+  // try to add 0.5 to this number, 1.0 will be added instead.
+  if (exponent >= 52) {
+    return *number;
+  }
+
+  if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
+
+  // Do not call NumberFromDouble() to avoid extra checks.
+  return *isolate->factory()->NewNumber(Floor(value + 0.5));
+}
+
+
+RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  isolate->counters()->math_sqrt()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  return *isolate->factory()->NewNumber(fast_sqrt(x));
+}
+
+
+RUNTIME_FUNCTION(Runtime_MathFround) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  float xf = DoubleToFloat32(x);
+  return *isolate->factory()->NewNumber(xf);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_MathPow) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_MathPowSlow(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
+  HeapNumber* number = HeapNumber::cast(obj);
+  return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-numbers.cc b/src/runtime/runtime-numbers.cc
new file mode 100644 (file)
index 0000000..3286aa6
--- /dev/null
@@ -0,0 +1,565 @@
+// Copyright 2014 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/v8.h"
+
+#include "src/arguments.h"
+#include "src/codegen.h"
+#include "src/misc-intrinsics.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+
+#ifndef _STLP_VENDOR_CSTD
+// STLPort doesn't import fpclassify and isless into the std namespace.
+using std::fpclassify;
+using std::isless;
+#endif
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_SMI_ARG_CHECKED(radix, 1);
+  RUNTIME_ASSERT(2 <= radix && radix <= 36);
+
+  // Fast case where the result is a one character string.
+  if (args[0]->IsSmi()) {
+    int value = args.smi_at(0);
+    if (value >= 0 && value < radix) {
+      // Character array used for conversion.
+      static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+      return *isolate->factory()->LookupSingleCharacterStringFromCode(
+          kCharTable[value]);
+    }
+  }
+
+  // Slow case.
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
+  if (std::isnan(value)) {
+    return isolate->heap()->nan_string();
+  }
+  if (std::isinf(value)) {
+    if (value < 0) {
+      return isolate->heap()->minus_infinity_string();
+    }
+    return isolate->heap()->infinity_string();
+  }
+  char* str = DoubleToRadixCString(value, radix);
+  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
+  DeleteArray(str);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToFixed) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
+  int f = FastD2IChecked(f_number);
+  // See DoubleToFixedCString for these constants:
+  RUNTIME_ASSERT(f >= 0 && f <= 20);
+  RUNTIME_ASSERT(!Double(value).IsSpecial());
+  char* str = DoubleToFixedCString(value, f);
+  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
+  DeleteArray(str);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToExponential) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
+  int f = FastD2IChecked(f_number);
+  RUNTIME_ASSERT(f >= -1 && f <= 20);
+  RUNTIME_ASSERT(!Double(value).IsSpecial());
+  char* str = DoubleToExponentialCString(value, f);
+  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
+  DeleteArray(str);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
+  int f = FastD2IChecked(f_number);
+  RUNTIME_ASSERT(f >= 1 && f <= 21);
+  RUNTIME_ASSERT(!Double(value).IsSpecial());
+  char* str = DoubleToPrecisionCString(value, f);
+  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
+  DeleteArray(str);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsValidSmi) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
+  return isolate->heap()->ToBoolean(Smi::IsValid(number));
+}
+
+
+static bool AreDigits(const uint8_t* s, int from, int to) {
+  for (int i = from; i < to; i++) {
+    if (s[i] < '0' || s[i] > '9') return false;
+  }
+
+  return true;
+}
+
+
+static int ParseDecimalInteger(const uint8_t* s, int from, int to) {
+  DCHECK(to - from < 10);  // Overflow is not possible.
+  DCHECK(from < to);
+  int d = s[from] - '0';
+
+  for (int i = from + 1; i < to; i++) {
+    d = 10 * d + (s[i] - '0');
+  }
+
+  return d;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringToNumber) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  subject = String::Flatten(subject);
+
+  // Fast case: short integer or some sorts of junk values.
+  if (subject->IsSeqOneByteString()) {
+    int len = subject->length();
+    if (len == 0) return Smi::FromInt(0);
+
+    DisallowHeapAllocation no_gc;
+    uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
+    bool minus = (data[0] == '-');
+    int start_pos = (minus ? 1 : 0);
+
+    if (start_pos == len) {
+      return isolate->heap()->nan_value();
+    } else if (data[start_pos] > '9') {
+      // Fast check for a junk value. A valid string may start from a
+      // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
+      // or the 'I' character ('Infinity'). All of that have codes not greater
+      // than '9' except 'I' and &nbsp;.
+      if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
+        return isolate->heap()->nan_value();
+      }
+    } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
+      // The maximal/minimal smi has 10 digits. If the string has less digits
+      // we know it will fit into the smi-data type.
+      int d = ParseDecimalInteger(data, start_pos, len);
+      if (minus) {
+        if (d == 0) return isolate->heap()->minus_zero_value();
+        d = -d;
+      } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
+                 (len == 1 || data[0] != '0')) {
+        // String hash is not calculated yet but all the data are present.
+        // Update the hash field to speed up sequential convertions.
+        uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
+#ifdef DEBUG
+        subject->Hash();  // Force hash calculation.
+        DCHECK_EQ(static_cast<int>(subject->hash_field()),
+                  static_cast<int>(hash));
+#endif
+        subject->set_hash_field(hash);
+      }
+      return Smi::FromInt(d);
+    }
+  }
+
+  // Slower case.
+  int flags = ALLOW_HEX;
+  if (FLAG_harmony_numeric_literals) {
+    // The current spec draft has not updated "ToNumber Applied to the String
+    // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
+    flags |= ALLOW_OCTAL | ALLOW_BINARY;
+  }
+
+  return *isolate->factory()->NewNumber(
+      StringToDouble(isolate->unicode_cache(), *subject, flags));
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringParseInt) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
+  RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
+
+  subject = String::Flatten(subject);
+  double value;
+
+  {
+    DisallowHeapAllocation no_gc;
+    String::FlatContent flat = subject->GetFlatContent();
+
+    // ECMA-262 section 15.1.2.3, empty string is NaN
+    if (flat.IsOneByte()) {
+      value =
+          StringToInt(isolate->unicode_cache(), flat.ToOneByteVector(), radix);
+    } else {
+      value = StringToInt(isolate->unicode_cache(), flat.ToUC16Vector(), radix);
+    }
+  }
+
+  return *isolate->factory()->NewNumber(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringParseFloat) {
+  HandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+
+  subject = String::Flatten(subject);
+  double value = StringToDouble(isolate->unicode_cache(), *subject,
+                                ALLOW_TRAILING_JUNK, base::OS::nan_value());
+
+  return *isolate->factory()->NewNumber(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToStringRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
+
+  return *isolate->factory()->NumberToString(number);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
+
+  return *isolate->factory()->NumberToString(number, false);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToInteger) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
+  return *isolate->factory()->NewNumber(DoubleToInteger(number));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
+  double double_value = DoubleToInteger(number);
+  // Map both -0 and +0 to +0.
+  if (double_value == 0) double_value = 0;
+
+  return *isolate->factory()->NewNumber(double_value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
+  return *isolate->factory()->NewNumberFromUint(number);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
+  return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
+}
+
+
+// Converts a Number to a Smi, if possible. Returns NaN if the number is not
+// a small integer.
+RUNTIME_FUNCTION(Runtime_NumberToSmi) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (obj->IsSmi()) {
+    return obj;
+  }
+  if (obj->IsHeapNumber()) {
+    double value = HeapNumber::cast(obj)->value();
+    int int_value = FastD2I(value);
+    if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
+      return Smi::FromInt(int_value);
+    }
+  }
+  return isolate->heap()->nan_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberAdd) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(x + y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberSub) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(x - y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberMul) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(x * y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  return *isolate->factory()->NewNumber(-x);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberDiv) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(x / y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberMod) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(modulo(x, y));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberImul) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  // We rely on implementation-defined behavior below, but at least not on
+  // undefined behavior.
+  CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
+  int32_t product = static_cast<int32_t>(x * y);
+  return *isolate->factory()->NewNumberFromInt(product);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberOr) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(x | y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberAnd) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(x & y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberXor) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(x ^ y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberShl) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberShr) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberSar) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(
+      ArithmeticShiftRight(x, y & 0x1f));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberEquals) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
+  if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
+  if (x == y) return Smi::FromInt(EQUAL);
+  Object* result;
+  if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
+    result = Smi::FromInt(EQUAL);
+  } else {
+    result = Smi::FromInt(NOT_EQUAL);
+  }
+  return result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberCompare) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
+  if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
+  if (x == y) return Smi::FromInt(EQUAL);
+  if (isless(x, y)) return Smi::FromInt(LESS);
+  return Smi::FromInt(GREATER);
+}
+
+
+// Compare two Smis as if they were converted to strings and then
+// compared lexicographically.
+RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_SMI_ARG_CHECKED(x_value, 0);
+  CONVERT_SMI_ARG_CHECKED(y_value, 1);
+
+  // If the integers are equal so are the string representations.
+  if (x_value == y_value) return Smi::FromInt(EQUAL);
+
+  // If one of the integers is zero the normal integer order is the
+  // same as the lexicographic order of the string representations.
+  if (x_value == 0 || y_value == 0)
+    return Smi::FromInt(x_value < y_value ? LESS : GREATER);
+
+  // If only one of the integers is negative the negative number is
+  // smallest because the char code of '-' is less than the char code
+  // of any digit.  Otherwise, we make both values positive.
+
+  // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
+  // architectures using 32-bit Smis.
+  uint32_t x_scaled = x_value;
+  uint32_t y_scaled = y_value;
+  if (x_value < 0 || y_value < 0) {
+    if (y_value >= 0) return Smi::FromInt(LESS);
+    if (x_value >= 0) return Smi::FromInt(GREATER);
+    x_scaled = -x_value;
+    y_scaled = -y_value;
+  }
+
+  static const uint32_t kPowersOf10[] = {
+      1,                 10,                100,         1000,
+      10 * 1000,         100 * 1000,        1000 * 1000, 10 * 1000 * 1000,
+      100 * 1000 * 1000, 1000 * 1000 * 1000};
+
+  // If the integers have the same number of decimal digits they can be
+  // compared directly as the numeric order is the same as the
+  // lexicographic order.  If one integer has fewer digits, it is scaled
+  // by some power of 10 to have the same number of digits as the longer
+  // integer.  If the scaled integers are equal it means the shorter
+  // integer comes first in the lexicographic order.
+
+  // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+  int x_log2 = IntegerLog2(x_scaled);
+  int x_log10 = ((x_log2 + 1) * 1233) >> 12;
+  x_log10 -= x_scaled < kPowersOf10[x_log10];
+
+  int y_log2 = IntegerLog2(y_scaled);
+  int y_log10 = ((y_log2 + 1) * 1233) >> 12;
+  y_log10 -= y_scaled < kPowersOf10[y_log10];
+
+  int tie = EQUAL;
+
+  if (x_log10 < y_log10) {
+    // X has fewer digits.  We would like to simply scale up X but that
+    // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
+    // be scaled up to 9_000_000_000. So we scale up by the next
+    // smallest power and scale down Y to drop one digit. It is OK to
+    // drop one digit from the longer integer since the final digit is
+    // past the length of the shorter integer.
+    x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
+    y_scaled /= 10;
+    tie = LESS;
+  } else if (y_log10 < x_log10) {
+    y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
+    x_scaled /= 10;
+    tie = GREATER;
+  }
+
+  if (x_scaled < y_scaled) return Smi::FromInt(LESS);
+  if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
+  return Smi::FromInt(tie);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_NumberToStringRT(args, isolate);
+}
+}
+}  // namespace v8::internal
index 8d245a5..82174e9 100644 (file)
@@ -1182,6 +1182,14 @@ RUNTIME_FUNCTION(Runtime_StringEquals) {
 }
 
 
+RUNTIME_FUNCTION(Runtime_FlattenString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
+  return *String::Flatten(str);
+}
+
+
 RUNTIME_FUNCTION(RuntimeReference_StringCharFromCode) {
   SealHandleScope shs(isolate);
   return __RT_impl_Runtime_CharFromCode(args, isolate);
diff --git a/src/runtime/runtime-test.cc b/src/runtime/runtime-test.cc
new file mode 100644 (file)
index 0000000..eac3c61
--- /dev/null
@@ -0,0 +1,323 @@
+// Copyright 2014 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/v8.h"
+
+#include "src/arguments.h"
+#include "src/deoptimizer.h"
+#include "src/full-codegen.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  if (!function->IsOptimized()) return isolate->heap()->undefined_value();
+
+  // TODO(turbofan): Deoptimization is not supported yet.
+  if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
+    return isolate->heap()->undefined_value();
+  }
+
+  Deoptimizer::DeoptimizeFunction(*function);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+#if defined(USE_SIMULATOR)
+  return isolate->heap()->true_value();
+#else
+  return isolate->heap()->false_value();
+#endif
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  return isolate->heap()->ToBoolean(
+      isolate->concurrent_recompilation_enabled());
+}
+
+
+RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  // The following two assertions are lifted from the DCHECKs inside
+  // JSFunction::MarkForOptimization().
+  RUNTIME_ASSERT(!function->shared()->is_generator());
+  RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
+                 (function->code()->kind() == Code::FUNCTION &&
+                  function->code()->optimizable()));
+
+  // If the function is optimized, just return.
+  if (function->IsOptimized()) return isolate->heap()->undefined_value();
+
+  function->MarkForOptimization();
+
+  Code* unoptimized = function->shared()->code();
+  if (args.length() == 2 && unoptimized->kind() == Code::FUNCTION) {
+    CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
+    if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
+      // Start patching from the currently patched loop nesting level.
+      DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
+      isolate->runtime_profiler()->AttemptOnStackReplacement(
+          *function, Code::kMaxLoopNestingMarker);
+    } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
+               isolate->concurrent_recompilation_enabled()) {
+      function->MarkForConcurrentOptimization();
+    }
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, function, 0);
+  function->shared()->set_optimization_disabled(true);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
+  if (!isolate->use_crankshaft()) {
+    return Smi::FromInt(4);  // 4 == "never".
+  }
+  bool sync_with_compiler_thread = true;
+  if (args.length() == 2) {
+    CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
+    if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
+      sync_with_compiler_thread = false;
+    }
+  }
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  if (isolate->concurrent_recompilation_enabled() &&
+      sync_with_compiler_thread) {
+    while (function->IsInOptimizationQueue()) {
+      isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+      base::OS::Sleep(50);
+    }
+  }
+  if (FLAG_always_opt) {
+    // We may have always opt, but that is more best-effort than a real
+    // promise, so we still say "no" if it is not optimized.
+    return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
+                                   : Smi::FromInt(2);  // 2 == "no".
+  }
+  if (FLAG_deopt_every_n_times) {
+    return Smi::FromInt(6);  // 6 == "maybe deopted".
+  }
+  if (function->IsOptimized() && function->code()->is_turbofanned()) {
+    return Smi::FromInt(7);  // 7 == "TurboFan compiler".
+  }
+  return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
+                                 : Smi::FromInt(2);  // 2 == "no".
+}
+
+
+RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
+  DCHECK(args.length() == 0);
+  RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
+  RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
+  isolate->optimizing_compiler_thread()->Unblock();
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  return Smi::FromInt(function->shared()->opt_count());
+}
+
+
+RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  function->shared()->ClearTypeFeedbackInfo();
+  Code* unoptimized = function->shared()->code();
+  if (unoptimized->kind() == Code::FUNCTION) {
+    unoptimized->ClearInlineCaches();
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  isolate->heap()->NotifyContextDisposed();
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2 || args.length() == 3);
+#ifdef DEBUG
+  CONVERT_SMI_ARG_CHECKED(interval, 0);
+  CONVERT_SMI_ARG_CHECKED(timeout, 1);
+  isolate->heap()->set_allocation_timeout(timeout);
+  FLAG_gc_interval = interval;
+  if (args.length() == 3) {
+    // Enable/disable inline allocation if requested.
+    CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
+    if (inline_allocation) {
+      isolate->heap()->EnableInlineAllocation();
+    } else {
+      isolate->heap()->DisableInlineAllocation();
+    }
+  }
+#endif
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugPrint) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  OFStream os(stdout);
+#ifdef DEBUG
+  if (args[0]->IsString()) {
+    // If we have a string, assume it's a code "marker"
+    // and print some interesting cpu debugging info.
+    JavaScriptFrameIterator it(isolate);
+    JavaScriptFrame* frame = it.frame();
+    os << "fp = " << frame->fp() << ", sp = " << frame->sp()
+       << ", caller_sp = " << frame->caller_sp() << ": ";
+  } else {
+    os << "DebugPrint: ";
+  }
+  args[0]->Print(os);
+  if (args[0]->IsHeapObject()) {
+    os << "\n";
+    HeapObject::cast(args[0])->map()->Print(os);
+  }
+#else
+  // ShortPrint is available in release mode. Print is not.
+  os << Brief(args[0]);
+#endif
+  os << endl;
+
+  return args[0];  // return TOS
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugTrace) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  isolate->PrintStack(stdout);
+  return isolate->heap()->undefined_value();
+}
+
+
+// This will not allocate (flatten the string), but it may run
+// very slowly for very deeply nested ConsStrings.  For debugging use only.
+RUNTIME_FUNCTION(Runtime_GlobalPrint) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(String, string, 0);
+  ConsStringIteratorOp op;
+  StringCharacterStream stream(string, &op);
+  while (stream.HasMore()) {
+    uint16_t character = stream.GetNext();
+    PrintF("%c", character);
+  }
+  return string;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SystemBreak) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  base::OS::DebugBreak();
+  return isolate->heap()->undefined_value();
+}
+
+
+// Sets a v8 flag.
+RUNTIME_FUNCTION(Runtime_SetFlags) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(String, arg, 0);
+  SmartArrayPointer<char> flags =
+      arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+  FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_Abort) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_SMI_ARG_CHECKED(message_id, 0);
+  const char* message =
+      GetBailoutReason(static_cast<BailoutReason>(message_id));
+  base::OS::PrintError("abort: %s\n", message);
+  isolate->PrintStack(stderr);
+  base::OS::Abort();
+  UNREACHABLE();
+  return NULL;
+}
+
+
+RUNTIME_FUNCTION(Runtime_AbortJS) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
+  base::OS::PrintError("abort: %s\n", message->ToCString().get());
+  isolate->PrintStack(stderr);
+  base::OS::Abort();
+  UNREACHABLE();
+  return NULL;
+}
+
+
+RUNTIME_FUNCTION(Runtime_HaveSameMap) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSObject, obj1, 0);
+  CONVERT_ARG_CHECKED(JSObject, obj2, 1);
+  return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
+}
+
+
+#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)       \
+  RUNTIME_FUNCTION(Runtime_Has##Name) {                  \
+    CONVERT_ARG_CHECKED(JSObject, obj, 0);               \
+    return isolate->heap()->ToBoolean(obj->Has##Name()); \
+  }
+
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
+// Properties test sitting with elements tests - not fooling anyone.
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
+
+#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-typedarray.cc b/src/runtime/runtime-typedarray.cc
new file mode 100644 (file)
index 0000000..c138a4f
--- /dev/null
@@ -0,0 +1,760 @@
+// Copyright 2014 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/v8.h"
+
+#include "src/arguments.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+
+namespace v8 {
+namespace internal {
+
+void Runtime::FreeArrayBuffer(Isolate* isolate,
+                              JSArrayBuffer* phantom_array_buffer) {
+  if (phantom_array_buffer->should_be_freed()) {
+    DCHECK(phantom_array_buffer->is_external());
+    free(phantom_array_buffer->backing_store());
+  }
+  if (phantom_array_buffer->is_external()) return;
+
+  size_t allocated_length =
+      NumberToSize(isolate, phantom_array_buffer->byte_length());
+
+  reinterpret_cast<v8::Isolate*>(isolate)
+      ->AdjustAmountOfExternalAllocatedMemory(
+          -static_cast<int64_t>(allocated_length));
+  CHECK(V8::ArrayBufferAllocator() != NULL);
+  V8::ArrayBufferAllocator()->Free(phantom_array_buffer->backing_store(),
+                                   allocated_length);
+}
+
+
+void Runtime::SetupArrayBuffer(Isolate* isolate,
+                               Handle<JSArrayBuffer> array_buffer,
+                               bool is_external, void* data,
+                               size_t allocated_length) {
+  DCHECK(array_buffer->GetInternalFieldCount() ==
+         v8::ArrayBuffer::kInternalFieldCount);
+  for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
+    array_buffer->SetInternalField(i, Smi::FromInt(0));
+  }
+  array_buffer->set_backing_store(data);
+  array_buffer->set_flag(Smi::FromInt(0));
+  array_buffer->set_is_external(is_external);
+
+  Handle<Object> byte_length =
+      isolate->factory()->NewNumberFromSize(allocated_length);
+  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
+  array_buffer->set_byte_length(*byte_length);
+
+  array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
+  isolate->heap()->set_array_buffers_list(*array_buffer);
+  array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
+}
+
+
+bool Runtime::SetupArrayBufferAllocatingData(Isolate* isolate,
+                                             Handle<JSArrayBuffer> array_buffer,
+                                             size_t allocated_length,
+                                             bool initialize) {
+  void* data;
+  CHECK(V8::ArrayBufferAllocator() != NULL);
+  if (allocated_length != 0) {
+    if (initialize) {
+      data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
+    } else {
+      data =
+          V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
+    }
+    if (data == NULL) return false;
+  } else {
+    data = NULL;
+  }
+
+  SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
+
+  reinterpret_cast<v8::Isolate*>(isolate)
+      ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
+
+  return true;
+}
+
+
+void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
+  Isolate* isolate = array_buffer->GetIsolate();
+  for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
+       !view_obj->IsUndefined();) {
+    Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
+    if (view->IsJSTypedArray()) {
+      JSTypedArray::cast(*view)->Neuter();
+    } else if (view->IsJSDataView()) {
+      JSDataView::cast(*view)->Neuter();
+    } else {
+      UNREACHABLE();
+    }
+    view_obj = handle(view->weak_next(), isolate);
+  }
+  array_buffer->Neuter();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
+  if (!holder->byte_length()->IsUndefined()) {
+    // ArrayBuffer is already initialized; probably a fuzz test.
+    return *holder;
+  }
+  size_t allocated_length = 0;
+  if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+  if (!Runtime::SetupArrayBufferAllocatingData(isolate, holder,
+                                               allocated_length)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
+  return holder->byte_length();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
+  RUNTIME_ASSERT(!source.is_identical_to(target));
+  size_t start = 0;
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
+  size_t target_length = NumberToSize(isolate, target->byte_length());
+
+  if (target_length == 0) return isolate->heap()->undefined_value();
+
+  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
+  RUNTIME_ASSERT(start <= source_byte_length);
+  RUNTIME_ASSERT(source_byte_length - start >= target_length);
+  uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
+  uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
+  CopyBytes(target_data, source_data + start, target_length);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, object, 0);
+  return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
+  if (array_buffer->backing_store() == NULL) {
+    CHECK(Smi::FromInt(0) == array_buffer->byte_length());
+    return isolate->heap()->undefined_value();
+  }
+  DCHECK(!array_buffer->is_external());
+  void* backing_store = array_buffer->backing_store();
+  size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
+  array_buffer->set_is_external(true);
+  Runtime::NeuterArrayBuffer(array_buffer);
+  V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
+  return isolate->heap()->undefined_value();
+}
+
+
+void Runtime::ArrayIdToTypeAndSize(int arrayId, ExternalArrayType* array_type,
+                                   ElementsKind* external_elements_kind,
+                                   ElementsKind* fixed_elements_kind,
+                                   size_t* element_size) {
+  switch (arrayId) {
+#define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)      \
+  case ARRAY_ID_##TYPE:                                   \
+    *array_type = kExternal##Type##Array;                 \
+    *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS; \
+    *fixed_elements_kind = TYPE##_ELEMENTS;               \
+    *element_size = size;                                 \
+    break;
+
+    TYPED_ARRAYS(ARRAY_ID_CASE)
+#undef ARRAY_ID_CASE
+
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 5);
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
+
+  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
+                 arrayId <= Runtime::ARRAY_ID_LAST);
+
+  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
+  size_t element_size = 1;                            // Bogus initialization.
+  ElementsKind external_elements_kind =
+      EXTERNAL_INT8_ELEMENTS;                        // Bogus initialization.
+  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
+  Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind,
+                                &fixed_elements_kind, &element_size);
+  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
+
+  size_t byte_offset = 0;
+  size_t byte_length = 0;
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
+
+  if (maybe_buffer->IsJSArrayBuffer()) {
+    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
+    size_t array_buffer_byte_length =
+        NumberToSize(isolate, buffer->byte_length());
+    RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
+    RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
+  } else {
+    RUNTIME_ASSERT(maybe_buffer->IsNull());
+  }
+
+  RUNTIME_ASSERT(byte_length % element_size == 0);
+  size_t length = byte_length / element_size;
+
+  if (length > static_cast<unsigned>(Smi::kMaxValue)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_typed_array_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+
+  // All checks are done, now we can modify objects.
+
+  DCHECK(holder->GetInternalFieldCount() ==
+         v8::ArrayBufferView::kInternalFieldCount);
+  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
+    holder->SetInternalField(i, Smi::FromInt(0));
+  }
+  Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
+  holder->set_length(*length_obj);
+  holder->set_byte_offset(*byte_offset_object);
+  holder->set_byte_length(*byte_length_object);
+
+  if (!maybe_buffer->IsNull()) {
+    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
+    holder->set_buffer(*buffer);
+    holder->set_weak_next(buffer->weak_first_view());
+    buffer->set_weak_first_view(*holder);
+
+    Handle<ExternalArray> elements = isolate->factory()->NewExternalArray(
+        static_cast<int>(length), array_type,
+        static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
+    Handle<Map> map =
+        JSObject::GetElementsTransitionMap(holder, external_elements_kind);
+    JSObject::SetMapAndElements(holder, map, elements);
+    DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind()));
+  } else {
+    holder->set_buffer(Smi::FromInt(0));
+    holder->set_weak_next(isolate->heap()->undefined_value());
+    Handle<FixedTypedArrayBase> elements =
+        isolate->factory()->NewFixedTypedArray(static_cast<int>(length),
+                                               array_type);
+    holder->set_elements(*elements);
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+// Initializes a typed array from an array-like object.
+// If an array-like object happens to be a typed array of the same type,
+// initializes backing store using memove.
+//
+// Returns true if backing store was initialized or false otherwise.
+RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
+
+  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
+                 arrayId <= Runtime::ARRAY_ID_LAST);
+
+  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
+  size_t element_size = 1;                            // Bogus initialization.
+  ElementsKind external_elements_kind =
+      EXTERNAL_INT8_ELEMENTS;                        // Bogus intialization.
+  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
+  Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind,
+                                &fixed_elements_kind, &element_size);
+
+  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
+
+  Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
+  if (source->IsJSTypedArray() &&
+      JSTypedArray::cast(*source)->type() == array_type) {
+    length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
+  }
+  size_t length = 0;
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
+
+  if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
+      (length > (kMaxInt / element_size))) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_typed_array_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+  size_t byte_length = length * element_size;
+
+  DCHECK(holder->GetInternalFieldCount() ==
+         v8::ArrayBufferView::kInternalFieldCount);
+  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
+    holder->SetInternalField(i, Smi::FromInt(0));
+  }
+
+  // NOTE: not initializing backing store.
+  // We assume that the caller of this function will initialize holder
+  // with the loop
+  //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
+  // We assume that the caller of this function is always a typed array
+  // constructor.
+  // If source is a typed array, this loop will always run to completion,
+  // so we are sure that the backing store will be initialized.
+  // Otherwise, the indexing operation might throw, so the loop will not
+  // run to completion and the typed array might remain partly initialized.
+  // However we further assume that the caller of this function is a typed array
+  // constructor, and the exception will propagate out of the constructor,
+  // therefore uninitialized memory will not be accessible by a user program.
+  //
+  // TODO(dslomov): revise this once we support subclassing.
+
+  if (!Runtime::SetupArrayBufferAllocatingData(isolate, buffer, byte_length,
+                                               false)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+
+  holder->set_buffer(*buffer);
+  holder->set_byte_offset(Smi::FromInt(0));
+  Handle<Object> byte_length_obj(
+      isolate->factory()->NewNumberFromSize(byte_length));
+  holder->set_byte_length(*byte_length_obj);
+  holder->set_length(*length_obj);
+  holder->set_weak_next(buffer->weak_first_view());
+  buffer->set_weak_first_view(*holder);
+
+  Handle<ExternalArray> elements = isolate->factory()->NewExternalArray(
+      static_cast<int>(length), array_type,
+      static_cast<uint8_t*>(buffer->backing_store()));
+  Handle<Map> map =
+      JSObject::GetElementsTransitionMap(holder, external_elements_kind);
+  JSObject::SetMapAndElements(holder, map, elements);
+
+  if (source->IsJSTypedArray()) {
+    Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
+
+    if (typed_array->type() == holder->type()) {
+      uint8_t* backing_store =
+          static_cast<uint8_t*>(typed_array->GetBuffer()->backing_store());
+      size_t source_byte_offset =
+          NumberToSize(isolate, typed_array->byte_offset());
+      memcpy(buffer->backing_store(), backing_store + source_byte_offset,
+             byte_length);
+      return isolate->heap()->true_value();
+    }
+  }
+
+  return isolate->heap()->false_value();
+}
+
+
+#define BUFFER_VIEW_GETTER(Type, getter, accessor)   \
+  RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {    \
+    HandleScope scope(isolate);                      \
+    DCHECK(args.length() == 1);                      \
+    CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
+    return holder->accessor();                       \
+  }
+
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
+BUFFER_VIEW_GETTER(TypedArray, Length, length)
+BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
+
+#undef BUFFER_VIEW_GETTER
+
+RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+  return *holder->GetBuffer();
+}
+
+
+// Return codes for Runtime_TypedArraySetFastCases.
+// Should be synchronized with typedarray.js natives.
+enum TypedArraySetResultCodes {
+  // Set from typed array of the same type.
+  // This is processed by TypedArraySetFastCases
+  TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
+  // Set from typed array of the different type, overlapping in memory.
+  TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
+  // Set from typed array of the different type, non-overlapping.
+  TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
+  // Set from non-typed array.
+  TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
+};
+
+
+RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  if (!args[0]->IsJSTypedArray()) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError("not_typed_array", HandleVector<Object>(NULL, 0)));
+  }
+
+  if (!args[1]->IsJSTypedArray())
+    return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
+
+  Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
+  Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
+  size_t offset = 0;
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
+  size_t target_length = NumberToSize(isolate, target->length());
+  size_t source_length = NumberToSize(isolate, source->length());
+  size_t target_byte_length = NumberToSize(isolate, target->byte_length());
+  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
+  if (offset > target_length || offset + source_length > target_length ||
+      offset + source_length < offset) {  // overflow
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("typed_array_set_source_too_large",
+                               HandleVector<Object>(NULL, 0)));
+  }
+
+  size_t target_offset = NumberToSize(isolate, target->byte_offset());
+  size_t source_offset = NumberToSize(isolate, source->byte_offset());
+  uint8_t* target_base =
+      static_cast<uint8_t*>(target->GetBuffer()->backing_store()) +
+      target_offset;
+  uint8_t* source_base =
+      static_cast<uint8_t*>(source->GetBuffer()->backing_store()) +
+      source_offset;
+
+  // Typed arrays of the same type: use memmove.
+  if (target->type() == source->type()) {
+    memmove(target_base + offset * target->element_size(), source_base,
+            source_byte_length);
+    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
+  }
+
+  // Typed arrays of different types over the same backing store
+  if ((source_base <= target_base &&
+       source_base + source_byte_length > target_base) ||
+      (target_base <= source_base &&
+       target_base + target_byte_length > source_base)) {
+    // We do not support overlapping ArrayBuffers
+    DCHECK(target->GetBuffer()->backing_store() ==
+           source->GetBuffer()->backing_store());
+    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
+  } else {  // Non-overlapping typed arrays
+    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
+  DCHECK(args.length() == 0);
+  DCHECK_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap +
+                     FixedTypedArrayBase::kDataOffset);
+  return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
+}
+
+
+RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
+
+  DCHECK(holder->GetInternalFieldCount() ==
+         v8::ArrayBufferView::kInternalFieldCount);
+  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
+    holder->SetInternalField(i, Smi::FromInt(0));
+  }
+  size_t buffer_length = 0;
+  size_t offset = 0;
+  size_t length = 0;
+  RUNTIME_ASSERT(
+      TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
+
+  // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
+  // Entire range [offset, offset + length] must be in bounds.
+  RUNTIME_ASSERT(offset <= buffer_length);
+  RUNTIME_ASSERT(offset + length <= buffer_length);
+  // No overflow.
+  RUNTIME_ASSERT(offset + length >= offset);
+
+  holder->set_buffer(*buffer);
+  holder->set_byte_offset(*byte_offset);
+  holder->set_byte_length(*byte_length);
+
+  holder->set_weak_next(buffer->weak_first_view());
+  buffer->set_weak_first_view(*holder);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+inline static bool NeedToFlipBytes(bool is_little_endian) {
+#ifdef V8_TARGET_LITTLE_ENDIAN
+  return !is_little_endian;
+#else
+  return is_little_endian;
+#endif
+}
+
+
+template <int n>
+inline void CopyBytes(uint8_t* target, uint8_t* source) {
+  for (int i = 0; i < n; i++) {
+    *(target++) = *(source++);
+  }
+}
+
+
+template <int n>
+inline void FlipBytes(uint8_t* target, uint8_t* source) {
+  source = source + (n - 1);
+  for (int i = 0; i < n; i++) {
+    *(target++) = *(source--);
+  }
+}
+
+
+template <typename T>
+inline static bool DataViewGetValue(Isolate* isolate,
+                                    Handle<JSDataView> data_view,
+                                    Handle<Object> byte_offset_obj,
+                                    bool is_little_endian, T* result) {
+  size_t byte_offset = 0;
+  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+    return false;
+  }
+  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
+
+  size_t data_view_byte_offset =
+      NumberToSize(isolate, data_view->byte_offset());
+  size_t data_view_byte_length =
+      NumberToSize(isolate, data_view->byte_length());
+  if (byte_offset + sizeof(T) > data_view_byte_length ||
+      byte_offset + sizeof(T) < byte_offset) {  // overflow
+    return false;
+  }
+
+  union Value {
+    T data;
+    uint8_t bytes[sizeof(T)];
+  };
+
+  Value value;
+  size_t buffer_offset = data_view_byte_offset + byte_offset;
+  DCHECK(NumberToSize(isolate, buffer->byte_length()) >=
+         buffer_offset + sizeof(T));
+  uint8_t* source =
+      static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
+  if (NeedToFlipBytes(is_little_endian)) {
+    FlipBytes<sizeof(T)>(value.bytes, source);
+  } else {
+    CopyBytes<sizeof(T)>(value.bytes, source);
+  }
+  *result = value.data;
+  return true;
+}
+
+
+template <typename T>
+static bool DataViewSetValue(Isolate* isolate, Handle<JSDataView> data_view,
+                             Handle<Object> byte_offset_obj,
+                             bool is_little_endian, T data) {
+  size_t byte_offset = 0;
+  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+    return false;
+  }
+  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
+
+  size_t data_view_byte_offset =
+      NumberToSize(isolate, data_view->byte_offset());
+  size_t data_view_byte_length =
+      NumberToSize(isolate, data_view->byte_length());
+  if (byte_offset + sizeof(T) > data_view_byte_length ||
+      byte_offset + sizeof(T) < byte_offset) {  // overflow
+    return false;
+  }
+
+  union Value {
+    T data;
+    uint8_t bytes[sizeof(T)];
+  };
+
+  Value value;
+  value.data = data;
+  size_t buffer_offset = data_view_byte_offset + byte_offset;
+  DCHECK(NumberToSize(isolate, buffer->byte_length()) >=
+         buffer_offset + sizeof(T));
+  uint8_t* target =
+      static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
+  if (NeedToFlipBytes(is_little_endian)) {
+    FlipBytes<sizeof(T)>(target, value.bytes);
+  } else {
+    CopyBytes<sizeof(T)>(target, value.bytes);
+  }
+  return true;
+}
+
+
+#define DATA_VIEW_GETTER(TypeName, Type, Converter)                   \
+  RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                   \
+    HandleScope scope(isolate);                                       \
+    DCHECK(args.length() == 3);                                       \
+    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                \
+    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                     \
+    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                 \
+    Type result;                                                      \
+    if (DataViewGetValue(isolate, holder, offset, is_little_endian,   \
+                         &result)) {                                  \
+      return *isolate->factory()->Converter(result);                  \
+    } else {                                                          \
+      THROW_NEW_ERROR_RETURN_FAILURE(                                 \
+          isolate, NewRangeError("invalid_data_view_accessor_offset", \
+                                 HandleVector<Object>(NULL, 0)));     \
+    }                                                                 \
+  }
+
+DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Float32, float, NewNumber)
+DATA_VIEW_GETTER(Float64, double, NewNumber)
+
+#undef DATA_VIEW_GETTER
+
+
+template <typename T>
+static T DataViewConvertValue(double value);
+
+
+template <>
+int8_t DataViewConvertValue<int8_t>(double value) {
+  return static_cast<int8_t>(DoubleToInt32(value));
+}
+
+
+template <>
+int16_t DataViewConvertValue<int16_t>(double value) {
+  return static_cast<int16_t>(DoubleToInt32(value));
+}
+
+
+template <>
+int32_t DataViewConvertValue<int32_t>(double value) {
+  return DoubleToInt32(value);
+}
+
+
+template <>
+uint8_t DataViewConvertValue<uint8_t>(double value) {
+  return static_cast<uint8_t>(DoubleToUint32(value));
+}
+
+
+template <>
+uint16_t DataViewConvertValue<uint16_t>(double value) {
+  return static_cast<uint16_t>(DoubleToUint32(value));
+}
+
+
+template <>
+uint32_t DataViewConvertValue<uint32_t>(double value) {
+  return DoubleToUint32(value);
+}
+
+
+template <>
+float DataViewConvertValue<float>(double value) {
+  return static_cast<float>(value);
+}
+
+
+template <>
+double DataViewConvertValue<double>(double value) {
+  return value;
+}
+
+
+#define DATA_VIEW_SETTER(TypeName, Type)                                  \
+  RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                       \
+    HandleScope scope(isolate);                                           \
+    DCHECK(args.length() == 4);                                           \
+    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                    \
+    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                         \
+    CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                          \
+    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                     \
+    Type v = DataViewConvertValue<Type>(value->Number());                 \
+    if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \
+      return isolate->heap()->undefined_value();                          \
+    } else {                                                              \
+      THROW_NEW_ERROR_RETURN_FAILURE(                                     \
+          isolate, NewRangeError("invalid_data_view_accessor_offset",     \
+                                 HandleVector<Object>(NULL, 0)));         \
+    }                                                                     \
+  }
+
+DATA_VIEW_SETTER(Uint8, uint8_t)
+DATA_VIEW_SETTER(Int8, int8_t)
+DATA_VIEW_SETTER(Uint16, uint16_t)
+DATA_VIEW_SETTER(Int16, int16_t)
+DATA_VIEW_SETTER(Uint32, uint32_t)
+DATA_VIEW_SETTER(Int32, int32_t)
+DATA_VIEW_SETTER(Float32, float)
+DATA_VIEW_SETTER(Float64, double)
+
+#undef DATA_VIEW_SETTER
+}
+}  // namespace v8::internal
index 0cafc3e..427b821 100644 (file)
 #include "src/utils.h"
 #include "src/v8threads.h"
 #include "src/vm-state-inl.h"
-#include "third_party/fdlibm/fdlibm.h"
 
 
-#ifndef _STLP_VENDOR_CSTD
-// STLPort doesn't import fpclassify and isless into the std namespace.
-using std::fpclassify;
-using std::isless;
-#endif
-
 namespace v8 {
 namespace internal {
 
@@ -647,4456 +640,2640 @@ RUNTIME_FUNCTION(Runtime_Fix) {
 }
 
 
-void Runtime::FreeArrayBuffer(Isolate* isolate,
-                              JSArrayBuffer* phantom_array_buffer) {
-  if (phantom_array_buffer->should_be_freed()) {
-    DCHECK(phantom_array_buffer->is_external());
-    free(phantom_array_buffer->backing_store());
+RUNTIME_FUNCTION(Runtime_GetPrototype) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
+  // We don't expect access checks to be needed on JSProxy objects.
+  DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
+  PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+  do {
+    if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
+        !isolate->MayNamedAccess(
+            Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+            isolate->factory()->proto_string(), v8::ACCESS_GET)) {
+      isolate->ReportFailedAccessCheck(
+          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+          v8::ACCESS_GET);
+      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+      return isolate->heap()->undefined_value();
+    }
+    iter.AdvanceIgnoringProxies();
+    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+      return *PrototypeIterator::GetCurrent(iter);
+    }
+  } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
+  return *PrototypeIterator::GetCurrent(iter);
+}
+
+
+static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
+    Isolate* isolate, Handle<Object> receiver) {
+  PrototypeIterator iter(isolate, receiver);
+  while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
+    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+      return PrototypeIterator::GetCurrent(iter);
+    }
+    iter.Advance();
   }
-  if (phantom_array_buffer->is_external()) return;
+  return PrototypeIterator::GetCurrent(iter);
+}
 
-  size_t allocated_length =
-      NumberToSize(isolate, phantom_array_buffer->byte_length());
 
-  reinterpret_cast<v8::Isolate*>(isolate)
-      ->AdjustAmountOfExternalAllocatedMemory(
-          -static_cast<int64_t>(allocated_length));
-  CHECK(V8::ArrayBufferAllocator() != NULL);
-  V8::ArrayBufferAllocator()->Free(phantom_array_buffer->backing_store(),
-                                   allocated_length);
+RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+  DCHECK(!obj->IsAccessCheckNeeded());
+  DCHECK(!obj->map()->is_observed());
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, JSObject::SetPrototype(obj, prototype, false));
+  return *result;
 }
 
 
-void Runtime::SetupArrayBuffer(Isolate* isolate,
-                               Handle<JSArrayBuffer> array_buffer,
-                               bool is_external, void* data,
-                               size_t allocated_length) {
-  DCHECK(array_buffer->GetInternalFieldCount() ==
-         v8::ArrayBuffer::kInternalFieldCount);
-  for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
-    array_buffer->SetInternalField(i, Smi::FromInt(0));
+RUNTIME_FUNCTION(Runtime_SetPrototype) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+  if (obj->IsAccessCheckNeeded() &&
+      !isolate->MayNamedAccess(obj, isolate->factory()->proto_string(),
+                               v8::ACCESS_SET)) {
+    isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
+    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+    return isolate->heap()->undefined_value();
   }
-  array_buffer->set_backing_store(data);
-  array_buffer->set_flag(Smi::FromInt(0));
-  array_buffer->set_is_external(is_external);
-
-  Handle<Object> byte_length =
-      isolate->factory()->NewNumberFromSize(allocated_length);
-  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
-  array_buffer->set_byte_length(*byte_length);
+  if (obj->map()->is_observed()) {
+    Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
+    Handle<Object> result;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result, JSObject::SetPrototype(obj, prototype, true));
 
-  array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
-  isolate->heap()->set_array_buffers_list(*array_buffer);
-  array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
+    Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
+    if (!new_value->SameValue(*old_value)) {
+      JSObject::EnqueueChangeRecord(
+          obj, "setPrototype", isolate->factory()->proto_string(), old_value);
+    }
+    return *result;
+  }
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, JSObject::SetPrototype(obj, prototype, true));
+  return *result;
 }
 
 
-bool Runtime::SetupArrayBufferAllocatingData(Isolate* isolate,
-                                             Handle<JSArrayBuffer> array_buffer,
-                                             size_t allocated_length,
-                                             bool initialize) {
-  void* data;
-  CHECK(V8::ArrayBufferAllocator() != NULL);
-  if (allocated_length != 0) {
-    if (initialize) {
-      data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
-    } else {
-      data =
-          V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
-    }
-    if (data == NULL) return false;
-  } else {
-    data = NULL;
+RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
+  HandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
+  CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
+  PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
+  while (true) {
+    iter.AdvanceIgnoringProxies();
+    if (iter.IsAtEnd()) return isolate->heap()->false_value();
+    if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
   }
+}
+
 
-  SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
+// Enumerator used as indices into the array returned from GetOwnProperty
+enum PropertyDescriptorIndices {
+  IS_ACCESSOR_INDEX,
+  VALUE_INDEX,
+  GETTER_INDEX,
+  SETTER_INDEX,
+  WRITABLE_INDEX,
+  ENUMERABLE_INDEX,
+  CONFIGURABLE_INDEX,
+  DESCRIPTOR_SIZE
+};
 
-  reinterpret_cast<v8::Isolate*>(isolate)
-      ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
 
-  return true;
-}
+MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
+                                                          Handle<JSObject> obj,
+                                                          Handle<Name> name) {
+  Heap* heap = isolate->heap();
+  Factory* factory = isolate->factory();
 
+  PropertyAttributes attrs;
+  uint32_t index = 0;
+  Handle<Object> value;
+  MaybeHandle<AccessorPair> maybe_accessors;
+  // TODO(verwaest): Unify once indexed properties can be handled by the
+  // LookupIterator.
+  if (name->AsArrayIndex(&index)) {
+    // Get attributes.
+    Maybe<PropertyAttributes> maybe =
+        JSReceiver::GetOwnElementAttribute(obj, index);
+    if (!maybe.has_value) return MaybeHandle<Object>();
+    attrs = maybe.value;
+    if (attrs == ABSENT) return factory->undefined_value();
 
-void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
-  Isolate* isolate = array_buffer->GetIsolate();
-  for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
-       !view_obj->IsUndefined();) {
-    Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
-    if (view->IsJSTypedArray()) {
-      JSTypedArray::cast(*view)->Neuter();
-    } else if (view->IsJSDataView()) {
-      JSDataView::cast(*view)->Neuter();
-    } else {
-      UNREACHABLE();
+    // Get AccessorPair if present.
+    maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
+
+    // Get value if not an AccessorPair.
+    if (maybe_accessors.is_null()) {
+      ASSIGN_RETURN_ON_EXCEPTION(
+          isolate, value, Runtime::GetElementOrCharAt(isolate, obj, index),
+          Object);
     }
-    view_obj = handle(view->weak_next(), isolate);
-  }
-  array_buffer->Neuter();
-}
+  } else {
+    // Get attributes.
+    LookupIterator it(obj, name, LookupIterator::HIDDEN);
+    Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
+    if (!maybe.has_value) return MaybeHandle<Object>();
+    attrs = maybe.value;
+    if (attrs == ABSENT) return factory->undefined_value();
 
+    // Get AccessorPair if present.
+    if (it.state() == LookupIterator::ACCESSOR &&
+        it.GetAccessors()->IsAccessorPair()) {
+      maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
+    }
 
-RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
-  if (!holder->byte_length()->IsUndefined()) {
-    // ArrayBuffer is already initialized; probably a fuzz test.
-    return *holder;
-  }
-  size_t allocated_length = 0;
-  if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_array_buffer_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-  if (!Runtime::SetupArrayBufferAllocatingData(isolate, holder,
-                                               allocated_length)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_array_buffer_length",
-                               HandleVector<Object>(NULL, 0)));
+    // Get value if not an AccessorPair.
+    if (maybe_accessors.is_null()) {
+      ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it),
+                                 Object);
+    }
   }
-  return *holder;
-}
+  DCHECK(!isolate->has_pending_exception());
+  Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
+  elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
+  elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
+  elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null()));
 
+  Handle<AccessorPair> accessors;
+  if (maybe_accessors.ToHandle(&accessors)) {
+    Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
+    Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
+    elms->set(GETTER_INDEX, *getter);
+    elms->set(SETTER_INDEX, *setter);
+  } else {
+    elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
+    elms->set(VALUE_INDEX, *value);
+  }
 
-RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
-  return holder->byte_length();
+  return factory->NewJSArrayWithElements(elms);
 }
 
 
-RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
+// Returns an array with the property description:
+//  if args[1] is not a property on args[0]
+//          returns undefined
+//  if args[1] is a data property on args[0]
+//         [false, value, Writeable, Enumerable, Configurable]
+//  if args[1] is an accessor on args[0]
+//         [true, GetFunction, SetFunction, Enumerable, Configurable]
+RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
-  RUNTIME_ASSERT(!source.is_identical_to(target));
-  size_t start = 0;
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
-  size_t target_length = NumberToSize(isolate, target->byte_length());
-
-  if (target_length == 0) return isolate->heap()->undefined_value();
-
-  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
-  RUNTIME_ASSERT(start <= source_byte_length);
-  RUNTIME_ASSERT(source_byte_length - start >= target_length);
-  uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
-  uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
-  CopyBytes(target_data, source_data + start, target_length);
-  return isolate->heap()->undefined_value();
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     GetOwnProperty(isolate, obj, name));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
+RUNTIME_FUNCTION(Runtime_PreventExtensions) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, object, 0);
-  return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     JSObject::PreventExtensions(obj));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
+RUNTIME_FUNCTION(Runtime_ToMethod) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
-  if (array_buffer->backing_store() == NULL) {
-    CHECK(Smi::FromInt(0) == array_buffer->byte_length());
-    return isolate->heap()->undefined_value();
-  }
-  DCHECK(!array_buffer->is_external());
-  void* backing_store = array_buffer->backing_store();
-  size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
-  array_buffer->set_is_external(true);
-  Runtime::NeuterArrayBuffer(array_buffer);
-  V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
-  return isolate->heap()->undefined_value();
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  Handle<JSFunction> clone = JSFunction::CloneClosure(fun);
+  Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
+  JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol,
+                                           home_object, DONT_ENUM).Assert();
+  return *clone;
 }
 
 
-void Runtime::ArrayIdToTypeAndSize(int arrayId, ExternalArrayType* array_type,
-                                   ElementsKind* external_elements_kind,
-                                   ElementsKind* fixed_elements_kind,
-                                   size_t* element_size) {
-  switch (arrayId) {
-#define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)      \
-  case ARRAY_ID_##TYPE:                                   \
-    *array_type = kExternal##Type##Array;                 \
-    *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS; \
-    *fixed_elements_kind = TYPE##_ELEMENTS;               \
-    *element_size = size;                                 \
-    break;
-
-    TYPED_ARRAYS(ARRAY_ID_CASE)
-#undef ARRAY_ID_CASE
-
-    default:
-      UNREACHABLE();
-  }
+RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
+  DCHECK(args.length() == 0);
+  return isolate->heap()->home_object_symbol();
 }
 
 
-RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
+RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
-  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
-
-  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
-                 arrayId <= Runtime::ARRAY_ID_LAST);
-
-  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
-  size_t element_size = 1;                            // Bogus initialization.
-  ElementsKind external_elements_kind =
-      EXTERNAL_INT8_ELEMENTS;                        // Bogus initialization.
-  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
-  Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind,
-                                &fixed_elements_kind, &element_size);
-  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
-
-  size_t byte_offset = 0;
-  size_t byte_length = 0;
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
-
-  if (maybe_buffer->IsJSArrayBuffer()) {
-    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
-    size_t array_buffer_byte_length =
-        NumberToSize(isolate, buffer->byte_length());
-    RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
-    RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
-  } else {
-    RUNTIME_ASSERT(maybe_buffer->IsNull());
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
+
+  if (home_object->IsAccessCheckNeeded() &&
+      !isolate->MayNamedAccess(home_object, name, v8::ACCESS_GET)) {
+    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
+    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   }
 
-  RUNTIME_ASSERT(byte_length % element_size == 0);
-  size_t length = byte_length / element_size;
+  PrototypeIterator iter(isolate, home_object);
+  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
 
-  if (length > static_cast<unsigned>(Smi::kMaxValue)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_typed_array_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-
-  // All checks are done, now we can modify objects.
-
-  DCHECK(holder->GetInternalFieldCount() ==
-         v8::ArrayBufferView::kInternalFieldCount);
-  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
-    holder->SetInternalField(i, Smi::FromInt(0));
-  }
-  Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
-  holder->set_length(*length_obj);
-  holder->set_byte_offset(*byte_offset_object);
-  holder->set_byte_length(*byte_length_object);
-
-  if (!maybe_buffer->IsNull()) {
-    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
-    holder->set_buffer(*buffer);
-    holder->set_weak_next(buffer->weak_first_view());
-    buffer->set_weak_first_view(*holder);
-
-    Handle<ExternalArray> elements = isolate->factory()->NewExternalArray(
-        static_cast<int>(length), array_type,
-        static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
-    Handle<Map> map =
-        JSObject::GetElementsTransitionMap(holder, external_elements_kind);
-    JSObject::SetMapAndElements(holder, map, elements);
-    DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind()));
-  } else {
-    holder->set_buffer(Smi::FromInt(0));
-    holder->set_weak_next(isolate->heap()->undefined_value());
-    Handle<FixedTypedArrayBase> elements =
-        isolate->factory()->NewFixedTypedArray(static_cast<int>(length),
-                                               array_type);
-    holder->set_elements(*elements);
-  }
-  return isolate->heap()->undefined_value();
+  LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
+  return *result;
 }
 
 
-// Initializes a typed array from an array-like object.
-// If an array-like object happens to be a typed array of the same type,
-// initializes backing store using memove.
-//
-// Returns true if backing store was initialized or false otherwise.
-RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
-  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
-
-  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
-                 arrayId <= Runtime::ARRAY_ID_LAST);
-
-  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
-  size_t element_size = 1;                            // Bogus initialization.
-  ElementsKind external_elements_kind =
-      EXTERNAL_INT8_ELEMENTS;                        // Bogus intialization.
-  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
-  Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind,
-                                &fixed_elements_kind, &element_size);
-
-  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
-
-  Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
-  if (source->IsJSTypedArray() &&
-      JSTypedArray::cast(*source)->type() == array_type) {
-    length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
-  }
-  size_t length = 0;
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
-
-  if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
-      (length > (kMaxInt / element_size))) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_typed_array_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-  size_t byte_length = length * element_size;
-
-  DCHECK(holder->GetInternalFieldCount() ==
-         v8::ArrayBufferView::kInternalFieldCount);
-  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
-    holder->SetInternalField(i, Smi::FromInt(0));
-  }
-
-  // NOTE: not initializing backing store.
-  // We assume that the caller of this function will initialize holder
-  // with the loop
-  //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
-  // We assume that the caller of this function is always a typed array
-  // constructor.
-  // If source is a typed array, this loop will always run to completion,
-  // so we are sure that the backing store will be initialized.
-  // Otherwise, the indexing operation might throw, so the loop will not
-  // run to completion and the typed array might remain partly initialized.
-  // However we further assume that the caller of this function is a typed array
-  // constructor, and the exception will propagate out of the constructor,
-  // therefore uninitialized memory will not be accessible by a user program.
-  //
-  // TODO(dslomov): revise this once we support subclassing.
-
-  if (!Runtime::SetupArrayBufferAllocatingData(isolate, buffer, byte_length,
-                                               false)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_array_buffer_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-
-  holder->set_buffer(*buffer);
-  holder->set_byte_offset(Smi::FromInt(0));
-  Handle<Object> byte_length_obj(
-      isolate->factory()->NewNumberFromSize(byte_length));
-  holder->set_byte_length(*byte_length_obj);
-  holder->set_length(*length_obj);
-  holder->set_weak_next(buffer->weak_first_view());
-  buffer->set_weak_first_view(*holder);
-
-  Handle<ExternalArray> elements = isolate->factory()->NewExternalArray(
-      static_cast<int>(length), array_type,
-      static_cast<uint8_t*>(buffer->backing_store()));
-  Handle<Map> map =
-      JSObject::GetElementsTransitionMap(holder, external_elements_kind);
-  JSObject::SetMapAndElements(holder, map, elements);
-
-  if (source->IsJSTypedArray()) {
-    Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
-
-    if (typed_array->type() == holder->type()) {
-      uint8_t* backing_store =
-          static_cast<uint8_t*>(typed_array->GetBuffer()->backing_store());
-      size_t source_byte_offset =
-          NumberToSize(isolate, typed_array->byte_offset());
-      memcpy(buffer->backing_store(), backing_store + source_byte_offset,
-             byte_length);
-      return isolate->heap()->true_value();
-    }
-  }
-
-  return isolate->heap()->false_value();
-}
-
-
-#define BUFFER_VIEW_GETTER(Type, getter, accessor)   \
-  RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {    \
-    HandleScope scope(isolate);                      \
-    DCHECK(args.length() == 1);                      \
-    CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
-    return holder->accessor();                       \
+static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
+                            Handle<Object> receiver, Handle<Name> name,
+                            Handle<Object> value, StrictMode strict_mode) {
+  if (home_object->IsAccessCheckNeeded() &&
+      !isolate->MayNamedAccess(home_object, name, v8::ACCESS_SET)) {
+    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_SET);
+    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   }
 
-BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
-BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
-BUFFER_VIEW_GETTER(TypedArray, Length, length)
-BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
-
-#undef BUFFER_VIEW_GETTER
+  PrototypeIterator iter(isolate, home_object);
+  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
 
-RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
-  return *holder->GetBuffer();
-}
-
-
-// Return codes for Runtime_TypedArraySetFastCases.
-// Should be synchronized with typedarray.js natives.
-enum TypedArraySetResultCodes {
-  // Set from typed array of the same type.
-  // This is processed by TypedArraySetFastCases
-  TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
-  // Set from typed array of the different type, overlapping in memory.
-  TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
-  // Set from typed array of the different type, non-overlapping.
-  TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
-  // Set from non-typed array.
-  TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
-};
+  LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Object::SetProperty(&it, value, strict_mode,
+                          Object::CERTAINLY_NOT_STORE_FROM_KEYED,
+                          Object::SUPER_PROPERTY));
+  return *result;
+}
 
 
-RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
+RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  if (!args[0]->IsJSTypedArray()) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate,
-        NewTypeError("not_typed_array", HandleVector<Object>(NULL, 0)));
-  }
-
-  if (!args[1]->IsJSTypedArray())
-    return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
-
-  Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
-  Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
-  size_t offset = 0;
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
-  size_t target_length = NumberToSize(isolate, target->length());
-  size_t source_length = NumberToSize(isolate, source->length());
-  size_t target_byte_length = NumberToSize(isolate, target->byte_length());
-  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
-  if (offset > target_length || offset + source_length > target_length ||
-      offset + source_length < offset) {  // overflow
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("typed_array_set_source_too_large",
-                               HandleVector<Object>(NULL, 0)));
-  }
-
-  size_t target_offset = NumberToSize(isolate, target->byte_offset());
-  size_t source_offset = NumberToSize(isolate, source->byte_offset());
-  uint8_t* target_base =
-      static_cast<uint8_t*>(target->GetBuffer()->backing_store()) +
-      target_offset;
-  uint8_t* source_base =
-      static_cast<uint8_t*>(source->GetBuffer()->backing_store()) +
-      source_offset;
-
-  // Typed arrays of the same type: use memmove.
-  if (target->type() == source->type()) {
-    memmove(target_base + offset * target->element_size(), source_base,
-            source_byte_length);
-    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
-  }
-
-  // Typed arrays of different types over the same backing store
-  if ((source_base <= target_base &&
-       source_base + source_byte_length > target_base) ||
-      (target_base <= source_base &&
-       target_base + target_byte_length > source_base)) {
-    // We do not support overlapping ArrayBuffers
-    DCHECK(target->GetBuffer()->backing_store() ==
-           source->GetBuffer()->backing_store());
-    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
-  } else {  // Non-overlapping typed arrays
-    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
-  }
-}
-
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 3);
 
-RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
-  DCHECK(args.length() == 0);
-  DCHECK_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap +
-                     FixedTypedArrayBase::kDataOffset);
-  return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
+  return StoreToSuper(isolate, home_object, receiver, name, value, STRICT);
 }
 
 
-RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
+RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
-
-  DCHECK(holder->GetInternalFieldCount() ==
-         v8::ArrayBufferView::kInternalFieldCount);
-  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
-    holder->SetInternalField(i, Smi::FromInt(0));
-  }
-  size_t buffer_length = 0;
-  size_t offset = 0;
-  size_t length = 0;
-  RUNTIME_ASSERT(
-      TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
-
-  // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
-  // Entire range [offset, offset + length] must be in bounds.
-  RUNTIME_ASSERT(offset <= buffer_length);
-  RUNTIME_ASSERT(offset + length <= buffer_length);
-  // No overflow.
-  RUNTIME_ASSERT(offset + length >= offset);
-
-  holder->set_buffer(*buffer);
-  holder->set_byte_offset(*byte_offset);
-  holder->set_byte_length(*byte_length);
-
-  holder->set_weak_next(buffer->weak_first_view());
-  buffer->set_weak_first_view(*holder);
-
-  return isolate->heap()->undefined_value();
-}
-
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 3);
 
-inline static bool NeedToFlipBytes(bool is_little_endian) {
-#ifdef V8_TARGET_LITTLE_ENDIAN
-  return !is_little_endian;
-#else
-  return is_little_endian;
-#endif
+  return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY);
 }
 
 
-template <int n>
-inline void CopyBytes(uint8_t* target, uint8_t* source) {
-  for (int i = 0; i < n; i++) {
-    *(target++) = *(source++);
+RUNTIME_FUNCTION(Runtime_IsExtensible) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSObject, obj, 0);
+  if (obj->IsJSGlobalProxy()) {
+    PrototypeIterator iter(isolate, obj);
+    if (iter.IsAtEnd()) return isolate->heap()->false_value();
+    DCHECK(iter.GetCurrent()->IsJSGlobalObject());
+    obj = JSObject::cast(iter.GetCurrent());
   }
+  return isolate->heap()->ToBoolean(obj->map()->is_extensible());
 }
 
 
-template <int n>
-inline void FlipBytes(uint8_t* target, uint8_t* source) {
-  source = source + (n - 1);
-  for (int i = 0; i < n; i++) {
-    *(target++) = *(source--);
-  }
+RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+  return *isolate->factory()->CreateApiFunction(data, prototype);
 }
 
 
-template <typename T>
-inline static bool DataViewGetValue(Isolate* isolate,
-                                    Handle<JSDataView> data_view,
-                                    Handle<Object> byte_offset_obj,
-                                    bool is_little_endian, T* result) {
-  size_t byte_offset = 0;
-  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
-    return false;
-  }
-  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
-
-  size_t data_view_byte_offset =
-      NumberToSize(isolate, data_view->byte_offset());
-  size_t data_view_byte_length =
-      NumberToSize(isolate, data_view->byte_length());
-  if (byte_offset + sizeof(T) > data_view_byte_length ||
-      byte_offset + sizeof(T) < byte_offset) {  // overflow
-    return false;
-  }
-
-  union Value {
-    T data;
-    uint8_t bytes[sizeof(T)];
-  };
-
-  Value value;
-  size_t buffer_offset = data_view_byte_offset + byte_offset;
-  DCHECK(NumberToSize(isolate, buffer->byte_length()) >=
-         buffer_offset + sizeof(T));
-  uint8_t* source =
-      static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
-  if (NeedToFlipBytes(is_little_endian)) {
-    FlipBytes<sizeof(T)>(value.bytes, source);
-  } else {
-    CopyBytes<sizeof(T)>(value.bytes, source);
-  }
-  *result = value.data;
-  return true;
+RUNTIME_FUNCTION(Runtime_IsTemplate) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
+  bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
+  return isolate->heap()->ToBoolean(result);
 }
 
 
-template <typename T>
-static bool DataViewSetValue(Isolate* isolate, Handle<JSDataView> data_view,
-                             Handle<Object> byte_offset_obj,
-                             bool is_little_endian, T data) {
-  size_t byte_offset = 0;
-  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
-    return false;
-  }
-  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
-
-  size_t data_view_byte_offset =
-      NumberToSize(isolate, data_view->byte_offset());
-  size_t data_view_byte_length =
-      NumberToSize(isolate, data_view->byte_length());
-  if (byte_offset + sizeof(T) > data_view_byte_length ||
-      byte_offset + sizeof(T) < byte_offset) {  // overflow
-    return false;
-  }
-
-  union Value {
-    T data;
-    uint8_t bytes[sizeof(T)];
-  };
-
-  Value value;
-  value.data = data;
-  size_t buffer_offset = data_view_byte_offset + byte_offset;
-  DCHECK(NumberToSize(isolate, buffer->byte_length()) >=
-         buffer_offset + sizeof(T));
-  uint8_t* target =
-      static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
-  if (NeedToFlipBytes(is_little_endian)) {
-    FlipBytes<sizeof(T)>(target, value.bytes);
+RUNTIME_FUNCTION(Runtime_GetTemplateField) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(HeapObject, templ, 0);
+  CONVERT_SMI_ARG_CHECKED(index, 1);
+  int offset = index * kPointerSize + HeapObject::kHeaderSize;
+  InstanceType type = templ->map()->instance_type();
+  RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
+                 type == OBJECT_TEMPLATE_INFO_TYPE);
+  RUNTIME_ASSERT(offset > 0);
+  if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
+    RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
   } else {
-    CopyBytes<sizeof(T)>(target, value.bytes);
+    RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
   }
-  return true;
+  return *HeapObject::RawField(templ, offset);
 }
 
 
-#define DATA_VIEW_GETTER(TypeName, Type, Converter)                   \
-  RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                   \
-    HandleScope scope(isolate);                                       \
-    DCHECK(args.length() == 3);                                       \
-    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                \
-    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                     \
-    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                 \
-    Type result;                                                      \
-    if (DataViewGetValue(isolate, holder, offset, is_little_endian,   \
-                         &result)) {                                  \
-      return *isolate->factory()->Converter(result);                  \
-    } else {                                                          \
-      THROW_NEW_ERROR_RETURN_FAILURE(                                 \
-          isolate, NewRangeError("invalid_data_view_accessor_offset", \
-                                 HandleVector<Object>(NULL, 0)));     \
-    }                                                                 \
+RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
+  Handle<Map> old_map(object->map());
+  bool needs_access_checks = old_map->is_access_check_needed();
+  if (needs_access_checks) {
+    // Copy map so it won't interfere constructor's initial map.
+    Handle<Map> new_map = Map::Copy(old_map);
+    new_map->set_is_access_check_needed(false);
+    JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
   }
-
-DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
-DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
-DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
-DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
-DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
-DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
-DATA_VIEW_GETTER(Float32, float, NewNumber)
-DATA_VIEW_GETTER(Float64, double, NewNumber)
-
-#undef DATA_VIEW_GETTER
-
-
-template <typename T>
-static T DataViewConvertValue(double value);
-
-
-template <>
-int8_t DataViewConvertValue<int8_t>(double value) {
-  return static_cast<int8_t>(DoubleToInt32(value));
+  return isolate->heap()->ToBoolean(needs_access_checks);
 }
 
 
-template <>
-int16_t DataViewConvertValue<int16_t>(double value) {
-  return static_cast<int16_t>(DoubleToInt32(value));
+RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  Handle<Map> old_map(object->map());
+  RUNTIME_ASSERT(!old_map->is_access_check_needed());
+  // Copy map so it won't interfere constructor's initial map.
+  Handle<Map> new_map = Map::Copy(old_map);
+  new_map->set_is_access_check_needed(true);
+  JSObject::MigrateToMap(object, new_map);
+  return isolate->heap()->undefined_value();
 }
 
 
-template <>
-int32_t DataViewConvertValue<int32_t>(double value) {
-  return DoubleToInt32(value);
+static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
+  HandleScope scope(isolate);
+  Handle<Object> args[1] = {name};
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate, NewTypeError("var_redeclaration", HandleVector(args, 1)));
 }
 
 
-template <>
-uint8_t DataViewConvertValue<uint8_t>(double value) {
-  return static_cast<uint8_t>(DoubleToUint32(value));
-}
+// May throw a RedeclarationError.
+static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
+                              Handle<String> name, Handle<Object> value,
+                              PropertyAttributes attr, bool is_var,
+                              bool is_const, bool is_function) {
+  // Do the lookup own properties only, see ES5 erratum.
+  LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+  if (!maybe.has_value) return isolate->heap()->exception();
 
+  if (it.IsFound()) {
+    PropertyAttributes old_attributes = maybe.value;
+    // The name was declared before; check for conflicting re-declarations.
+    if (is_const) return ThrowRedeclarationError(isolate, name);
 
-template <>
-uint16_t DataViewConvertValue<uint16_t>(double value) {
-  return static_cast<uint16_t>(DoubleToUint32(value));
-}
+    // Skip var re-declarations.
+    if (is_var) return isolate->heap()->undefined_value();
 
+    DCHECK(is_function);
+    if ((old_attributes & DONT_DELETE) != 0) {
+      // Only allow reconfiguring globals to functions in user code (no
+      // natives, which are marked as read-only).
+      DCHECK((attr & READ_ONLY) == 0);
 
-template <>
-uint32_t DataViewConvertValue<uint32_t>(double value) {
-  return DoubleToUint32(value);
-}
+      // Check whether we can reconfigure the existing property into a
+      // function.
+      PropertyDetails old_details = it.property_details();
+      // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo,
+      // which are actually data properties, not accessor properties.
+      if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
+          old_details.type() == CALLBACKS) {
+        return ThrowRedeclarationError(isolate, name);
+      }
+      // If the existing property is not configurable, keep its attributes. Do
+      attr = old_attributes;
+    }
+  }
 
+  // Define or redefine own property.
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           global, name, value, attr));
 
-template <>
-float DataViewConvertValue<float>(double value) {
-  return static_cast<float>(value);
+  return isolate->heap()->undefined_value();
 }
 
 
-template <>
-double DataViewConvertValue<double>(double value) {
-  return value;
-}
-
+RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  Handle<GlobalObject> global(isolate->global_object());
 
-#define DATA_VIEW_SETTER(TypeName, Type)                                  \
-  RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                       \
-    HandleScope scope(isolate);                                           \
-    DCHECK(args.length() == 4);                                           \
-    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                    \
-    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                         \
-    CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                          \
-    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                     \
-    Type v = DataViewConvertValue<Type>(value->Number());                 \
-    if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \
-      return isolate->heap()->undefined_value();                          \
-    } else {                                                              \
-      THROW_NEW_ERROR_RETURN_FAILURE(                                     \
-          isolate, NewRangeError("invalid_data_view_accessor_offset",     \
-                                 HandleVector<Object>(NULL, 0)));         \
-    }                                                                     \
-  }
+  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
+  CONVERT_SMI_ARG_CHECKED(flags, 2);
 
-DATA_VIEW_SETTER(Uint8, uint8_t)
-DATA_VIEW_SETTER(Int8, int8_t)
-DATA_VIEW_SETTER(Uint16, uint16_t)
-DATA_VIEW_SETTER(Int16, int16_t)
-DATA_VIEW_SETTER(Uint32, uint32_t)
-DATA_VIEW_SETTER(Int32, int32_t)
-DATA_VIEW_SETTER(Float32, float)
-DATA_VIEW_SETTER(Float64, double)
+  // Traverse the name/value pairs and set the properties.
+  int length = pairs->length();
+  for (int i = 0; i < length; i += 2) {
+    HandleScope scope(isolate);
+    Handle<String> name(String::cast(pairs->get(i)));
+    Handle<Object> initial_value(pairs->get(i + 1), isolate);
 
-#undef DATA_VIEW_SETTER
+    // We have to declare a global const property. To capture we only
+    // assign to it when evaluating the assignment for "const x =
+    // <expr>" the initial value is the hole.
+    bool is_var = initial_value->IsUndefined();
+    bool is_const = initial_value->IsTheHole();
+    bool is_function = initial_value->IsSharedFunctionInfo();
+    DCHECK(is_var + is_const + is_function == 1);
 
+    Handle<Object> value;
+    if (is_function) {
+      // Copy the function and update its context. Use it as value.
+      Handle<SharedFunctionInfo> shared =
+          Handle<SharedFunctionInfo>::cast(initial_value);
+      Handle<JSFunction> function =
+          isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
+                                                                TENURED);
+      value = function;
+    } else {
+      value = isolate->factory()->undefined_value();
+    }
 
-RUNTIME_FUNCTION(Runtime_SetInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
-  holder->set_table(*table);
-  return *holder;
-}
+    // Compute the property attributes. According to ECMA-262,
+    // the property must be non-configurable except in eval.
+    bool is_native = DeclareGlobalsNativeFlag::decode(flags);
+    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
+    int attr = NONE;
+    if (is_const) attr |= READ_ONLY;
+    if (is_function && is_native) attr |= READ_ONLY;
+    if (!is_const && !is_eval) attr |= DONT_DELETE;
 
+    Object* result = DeclareGlobals(isolate, global, name, value,
+                                    static_cast<PropertyAttributes>(attr),
+                                    is_var, is_const, is_function);
+    if (isolate->has_pending_exception()) return result;
+  }
 
-RUNTIME_FUNCTION(Runtime_SetAdd) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  table = OrderedHashSet::Add(table, key);
-  holder->set_table(*table);
-  return *holder;
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_SetHas) {
+RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  return isolate->heap()->ToBoolean(table->Contains(key));
-}
-
+  // args[0] == name
+  // args[1] == language_mode
+  // args[2] == value (optional)
 
-RUNTIME_FUNCTION(Runtime_SetDelete) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  bool was_present = false;
-  table = OrderedHashSet::Remove(table, key, &was_present);
-  holder->set_table(*table);
-  return isolate->heap()->ToBoolean(was_present);
-}
+  // Determine if we need to assign to the variable if it already
+  // exists (based on the number of arguments).
+  RUNTIME_ASSERT(args.length() == 3);
 
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
 
-RUNTIME_FUNCTION(Runtime_SetClear) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  table = OrderedHashSet::Clear(table);
-  holder->set_table(*table);
-  return isolate->heap()->undefined_value();
+  Handle<GlobalObject> global(isolate->context()->global_object());
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, Object::SetProperty(global, name, value, strict_mode));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_SetGetSize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  return Smi::FromInt(table->NumberOfElements());
-}
+RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
+  HandleScope handle_scope(isolate);
+  // All constants are declared with an initial value. The name
+  // of the constant is the first argument and the initial value
+  // is the second.
+  RUNTIME_ASSERT(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
 
+  Handle<GlobalObject> global = isolate->global_object();
 
-RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
-  CONVERT_SMI_ARG_CHECKED(kind, 2)
-  RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
-                 kind == JSSetIterator::kKindEntries);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
-  holder->set_table(*table);
-  holder->set_index(Smi::FromInt(0));
-  holder->set_kind(Smi::FromInt(kind));
-  return isolate->heap()->undefined_value();
-}
+  // Lookup the property as own on the global object.
+  LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+  DCHECK(maybe.has_value);
+  PropertyAttributes old_attributes = maybe.value;
+
+  PropertyAttributes attr =
+      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+  // Set the value if the property is either missing, or the property attributes
+  // allow setting the value without invoking an accessor.
+  if (it.IsFound()) {
+    // Ignore if we can't reconfigure the value.
+    if ((old_attributes & DONT_DELETE) != 0) {
+      if ((old_attributes & READ_ONLY) != 0 ||
+          it.state() == LookupIterator::ACCESSOR) {
+        return *value;
+      }
+      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
+    }
+  }
 
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           global, name, value, attr));
 
-RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(JSSetIterator, holder, 0);
-  CONVERT_ARG_CHECKED(JSArray, value_array, 1);
-  return holder->Next(value_array);
+  return *value;
 }
 
 
-RUNTIME_FUNCTION(Runtime_MapInitialize) {
+RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
-  holder->set_table(*table);
-  return *holder;
-}
+  DCHECK(args.length() == 4);
 
+  // Declarations are always made in a function, native, or global context. In
+  // the case of eval code, the context passed is the context of the caller,
+  // which may be some nested context and not the declaration context.
+  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
+  Handle<Context> context(context_arg->declaration_context());
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
+  CONVERT_SMI_ARG_CHECKED(attr_arg, 2);
+  PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg);
+  RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE);
+  CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
 
-RUNTIME_FUNCTION(Runtime_MapGet) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  Handle<Object> lookup(table->Lookup(key), isolate);
-  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
-}
+  // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
+  bool is_var = *initial_value == NULL;
+  bool is_const = initial_value->IsTheHole();
+  bool is_function = initial_value->IsJSFunction();
+  DCHECK(is_var + is_const + is_function == 1);
 
+  int index;
+  PropertyAttributes attributes;
+  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
+  BindingFlags binding_flags;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding_flags);
 
-RUNTIME_FUNCTION(Runtime_MapHas) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  Handle<Object> lookup(table->Lookup(key), isolate);
-  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
-}
+  Handle<JSObject> object;
+  Handle<Object> value =
+      is_function ? initial_value
+                  : Handle<Object>::cast(isolate->factory()->undefined_value());
 
+  // TODO(verwaest): This case should probably not be covered by this function,
+  // but by DeclareGlobals instead.
+  if ((attributes != ABSENT && holder->IsJSGlobalObject()) ||
+      (context_arg->has_extension() &&
+       context_arg->extension()->IsJSGlobalObject())) {
+    return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
+                          value, attr, is_var, is_const, is_function);
+  }
 
-RUNTIME_FUNCTION(Runtime_MapDelete) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  bool was_present = false;
-  Handle<OrderedHashMap> new_table =
-      OrderedHashMap::Remove(table, key, &was_present);
-  holder->set_table(*new_table);
-  return isolate->heap()->ToBoolean(was_present);
-}
+  if (attributes != ABSENT) {
+    // The name was declared before; check for conflicting re-declarations.
+    if (is_const || (attributes & READ_ONLY) != 0) {
+      return ThrowRedeclarationError(isolate, name);
+    }
 
+    // Skip var re-declarations.
+    if (is_var) return isolate->heap()->undefined_value();
 
-RUNTIME_FUNCTION(Runtime_MapClear) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  table = OrderedHashMap::Clear(table);
-  holder->set_table(*table);
-  return isolate->heap()->undefined_value();
-}
+    DCHECK(is_function);
+    if (index >= 0) {
+      DCHECK(holder.is_identical_to(context));
+      context->set(index, *initial_value);
+      return isolate->heap()->undefined_value();
+    }
 
+    object = Handle<JSObject>::cast(holder);
 
-RUNTIME_FUNCTION(Runtime_MapSet) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
-  holder->set_table(*new_table);
-  return *holder;
-}
+  } else if (context->has_extension()) {
+    object = handle(JSObject::cast(context->extension()));
+    DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
+  } else {
+    DCHECK(context->IsFunctionContext());
+    object =
+        isolate->factory()->NewJSObject(isolate->context_extension_function());
+    context->set_extension(*object);
+  }
 
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           object, name, value, attr));
 
-RUNTIME_FUNCTION(Runtime_MapGetSize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  return Smi::FromInt(table->NumberOfElements());
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
+RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
-  CONVERT_SMI_ARG_CHECKED(kind, 2)
-  RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys ||
-                 kind == JSMapIterator::kKindValues ||
-                 kind == JSMapIterator::kKindEntries);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
-  holder->set_table(*table);
-  holder->set_index(Smi::FromInt(0));
-  holder->set_kind(Smi::FromInt(kind));
-  return isolate->heap()->undefined_value();
-}
 
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
+  DCHECK(!value->IsTheHole());
+  // Initializations are always done in a function or native context.
+  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
+  Handle<Context> context(context_arg->declaration_context());
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
+
+  int index;
+  PropertyAttributes attributes;
+  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
+  BindingFlags binding_flags;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding_flags);
 
-RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
-  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
-  Handle<FixedArray> entries =
-      isolate->factory()->NewFixedArray(table->NumberOfElements() * 2);
-  {
-    DisallowHeapAllocation no_gc;
-    int number_of_non_hole_elements = 0;
-    for (int i = 0; i < table->Capacity(); i++) {
-      Handle<Object> key(table->KeyAt(i), isolate);
-      if (table->IsKey(*key)) {
-        entries->set(number_of_non_hole_elements++, *key);
-        Object* value = table->Lookup(key);
-        entries->set(number_of_non_hole_elements++, value);
-      }
-    }
-    DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
+  if (index >= 0) {
+    DCHECK(holder->IsContext());
+    // Property was found in a context.  Perform the assignment if the constant
+    // was uninitialized.
+    Handle<Context> context = Handle<Context>::cast(holder);
+    DCHECK((attributes & READ_ONLY) != 0);
+    if (context->get(index)->IsTheHole()) context->set(index, *value);
+    return *value;
   }
-  return *isolate->factory()->NewJSArrayWithElements(entries);
-}
 
+  PropertyAttributes attr =
+      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+
+  // Strict mode handling not needed (legacy const is disallowed in strict
+  // mode).
 
-RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
-  CONVERT_ARG_CHECKED(JSArray, value_array, 1);
-  return holder->Next(value_array);
-}
+  // The declared const was configurable, and may have been deleted in the
+  // meanwhile. If so, re-introduce the variable in the context extension.
+  DCHECK(context_arg->has_extension());
+  if (attributes == ABSENT) {
+    holder = handle(context_arg->extension(), isolate);
+  } else {
+    // For JSContextExtensionObjects, the initializer can be run multiple times
+    // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
+    // first assignment should go through. For JSGlobalObjects, additionally any
+    // code can run in between that modifies the declared property.
+    DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
 
+    LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+    if (!maybe.has_value) return isolate->heap()->exception();
+    PropertyAttributes old_attributes = maybe.value;
 
-static Handle<JSWeakCollection> WeakCollectionInitialize(
-    Isolate* isolate, Handle<JSWeakCollection> weak_collection) {
-  DCHECK(weak_collection->map()->inobject_properties() == 0);
-  Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
-  weak_collection->set_table(*table);
-  return weak_collection;
-}
+    // Ignore if we can't reconfigure the value.
+    if ((old_attributes & DONT_DELETE) != 0) {
+      if ((old_attributes & READ_ONLY) != 0 ||
+          it.state() == LookupIterator::ACCESSOR) {
+        return *value;
+      }
+      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
+    }
+  }
 
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                   Handle<JSObject>::cast(holder), name, value, attr));
 
-RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  return *WeakCollectionInitialize(isolate, weak_collection);
+  return *value;
 }
 
 
-RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
+RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
-  Handle<ObjectHashTable> table(
-      ObjectHashTable::cast(weak_collection->table()));
-  RUNTIME_ASSERT(table->IsKey(*key));
-  Handle<Object> lookup(table->Lookup(key), isolate);
-  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_SMI_ARG_CHECKED(properties, 1);
+  // Conservative upper limit to prevent fuzz tests from going OOM.
+  RUNTIME_ASSERT(properties <= 100000);
+  if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
+    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
+  }
+  return *object;
 }
 
 
-RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
+RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
-  Handle<ObjectHashTable> table(
-      ObjectHashTable::cast(weak_collection->table()));
-  RUNTIME_ASSERT(table->IsKey(*key));
-  Handle<Object> lookup(table->Lookup(key), isolate);
-  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
+  Object* length = prototype->length();
+  RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
+  RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
+  // This is necessary to enable fast checks for absence of elements
+  // on Array.prototype and below.
+  prototype->set_elements(isolate->heap()->empty_fixed_array());
+  return Smi::FromInt(0);
 }
 
 
-RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
-  Handle<ObjectHashTable> table(
-      ObjectHashTable::cast(weak_collection->table()));
-  RUNTIME_ASSERT(table->IsKey(*key));
-  bool was_present = false;
-  Handle<ObjectHashTable> new_table =
-      ObjectHashTable::Remove(table, key, &was_present);
-  weak_collection->set_table(*new_table);
-  return isolate->heap()->ToBoolean(was_present);
+static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder,
+                           const char* name, Builtins::Name builtin_name) {
+  Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
+  Handle<Code> code(isolate->builtins()->builtin(builtin_name));
+  Handle<JSFunction> optimized =
+      isolate->factory()->NewFunctionWithoutPrototype(key, code);
+  optimized->shared()->DontAdaptArguments();
+  JSObject::AddProperty(holder, key, optimized, NONE);
 }
 
 
-RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
+RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  Handle<ObjectHashTable> table(
-      ObjectHashTable::cast(weak_collection->table()));
-  RUNTIME_ASSERT(table->IsKey(*key));
-  Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
-  weak_collection->set_table(*new_table);
-  return *weak_collection;
+  DCHECK(args.length() == 0);
+  Handle<JSObject> holder =
+      isolate->factory()->NewJSObject(isolate->object_function());
+
+  InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
+  InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
+  InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
+  InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
+  InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
+  InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
+  InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
+
+  return *holder;
 }
 
 
-RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
-  HandleScope scope(isolate);
+RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
+  SealHandleScope shs(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
-  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
-  Handle<FixedArray> values =
-      isolate->factory()->NewFixedArray(table->NumberOfElements());
-  {
-    DisallowHeapAllocation no_gc;
-    int number_of_non_hole_elements = 0;
-    for (int i = 0; i < table->Capacity(); i++) {
-      Handle<Object> key(table->KeyAt(i), isolate);
-      if (table->IsKey(*key)) {
-        values->set(number_of_non_hole_elements++, *key);
-      }
-    }
-    DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements);
+  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
+  if (!callable->IsJSFunction()) {
+    HandleScope scope(isolate);
+    Handle<Object> delegate;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, delegate, Execution::TryGetFunctionDelegate(
+                               isolate, Handle<JSReceiver>(callable)));
+    callable = JSFunction::cast(*delegate);
   }
-  return *isolate->factory()->NewJSArrayWithElements(values);
+  JSFunction* function = JSFunction::cast(callable);
+  SharedFunctionInfo* shared = function->shared();
+  return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
 }
 
 
-RUNTIME_FUNCTION(Runtime_GetPrototype) {
-  HandleScope scope(isolate);
+RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
+  SealHandleScope shs(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
-  // We don't expect access checks to be needed on JSProxy objects.
-  DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
-  PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
-  do {
-    if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
-        !isolate->MayNamedAccess(
-            Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
-            isolate->factory()->proto_string(), v8::ACCESS_GET)) {
-      isolate->ReportFailedAccessCheck(
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
-          v8::ACCESS_GET);
-      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-      return isolate->heap()->undefined_value();
-    }
-    iter.AdvanceIgnoringProxies();
-    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
-      return *PrototypeIterator::GetCurrent(iter);
-    }
-  } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
-  return *PrototypeIterator::GetCurrent(iter);
-}
+  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
 
+  if (!callable->IsJSFunction()) {
+    HandleScope scope(isolate);
+    Handle<Object> delegate;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, delegate, Execution::TryGetFunctionDelegate(
+                               isolate, Handle<JSReceiver>(callable)));
+    callable = JSFunction::cast(*delegate);
+  }
+  JSFunction* function = JSFunction::cast(callable);
 
-static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
-    Isolate* isolate, Handle<Object> receiver) {
-  PrototypeIterator iter(isolate, receiver);
-  while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
-    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
-      return PrototypeIterator::GetCurrent(iter);
-    }
-    iter.Advance();
+  SharedFunctionInfo* shared = function->shared();
+  if (shared->native() || shared->strict_mode() == STRICT) {
+    return isolate->heap()->undefined_value();
   }
-  return PrototypeIterator::GetCurrent(iter);
+  // Returns undefined for strict or native functions, or
+  // the associated global receiver for "normal" functions.
+
+  return function->global_proxy();
 }
 
 
-RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
-  DCHECK(!obj->IsAccessCheckNeeded());
-  DCHECK(!obj->map()->is_observed());
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::SetPrototype(obj, prototype, false));
-  return *result;
+RUNTIME_FUNCTION(Runtime_FunctionGetName) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return f->shared()->name();
 }
 
 
-RUNTIME_FUNCTION(Runtime_SetPrototype) {
-  HandleScope scope(isolate);
+RUNTIME_FUNCTION(Runtime_FunctionSetName) {
+  SealHandleScope shs(isolate);
   DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
-  if (obj->IsAccessCheckNeeded() &&
-      !isolate->MayNamedAccess(obj, isolate->factory()->proto_string(),
-                               v8::ACCESS_SET)) {
-    isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
-    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-    return isolate->heap()->undefined_value();
-  }
-  if (obj->map()->is_observed()) {
-    Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
-    Handle<Object> result;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result, JSObject::SetPrototype(obj, prototype, true));
 
-    Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
-    if (!new_value->SameValue(*old_value)) {
-      JSObject::EnqueueChangeRecord(
-          obj, "setPrototype", isolate->factory()->proto_string(), old_value);
-    }
-    return *result;
-  }
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::SetPrototype(obj, prototype, true));
-  return *result;
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  CONVERT_ARG_CHECKED(String, name, 1);
+  f->shared()->set_name(name);
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
-  HandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
-  CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
-  PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
-  while (true) {
-    iter.AdvanceIgnoringProxies();
-    if (iter.IsAtEnd()) return isolate->heap()->false_value();
-    if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
-  }
+RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(
+      f->shared()->name_should_print_as_anonymous());
 }
 
 
-// Enumerator used as indices into the array returned from GetOwnProperty
-enum PropertyDescriptorIndices {
-  IS_ACCESSOR_INDEX,
-  VALUE_INDEX,
-  GETTER_INDEX,
-  SETTER_INDEX,
-  WRITABLE_INDEX,
-  ENUMERABLE_INDEX,
-  CONFIGURABLE_INDEX,
-  DESCRIPTOR_SIZE
-};
+RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  f->shared()->set_name_should_print_as_anonymous(true);
+  return isolate->heap()->undefined_value();
+}
 
 
-MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
-                                                          Handle<JSObject> obj,
-                                                          Handle<Name> name) {
-  Heap* heap = isolate->heap();
-  Factory* factory = isolate->factory();
+RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->shared()->is_generator());
+}
 
-  PropertyAttributes attrs;
-  uint32_t index = 0;
-  Handle<Object> value;
-  MaybeHandle<AccessorPair> maybe_accessors;
-  // TODO(verwaest): Unify once indexed properties can be handled by the
-  // LookupIterator.
-  if (name->AsArrayIndex(&index)) {
-    // Get attributes.
-    Maybe<PropertyAttributes> maybe =
-        JSReceiver::GetOwnElementAttribute(obj, index);
-    if (!maybe.has_value) return MaybeHandle<Object>();
-    attrs = maybe.value;
-    if (attrs == ABSENT) return factory->undefined_value();
 
-    // Get AccessorPair if present.
-    maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
+RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->shared()->is_arrow());
+}
 
-    // Get value if not an AccessorPair.
-    if (maybe_accessors.is_null()) {
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, value, Runtime::GetElementOrCharAt(isolate, obj, index),
-          Object);
-    }
-  } else {
-    // Get attributes.
-    LookupIterator it(obj, name, LookupIterator::HIDDEN);
-    Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
-    if (!maybe.has_value) return MaybeHandle<Object>();
-    attrs = maybe.value;
-    if (attrs == ABSENT) return factory->undefined_value();
 
-    // Get AccessorPair if present.
-    if (it.state() == LookupIterator::ACCESSOR &&
-        it.GetAccessors()->IsAccessorPair()) {
-      maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
-    }
+RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->shared()->is_concise_method());
+}
 
-    // Get value if not an AccessorPair.
-    if (maybe_accessors.is_null()) {
-      ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it),
-                                 Object);
-    }
-  }
-  DCHECK(!isolate->has_pending_exception());
-  Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
-  elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
-  elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
-  elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null()));
 
-  Handle<AccessorPair> accessors;
-  if (maybe_accessors.ToHandle(&accessors)) {
-    Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
-    Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
-    elms->set(GETTER_INDEX, *getter);
-    elms->set(SETTER_INDEX, *setter);
-  } else {
-    elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
-    elms->set(VALUE_INDEX, *value);
-  }
+RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
 
-  return factory->NewJSArrayWithElements(elms);
-}
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  RUNTIME_ASSERT(f->RemovePrototype());
 
-
-// Returns an array with the property description:
-//  if args[1] is not a property on args[0]
-//          returns undefined
-//  if args[1] is a data property on args[0]
-//         [false, value, Writeable, Enumerable, Configurable]
-//  if args[1] is an accessor on args[0]
-//         [true, GetFunction, SetFunction, Enumerable, Configurable]
-RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
-                                     GetOwnProperty(isolate, obj, name));
-  return *result;
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_PreventExtensions) {
+RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
-                                     JSObject::PreventExtensions(obj));
-  return *result;
+
+  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+  Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
+  if (!script->IsScript()) return isolate->heap()->undefined_value();
+
+  return *Script::GetWrapper(Handle<Script>::cast(script));
 }
 
 
-RUNTIME_FUNCTION(Runtime_ToMethod) {
+RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
-  Handle<JSFunction> clone = JSFunction::CloneClosure(fun);
-  Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
-  JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol,
-                                           home_object, DONT_ENUM).Assert();
-  return *clone;
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
+  Handle<SharedFunctionInfo> shared(f->shared());
+  return *shared->GetSourceCode();
 }
 
 
-RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
-  DCHECK(args.length() == 0);
-  return isolate->heap()->home_object_symbol();
+RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+  int pos = fun->shared()->start_position();
+  return Smi::FromInt(pos);
 }
 
 
-RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
+RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
 
-  if (home_object->IsAccessCheckNeeded() &&
-      !isolate->MayNamedAccess(home_object, name, v8::ACCESS_GET)) {
-    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
-    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-  }
+  CONVERT_ARG_CHECKED(Code, code, 0);
+  CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
 
-  PrototypeIterator iter(isolate, home_object);
-  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
-  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
+  RUNTIME_ASSERT(0 <= offset && offset < code->Size());
 
-  LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
-  return *result;
+  Address pc = code->address() + offset;
+  return Smi::FromInt(code->SourcePosition(pc));
 }
 
 
-static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
-                            Handle<Object> receiver, Handle<Name> name,
-                            Handle<Object> value, StrictMode strict_mode) {
-  if (home_object->IsAccessCheckNeeded() &&
-      !isolate->MayNamedAccess(home_object, name, v8::ACCESS_SET)) {
-    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_SET);
-    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-  }
-
-  PrototypeIterator iter(isolate, home_object);
-  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
-  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
+RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
 
-  LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Object::SetProperty(&it, value, strict_mode,
-                          Object::CERTAINLY_NOT_STORE_FROM_KEYED,
-                          Object::SUPER_PROPERTY));
-  return *result;
+  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+  CONVERT_ARG_CHECKED(String, name, 1);
+  fun->SetInstanceClassName(name);
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 3);
+RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
 
-  return StoreToSuper(isolate, home_object, receiver, name, value, STRICT);
+  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+  CONVERT_SMI_ARG_CHECKED(length, 1);
+  RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
+                 (length & 0xC0000000) == 0x0);
+  fun->shared()->set_length(length);
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) {
+RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 3);
+  DCHECK(args.length() == 2);
 
-  return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+  RUNTIME_ASSERT(fun->should_have_prototype());
+  Accessors::FunctionSetPrototype(fun, value);
+  return args[0];  // return TOS
 }
 
 
-RUNTIME_FUNCTION(Runtime_IsExtensible) {
+RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
   SealHandleScope shs(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSObject, obj, 0);
-  if (obj->IsJSGlobalProxy()) {
-    PrototypeIterator iter(isolate, obj);
-    if (iter.IsAtEnd()) return isolate->heap()->false_value();
-    DCHECK(iter.GetCurrent()->IsJSGlobalObject());
-    obj = JSObject::cast(iter.GetCurrent());
-  }
-  return isolate->heap()->ToBoolean(obj->map()->is_extensible());
-}
-
 
-RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
-  return *isolate->factory()->CreateApiFunction(data, prototype);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
 }
 
 
-RUNTIME_FUNCTION(Runtime_IsTemplate) {
+RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
   SealHandleScope shs(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
-  bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
-  return isolate->heap()->ToBoolean(result);
+
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->IsBuiltin());
 }
 
 
-RUNTIME_FUNCTION(Runtime_GetTemplateField) {
-  SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_SetCode) {
+  HandleScope scope(isolate);
   DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(HeapObject, templ, 0);
-  CONVERT_SMI_ARG_CHECKED(index, 1);
-  int offset = index * kPointerSize + HeapObject::kHeaderSize;
-  InstanceType type = templ->map()->instance_type();
-  RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
-                 type == OBJECT_TEMPLATE_INFO_TYPE);
-  RUNTIME_ASSERT(offset > 0);
-  if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
-    RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
-  } else {
-    RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
+
+  Handle<SharedFunctionInfo> target_shared(target->shared());
+  Handle<SharedFunctionInfo> source_shared(source->shared());
+  RUNTIME_ASSERT(!source_shared->bound());
+
+  if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
+    return isolate->heap()->exception();
   }
-  return *HeapObject::RawField(templ, offset);
-}
 
+  // Mark both, the source and the target, as un-flushable because the
+  // shared unoptimized code makes them impossible to enqueue in a list.
+  DCHECK(target_shared->code()->gc_metadata() == NULL);
+  DCHECK(source_shared->code()->gc_metadata() == NULL);
+  target_shared->set_dont_flush(true);
+  source_shared->set_dont_flush(true);
 
-RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
-  Handle<Map> old_map(object->map());
-  bool needs_access_checks = old_map->is_access_check_needed();
-  if (needs_access_checks) {
-    // Copy map so it won't interfere constructor's initial map.
-    Handle<Map> new_map = Map::Copy(old_map);
-    new_map->set_is_access_check_needed(false);
-    JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
+  // Set the code, scope info, formal parameter count, and the length
+  // of the target shared function info.
+  target_shared->ReplaceCode(source_shared->code());
+  target_shared->set_scope_info(source_shared->scope_info());
+  target_shared->set_length(source_shared->length());
+  target_shared->set_feedback_vector(source_shared->feedback_vector());
+  target_shared->set_formal_parameter_count(
+      source_shared->formal_parameter_count());
+  target_shared->set_script(source_shared->script());
+  target_shared->set_start_position_and_type(
+      source_shared->start_position_and_type());
+  target_shared->set_end_position(source_shared->end_position());
+  bool was_native = target_shared->native();
+  target_shared->set_compiler_hints(source_shared->compiler_hints());
+  target_shared->set_native(was_native);
+  target_shared->set_profiler_ticks(source_shared->profiler_ticks());
+
+  // Set the code of the target function.
+  target->ReplaceCode(source_shared->code());
+  DCHECK(target->next_function_link()->IsUndefined());
+
+  // Make sure we get a fresh copy of the literal vector to avoid cross
+  // context contamination.
+  Handle<Context> context(source->context());
+  int number_of_literals = source->NumberOfLiterals();
+  Handle<FixedArray> literals =
+      isolate->factory()->NewFixedArray(number_of_literals, TENURED);
+  if (number_of_literals > 0) {
+    literals->set(JSFunction::kLiteralNativeContextIndex,
+                  context->native_context());
   }
-  return isolate->heap()->ToBoolean(needs_access_checks);
+  target->set_context(*context);
+  target->set_literals(*literals);
+
+  if (isolate->logger()->is_logging_code_events() ||
+      isolate->cpu_profiler()->is_profiling()) {
+    isolate->logger()->LogExistingFunction(source_shared,
+                                           Handle<Code>(source_shared->code()));
+  }
+
+  return *target;
 }
 
 
-RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
+RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  Handle<Map> old_map(object->map());
-  RUNTIME_ASSERT(!old_map->is_access_check_needed());
-  // Copy map so it won't interfere constructor's initial map.
-  Handle<Map> new_map = Map::Copy(old_map);
-  new_map->set_is_access_check_needed(true);
-  JSObject::MigrateToMap(object, new_map);
-  return isolate->heap()->undefined_value();
-}
+  DCHECK(args.length() == 0);
 
+  JavaScriptFrameIterator it(isolate);
+  JavaScriptFrame* frame = it.frame();
+  Handle<JSFunction> function(frame->function());
+  RUNTIME_ASSERT(function->shared()->is_generator());
 
-static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
-  HandleScope scope(isolate);
-  Handle<Object> args[1] = {name};
-  THROW_NEW_ERROR_RETURN_FAILURE(
-      isolate, NewTypeError("var_redeclaration", HandleVector(args, 1)));
+  Handle<JSGeneratorObject> generator;
+  if (frame->IsConstructor()) {
+    generator = handle(JSGeneratorObject::cast(frame->receiver()));
+  } else {
+    generator = isolate->factory()->NewJSGeneratorObject(function);
+  }
+  generator->set_function(*function);
+  generator->set_context(Context::cast(frame->context()));
+  generator->set_receiver(frame->receiver());
+  generator->set_continuation(0);
+  generator->set_operand_stack(isolate->heap()->empty_fixed_array());
+  generator->set_stack_handler_index(-1);
+
+  return *generator;
 }
 
 
-// May throw a RedeclarationError.
-static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
-                              Handle<String> name, Handle<Object> value,
-                              PropertyAttributes attr, bool is_var,
-                              bool is_const, bool is_function) {
-  // Do the lookup own properties only, see ES5 erratum.
-  LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
-  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-  if (!maybe.has_value) return isolate->heap()->exception();
+RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
 
-  if (it.IsFound()) {
-    PropertyAttributes old_attributes = maybe.value;
-    // The name was declared before; check for conflicting re-declarations.
-    if (is_const) return ThrowRedeclarationError(isolate, name);
+  JavaScriptFrameIterator stack_iterator(isolate);
+  JavaScriptFrame* frame = stack_iterator.frame();
+  RUNTIME_ASSERT(frame->function()->shared()->is_generator());
+  DCHECK_EQ(frame->function(), generator_object->function());
 
-    // Skip var re-declarations.
-    if (is_var) return isolate->heap()->undefined_value();
+  // The caller should have saved the context and continuation already.
+  DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
+  DCHECK_LT(0, generator_object->continuation());
 
-    DCHECK(is_function);
-    if ((old_attributes & DONT_DELETE) != 0) {
-      // Only allow reconfiguring globals to functions in user code (no
-      // natives, which are marked as read-only).
-      DCHECK((attr & READ_ONLY) == 0);
+  // We expect there to be at least two values on the operand stack: the return
+  // value of the yield expression, and the argument to this runtime call.
+  // Neither of those should be saved.
+  int operands_count = frame->ComputeOperandsCount();
+  DCHECK_GE(operands_count, 2);
+  operands_count -= 2;
 
-      // Check whether we can reconfigure the existing property into a
-      // function.
-      PropertyDetails old_details = it.property_details();
-      // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo,
-      // which are actually data properties, not accessor properties.
-      if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
-          old_details.type() == CALLBACKS) {
-        return ThrowRedeclarationError(isolate, name);
-      }
-      // If the existing property is not configurable, keep its attributes. Do
-      attr = old_attributes;
-    }
+  if (operands_count == 0) {
+    // Although it's semantically harmless to call this function with an
+    // operands_count of zero, it is also unnecessary.
+    DCHECK_EQ(generator_object->operand_stack(),
+              isolate->heap()->empty_fixed_array());
+    DCHECK_EQ(generator_object->stack_handler_index(), -1);
+    // If there are no operands on the stack, there shouldn't be a handler
+    // active either.
+    DCHECK(!frame->HasHandler());
+  } else {
+    int stack_handler_index = -1;
+    Handle<FixedArray> operand_stack =
+        isolate->factory()->NewFixedArray(operands_count);
+    frame->SaveOperandStack(*operand_stack, &stack_handler_index);
+    generator_object->set_operand_stack(*operand_stack);
+    generator_object->set_stack_handler_index(stack_handler_index);
   }
 
-  // Define or redefine own property.
-  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
-                                           global, name, value, attr));
-
   return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
-  HandleScope scope(isolate);
+// Note that this function is the slow path for resuming generators.  It is only
+// called if the suspended activation had operands on the stack, stack handlers
+// needing rewinding, or if the resume should throw an exception.  The fast path
+// is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
+// inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
+// called in any case, as it needs to reconstruct the stack frame and make space
+// for arguments and operands.
+RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
+  SealHandleScope shs(isolate);
   DCHECK(args.length() == 3);
-  Handle<GlobalObject> global(isolate->global_object());
-
-  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
-  CONVERT_SMI_ARG_CHECKED(flags, 2);
+  CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
+  CONVERT_ARG_CHECKED(Object, value, 1);
+  CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
+  JavaScriptFrameIterator stack_iterator(isolate);
+  JavaScriptFrame* frame = stack_iterator.frame();
 
-  // Traverse the name/value pairs and set the properties.
-  int length = pairs->length();
-  for (int i = 0; i < length; i += 2) {
-    HandleScope scope(isolate);
-    Handle<String> name(String::cast(pairs->get(i)));
-    Handle<Object> initial_value(pairs->get(i + 1), isolate);
+  DCHECK_EQ(frame->function(), generator_object->function());
+  DCHECK(frame->function()->is_compiled());
 
-    // We have to declare a global const property. To capture we only
-    // assign to it when evaluating the assignment for "const x =
-    // <expr>" the initial value is the hole.
-    bool is_var = initial_value->IsUndefined();
-    bool is_const = initial_value->IsTheHole();
-    bool is_function = initial_value->IsSharedFunctionInfo();
-    DCHECK(is_var + is_const + is_function == 1);
+  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
+  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
 
-    Handle<Object> value;
-    if (is_function) {
-      // Copy the function and update its context. Use it as value.
-      Handle<SharedFunctionInfo> shared =
-          Handle<SharedFunctionInfo>::cast(initial_value);
-      Handle<JSFunction> function =
-          isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
-                                                                TENURED);
-      value = function;
-    } else {
-      value = isolate->factory()->undefined_value();
-    }
+  Address pc = generator_object->function()->code()->instruction_start();
+  int offset = generator_object->continuation();
+  DCHECK(offset > 0);
+  frame->set_pc(pc + offset);
+  if (FLAG_enable_ool_constant_pool) {
+    frame->set_constant_pool(
+        generator_object->function()->code()->constant_pool());
+  }
+  generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
 
-    // Compute the property attributes. According to ECMA-262,
-    // the property must be non-configurable except in eval.
-    bool is_native = DeclareGlobalsNativeFlag::decode(flags);
-    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
-    int attr = NONE;
-    if (is_const) attr |= READ_ONLY;
-    if (is_function && is_native) attr |= READ_ONLY;
-    if (!is_const && !is_eval) attr |= DONT_DELETE;
+  FixedArray* operand_stack = generator_object->operand_stack();
+  int operands_count = operand_stack->length();
+  if (operands_count != 0) {
+    frame->RestoreOperandStack(operand_stack,
+                               generator_object->stack_handler_index());
+    generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
+    generator_object->set_stack_handler_index(-1);
+  }
 
-    Object* result = DeclareGlobals(isolate, global, name, value,
-                                    static_cast<PropertyAttributes>(attr),
-                                    is_var, is_const, is_function);
-    if (isolate->has_pending_exception()) return result;
+  JSGeneratorObject::ResumeMode resume_mode =
+      static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
+  switch (resume_mode) {
+    case JSGeneratorObject::NEXT:
+      return value;
+    case JSGeneratorObject::THROW:
+      return isolate->Throw(value);
   }
 
-  return isolate->heap()->undefined_value();
+  UNREACHABLE();
+  return isolate->ThrowIllegalOperation();
 }
 
 
-RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
+RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) {
   HandleScope scope(isolate);
-  // args[0] == name
-  // args[1] == language_mode
-  // args[2] == value (optional)
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+  int continuation = generator->continuation();
+  const char* message = continuation == JSGeneratorObject::kGeneratorClosed
+                            ? "generator_finished"
+                            : "generator_running";
+  Vector<Handle<Object> > argv = HandleVector<Object>(NULL, 0);
+  THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv));
+}
 
-  // Determine if we need to assign to the variable if it already
-  // exists (based on the number of arguments).
-  RUNTIME_ASSERT(args.length() == 3);
 
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
-  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+  // %ObjectFreeze is a fast path and these cases are handled elsewhere.
+  RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
+                 !object->map()->is_observed() && !object->IsJSProxy());
 
-  Handle<GlobalObject> global(isolate->context()->global_object());
   Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, Object::SetProperty(global, name, value, strict_mode));
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
   return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
-  HandleScope handle_scope(isolate);
-  // All constants are declared with an initial value. The name
-  // of the constant is the first argument and the initial value
-  // is the second.
-  RUNTIME_ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+// Returns a single character string where first character equals
+// string->Get(index).
+static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
+  if (index < static_cast<uint32_t>(string->length())) {
+    Factory* factory = string->GetIsolate()->factory();
+    return factory->LookupSingleCharacterStringFromCode(
+        String::Flatten(string)->Get(index));
+  }
+  return Execution::CharAt(string, index);
+}
 
-  Handle<GlobalObject> global = isolate->global_object();
 
-  // Lookup the property as own on the global object.
-  LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
-  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-  DCHECK(maybe.has_value);
-  PropertyAttributes old_attributes = maybe.value;
+MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
+                                                Handle<Object> object,
+                                                uint32_t index) {
+  // Handle [] indexing on Strings
+  if (object->IsString()) {
+    Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
+    if (!result->IsUndefined()) return result;
+  }
 
-  PropertyAttributes attr =
-      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
-  // Set the value if the property is either missing, or the property attributes
-  // allow setting the value without invoking an accessor.
-  if (it.IsFound()) {
-    // Ignore if we can't reconfigure the value.
-    if ((old_attributes & DONT_DELETE) != 0) {
-      if ((old_attributes & READ_ONLY) != 0 ||
-          it.state() == LookupIterator::ACCESSOR) {
-        return *value;
-      }
-      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
-    }
+  // Handle [] indexing on String objects
+  if (object->IsStringObjectWithCharacterAt(index)) {
+    Handle<JSValue> js_value = Handle<JSValue>::cast(object);
+    Handle<Object> result =
+        GetCharAt(Handle<String>(String::cast(js_value->value())), index);
+    if (!result->IsUndefined()) return result;
   }
 
-  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
-                                           global, name, value, attr));
-
-  return *value;
+  Handle<Object> result;
+  if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
+    PrototypeIterator iter(isolate, object);
+    return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter),
+                              index);
+  } else {
+    return Object::GetElement(isolate, object, index);
+  }
 }
 
 
-RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-
-  // Declarations are always made in a function, native, or global context. In
-  // the case of eval code, the context passed is the context of the caller,
-  // which may be some nested context and not the declaration context.
-  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
-  Handle<Context> context(context_arg->declaration_context());
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
-  CONVERT_SMI_ARG_CHECKED(attr_arg, 2);
-  PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg);
-  RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE);
-  CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
-
-  // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
-  bool is_var = *initial_value == NULL;
-  bool is_const = initial_value->IsTheHole();
-  bool is_function = initial_value->IsJSFunction();
-  DCHECK(is_var + is_const + is_function == 1);
-
-  int index;
-  PropertyAttributes attributes;
-  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
-  BindingFlags binding_flags;
-  Handle<Object> holder =
-      context->Lookup(name, flags, &index, &attributes, &binding_flags);
-
-  Handle<JSObject> object;
-  Handle<Object> value =
-      is_function ? initial_value
-                  : Handle<Object>::cast(isolate->factory()->undefined_value());
-
-  // TODO(verwaest): This case should probably not be covered by this function,
-  // but by DeclareGlobals instead.
-  if ((attributes != ABSENT && holder->IsJSGlobalObject()) ||
-      (context_arg->has_extension() &&
-       context_arg->extension()->IsJSGlobalObject())) {
-    return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
-                          value, attr, is_var, is_const, is_function);
+MUST_USE_RESULT
+static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
+  if (key->IsName()) {
+    return Handle<Name>::cast(key);
+  } else {
+    Handle<Object> converted;
+    ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
+                               Execution::ToString(isolate, key), Name);
+    return Handle<Name>::cast(converted);
   }
+}
 
-  if (attributes != ABSENT) {
-    // The name was declared before; check for conflicting re-declarations.
-    if (is_const || (attributes & READ_ONLY) != 0) {
-      return ThrowRedeclarationError(isolate, name);
-    }
-
-    // Skip var re-declarations.
-    if (is_var) return isolate->heap()->undefined_value();
-
-    DCHECK(is_function);
-    if (index >= 0) {
-      DCHECK(holder.is_identical_to(context));
-      context->set(index, *initial_value);
-      return isolate->heap()->undefined_value();
-    }
-
-    object = Handle<JSObject>::cast(holder);
 
-  } else if (context->has_extension()) {
-    object = handle(JSObject::cast(context->extension()));
-    DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
+MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
+                                               Handle<JSReceiver> object,
+                                               Handle<Object> key) {
+  Maybe<bool> maybe;
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    maybe = JSReceiver::HasElement(object, index);
   } else {
-    DCHECK(context->IsFunctionContext());
-    object =
-        isolate->factory()->NewJSObject(isolate->context_extension_function());
-    context->set_extension(*object);
-  }
+    // Convert the key to a name - possibly by calling back into JavaScript.
+    Handle<Name> name;
+    ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
 
-  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
-                                           object, name, value, attr));
+    maybe = JSReceiver::HasProperty(object, name);
+  }
 
-  return isolate->heap()->undefined_value();
+  if (!maybe.has_value) return MaybeHandle<Object>();
+  return isolate->factory()->ToBoolean(maybe.value);
 }
 
 
-RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
-  DCHECK(!value->IsTheHole());
-  // Initializations are always done in a function or native context.
-  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
-  Handle<Context> context(context_arg->declaration_context());
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
-
-  int index;
-  PropertyAttributes attributes;
-  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
-  BindingFlags binding_flags;
-  Handle<Object> holder =
-      context->Lookup(name, flags, &index, &attributes, &binding_flags);
-
-  if (index >= 0) {
-    DCHECK(holder->IsContext());
-    // Property was found in a context.  Perform the assignment if the constant
-    // was uninitialized.
-    Handle<Context> context = Handle<Context>::cast(holder);
-    DCHECK((attributes & READ_ONLY) != 0);
-    if (context->get(index)->IsTheHole()) context->set(index, *value);
-    return *value;
+MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
+                                               Handle<Object> object,
+                                               Handle<Object> key) {
+  if (object->IsUndefined() || object->IsNull()) {
+    Handle<Object> args[2] = {key, object};
+    THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load",
+                                          HandleVector(args, 2)),
+                    Object);
   }
 
-  PropertyAttributes attr =
-      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    return GetElementOrCharAt(isolate, object, index);
+  }
 
-  // Strict mode handling not needed (legacy const is disallowed in strict
-  // mode).
+  // Convert the key to a name - possibly by calling back into JavaScript.
+  Handle<Name> name;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
 
-  // The declared const was configurable, and may have been deleted in the
-  // meanwhile. If so, re-introduce the variable in the context extension.
-  DCHECK(context_arg->has_extension());
-  if (attributes == ABSENT) {
-    holder = handle(context_arg->extension(), isolate);
+  // Check if the name is trivially convertible to an index and get
+  // the element if so.
+  if (name->AsArrayIndex(&index)) {
+    return GetElementOrCharAt(isolate, object, index);
   } else {
-    // For JSContextExtensionObjects, the initializer can be run multiple times
-    // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
-    // first assignment should go through. For JSGlobalObjects, additionally any
-    // code can run in between that modifies the declared property.
-    DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
-
-    LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
-    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-    if (!maybe.has_value) return isolate->heap()->exception();
-    PropertyAttributes old_attributes = maybe.value;
-
-    // Ignore if we can't reconfigure the value.
-    if ((old_attributes & DONT_DELETE) != 0) {
-      if ((old_attributes & READ_ONLY) != 0 ||
-          it.state() == LookupIterator::ACCESSOR) {
-        return *value;
-      }
-      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
-    }
+    return Object::GetProperty(object, name);
   }
-
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate, JSObject::SetOwnPropertyIgnoreAttributes(
-                   Handle<JSObject>::cast(holder), name, value, attr));
-
-  return *value;
 }
 
 
-RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
+RUNTIME_FUNCTION(Runtime_GetProperty) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_SMI_ARG_CHECKED(properties, 1);
-  // Conservative upper limit to prevent fuzz tests from going OOM.
-  RUNTIME_ASSERT(properties <= 100000);
-  if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
-    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
-  }
-  return *object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
-  Object* length = prototype->length();
-  RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
-  RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
-  // This is necessary to enable fast checks for absence of elements
-  // on Array.prototype and below.
-  prototype->set_elements(isolate->heap()->empty_fixed_array());
-  return Smi::FromInt(0);
-}
-
 
-static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder,
-                           const char* name, Builtins::Name builtin_name) {
-  Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
-  Handle<Code> code(isolate->builtins()->builtin(builtin_name));
-  Handle<JSFunction> optimized =
-      isolate->factory()->NewFunctionWithoutPrototype(key, code);
-  optimized->shared()->DontAdaptArguments();
-  JSObject::AddProperty(holder, key, optimized, NONE);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, Runtime::GetObjectProperty(isolate, object, key));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
+// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
+RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  Handle<JSObject> holder =
-      isolate->factory()->NewJSObject(isolate->object_function());
+  DCHECK(args.length() == 2);
 
-  InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
-  InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
-  InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
-  InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
-  InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
-  InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
-  InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
-
-  return *holder;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
-  if (!callable->IsJSFunction()) {
-    HandleScope scope(isolate);
-    Handle<Object> delegate;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, delegate, Execution::TryGetFunctionDelegate(
-                               isolate, Handle<JSReceiver>(callable)));
-    callable = JSFunction::cast(*delegate);
-  }
-  JSFunction* function = JSFunction::cast(callable);
-  SharedFunctionInfo* shared = function->shared();
-  return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
-
-  if (!callable->IsJSFunction()) {
-    HandleScope scope(isolate);
-    Handle<Object> delegate;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, delegate, Execution::TryGetFunctionDelegate(
-                               isolate, Handle<JSReceiver>(callable)));
-    callable = JSFunction::cast(*delegate);
-  }
-  JSFunction* function = JSFunction::cast(callable);
-
-  SharedFunctionInfo* shared = function->shared();
-  if (shared->native() || shared->strict_mode() == STRICT) {
-    return isolate->heap()->undefined_value();
-  }
-  // Returns undefined for strict or native functions, or
-  // the associated global receiver for "normal" functions.
-
-  return function->global_proxy();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetName) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return f->shared()->name();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionSetName) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  CONVERT_ARG_CHECKED(String, name, 1);
-  f->shared()->set_name(name);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(
-      f->shared()->name_should_print_as_anonymous());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  f->shared()->set_name_should_print_as_anonymous(true);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->shared()->is_generator());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->shared()->is_arrow());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->shared()->is_concise_method());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  RUNTIME_ASSERT(f->RemovePrototype());
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
-  Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
-  if (!script->IsScript()) return isolate->heap()->undefined_value();
-
-  return *Script::GetWrapper(Handle<Script>::cast(script));
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
-  Handle<SharedFunctionInfo> shared(f->shared());
-  return *shared->GetSourceCode();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
-  int pos = fun->shared()->start_position();
-  return Smi::FromInt(pos);
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_CHECKED(Code, code, 0);
-  CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
-
-  RUNTIME_ASSERT(0 <= offset && offset < code->Size());
-
-  Address pc = code->address() + offset;
-  return Smi::FromInt(code->SourcePosition(pc));
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
-  CONVERT_ARG_CHECKED(String, name, 1);
-  fun->SetInstanceClassName(name);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
-  CONVERT_SMI_ARG_CHECKED(length, 1);
-  RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
-                 (length & 0xC0000000) == 0x0);
-  fun->shared()->set_length(length);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-  RUNTIME_ASSERT(fun->should_have_prototype());
-  Accessors::FunctionSetPrototype(fun, value);
-  return args[0];  // return TOS
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->IsBuiltin());
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetCode) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
-
-  Handle<SharedFunctionInfo> target_shared(target->shared());
-  Handle<SharedFunctionInfo> source_shared(source->shared());
-  RUNTIME_ASSERT(!source_shared->bound());
-
-  if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
-    return isolate->heap()->exception();
-  }
-
-  // Mark both, the source and the target, as un-flushable because the
-  // shared unoptimized code makes them impossible to enqueue in a list.
-  DCHECK(target_shared->code()->gc_metadata() == NULL);
-  DCHECK(source_shared->code()->gc_metadata() == NULL);
-  target_shared->set_dont_flush(true);
-  source_shared->set_dont_flush(true);
-
-  // Set the code, scope info, formal parameter count, and the length
-  // of the target shared function info.
-  target_shared->ReplaceCode(source_shared->code());
-  target_shared->set_scope_info(source_shared->scope_info());
-  target_shared->set_length(source_shared->length());
-  target_shared->set_feedback_vector(source_shared->feedback_vector());
-  target_shared->set_formal_parameter_count(
-      source_shared->formal_parameter_count());
-  target_shared->set_script(source_shared->script());
-  target_shared->set_start_position_and_type(
-      source_shared->start_position_and_type());
-  target_shared->set_end_position(source_shared->end_position());
-  bool was_native = target_shared->native();
-  target_shared->set_compiler_hints(source_shared->compiler_hints());
-  target_shared->set_native(was_native);
-  target_shared->set_profiler_ticks(source_shared->profiler_ticks());
-
-  // Set the code of the target function.
-  target->ReplaceCode(source_shared->code());
-  DCHECK(target->next_function_link()->IsUndefined());
-
-  // Make sure we get a fresh copy of the literal vector to avoid cross
-  // context contamination.
-  Handle<Context> context(source->context());
-  int number_of_literals = source->NumberOfLiterals();
-  Handle<FixedArray> literals =
-      isolate->factory()->NewFixedArray(number_of_literals, TENURED);
-  if (number_of_literals > 0) {
-    literals->set(JSFunction::kLiteralNativeContextIndex,
-                  context->native_context());
-  }
-  target->set_context(*context);
-  target->set_literals(*literals);
-
-  if (isolate->logger()->is_logging_code_events() ||
-      isolate->cpu_profiler()->is_profiling()) {
-    isolate->logger()->LogExistingFunction(source_shared,
-                                           Handle<Code>(source_shared->code()));
-  }
-
-  return *target;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-
-  JavaScriptFrameIterator it(isolate);
-  JavaScriptFrame* frame = it.frame();
-  Handle<JSFunction> function(frame->function());
-  RUNTIME_ASSERT(function->shared()->is_generator());
-
-  Handle<JSGeneratorObject> generator;
-  if (frame->IsConstructor()) {
-    generator = handle(JSGeneratorObject::cast(frame->receiver()));
-  } else {
-    generator = isolate->factory()->NewJSGeneratorObject(function);
-  }
-  generator->set_function(*function);
-  generator->set_context(Context::cast(frame->context()));
-  generator->set_receiver(frame->receiver());
-  generator->set_continuation(0);
-  generator->set_operand_stack(isolate->heap()->empty_fixed_array());
-  generator->set_stack_handler_index(-1);
-
-  return *generator;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
-
-  JavaScriptFrameIterator stack_iterator(isolate);
-  JavaScriptFrame* frame = stack_iterator.frame();
-  RUNTIME_ASSERT(frame->function()->shared()->is_generator());
-  DCHECK_EQ(frame->function(), generator_object->function());
-
-  // The caller should have saved the context and continuation already.
-  DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
-  DCHECK_LT(0, generator_object->continuation());
-
-  // We expect there to be at least two values on the operand stack: the return
-  // value of the yield expression, and the argument to this runtime call.
-  // Neither of those should be saved.
-  int operands_count = frame->ComputeOperandsCount();
-  DCHECK_GE(operands_count, 2);
-  operands_count -= 2;
-
-  if (operands_count == 0) {
-    // Although it's semantically harmless to call this function with an
-    // operands_count of zero, it is also unnecessary.
-    DCHECK_EQ(generator_object->operand_stack(),
-              isolate->heap()->empty_fixed_array());
-    DCHECK_EQ(generator_object->stack_handler_index(), -1);
-    // If there are no operands on the stack, there shouldn't be a handler
-    // active either.
-    DCHECK(!frame->HasHandler());
-  } else {
-    int stack_handler_index = -1;
-    Handle<FixedArray> operand_stack =
-        isolate->factory()->NewFixedArray(operands_count);
-    frame->SaveOperandStack(*operand_stack, &stack_handler_index);
-    generator_object->set_operand_stack(*operand_stack);
-    generator_object->set_stack_handler_index(stack_handler_index);
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-// Note that this function is the slow path for resuming generators.  It is only
-// called if the suspended activation had operands on the stack, stack handlers
-// needing rewinding, or if the resume should throw an exception.  The fast path
-// is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
-// inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
-// called in any case, as it needs to reconstruct the stack frame and make space
-// for arguments and operands.
-RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
-  CONVERT_ARG_CHECKED(Object, value, 1);
-  CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
-  JavaScriptFrameIterator stack_iterator(isolate);
-  JavaScriptFrame* frame = stack_iterator.frame();
-
-  DCHECK_EQ(frame->function(), generator_object->function());
-  DCHECK(frame->function()->is_compiled());
-
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-
-  Address pc = generator_object->function()->code()->instruction_start();
-  int offset = generator_object->continuation();
-  DCHECK(offset > 0);
-  frame->set_pc(pc + offset);
-  if (FLAG_enable_ool_constant_pool) {
-    frame->set_constant_pool(
-        generator_object->function()->code()->constant_pool());
-  }
-  generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
-
-  FixedArray* operand_stack = generator_object->operand_stack();
-  int operands_count = operand_stack->length();
-  if (operands_count != 0) {
-    frame->RestoreOperandStack(operand_stack,
-                               generator_object->stack_handler_index());
-    generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
-    generator_object->set_stack_handler_index(-1);
-  }
-
-  JSGeneratorObject::ResumeMode resume_mode =
-      static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
-  switch (resume_mode) {
-    case JSGeneratorObject::NEXT:
-      return value;
-    case JSGeneratorObject::THROW:
-      return isolate->Throw(value);
-  }
-
-  UNREACHABLE();
-  return isolate->ThrowIllegalOperation();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
-  int continuation = generator->continuation();
-  const char* message = continuation == JSGeneratorObject::kGeneratorClosed
-                            ? "generator_finished"
-                            : "generator_running";
-  Vector<Handle<Object> > argv = HandleVector<Object>(NULL, 0);
-  THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv));
-}
-
-
-RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-
-  // %ObjectFreeze is a fast path and these cases are handled elsewhere.
-  RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
-                 !object->map()->is_observed() && !object->IsJSProxy());
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_SMI_ARG_CHECKED(radix, 1);
-  RUNTIME_ASSERT(2 <= radix && radix <= 36);
-
-  // Fast case where the result is a one character string.
-  if (args[0]->IsSmi()) {
-    int value = args.smi_at(0);
-    if (value >= 0 && value < radix) {
-      // Character array used for conversion.
-      static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-      return *isolate->factory()->LookupSingleCharacterStringFromCode(
-          kCharTable[value]);
-    }
-  }
-
-  // Slow case.
-  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
-  if (std::isnan(value)) {
-    return isolate->heap()->nan_string();
-  }
-  if (std::isinf(value)) {
-    if (value < 0) {
-      return isolate->heap()->minus_infinity_string();
-    }
-    return isolate->heap()->infinity_string();
-  }
-  char* str = DoubleToRadixCString(value, radix);
-  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
-  DeleteArray(str);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToFixed) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
-  int f = FastD2IChecked(f_number);
-  // See DoubleToFixedCString for these constants:
-  RUNTIME_ASSERT(f >= 0 && f <= 20);
-  RUNTIME_ASSERT(!Double(value).IsSpecial());
-  char* str = DoubleToFixedCString(value, f);
-  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
-  DeleteArray(str);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToExponential) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
-  int f = FastD2IChecked(f_number);
-  RUNTIME_ASSERT(f >= -1 && f <= 20);
-  RUNTIME_ASSERT(!Double(value).IsSpecial());
-  char* str = DoubleToExponentialCString(value, f);
-  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
-  DeleteArray(str);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
-  int f = FastD2IChecked(f_number);
-  RUNTIME_ASSERT(f >= 1 && f <= 21);
-  RUNTIME_ASSERT(!Double(value).IsSpecial());
-  char* str = DoubleToPrecisionCString(value, f);
-  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
-  DeleteArray(str);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsValidSmi) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
-  return isolate->heap()->ToBoolean(Smi::IsValid(number));
-}
-
-
-// Returns a single character string where first character equals
-// string->Get(index).
-static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
-  if (index < static_cast<uint32_t>(string->length())) {
-    Factory* factory = string->GetIsolate()->factory();
-    return factory->LookupSingleCharacterStringFromCode(
-        String::Flatten(string)->Get(index));
-  }
-  return Execution::CharAt(string, index);
-}
-
-
-MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
-                                                Handle<Object> object,
-                                                uint32_t index) {
-  // Handle [] indexing on Strings
-  if (object->IsString()) {
-    Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
-    if (!result->IsUndefined()) return result;
-  }
-
-  // Handle [] indexing on String objects
-  if (object->IsStringObjectWithCharacterAt(index)) {
-    Handle<JSValue> js_value = Handle<JSValue>::cast(object);
-    Handle<Object> result =
-        GetCharAt(Handle<String>(String::cast(js_value->value())), index);
-    if (!result->IsUndefined()) return result;
-  }
-
-  Handle<Object> result;
-  if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
-    PrototypeIterator iter(isolate, object);
-    return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter),
-                              index);
-  } else {
-    return Object::GetElement(isolate, object, index);
-  }
-}
-
-
-MUST_USE_RESULT
-static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
-  if (key->IsName()) {
-    return Handle<Name>::cast(key);
-  } else {
-    Handle<Object> converted;
-    ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
-                               Execution::ToString(isolate, key), Name);
-    return Handle<Name>::cast(converted);
-  }
-}
-
-
-MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
-                                               Handle<JSReceiver> object,
-                                               Handle<Object> key) {
-  Maybe<bool> maybe;
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    maybe = JSReceiver::HasElement(object, index);
-  } else {
-    // Convert the key to a name - possibly by calling back into JavaScript.
-    Handle<Name> name;
-    ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
-
-    maybe = JSReceiver::HasProperty(object, name);
-  }
-
-  if (!maybe.has_value) return MaybeHandle<Object>();
-  return isolate->factory()->ToBoolean(maybe.value);
-}
-
-
-MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
-                                               Handle<Object> object,
-                                               Handle<Object> key) {
-  if (object->IsUndefined() || object->IsNull()) {
-    Handle<Object> args[2] = {key, object};
-    THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load",
-                                          HandleVector(args, 2)),
-                    Object);
-  }
-
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    return GetElementOrCharAt(isolate, object, index);
-  }
-
-  // Convert the key to a name - possibly by calling back into JavaScript.
-  Handle<Name> name;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
-
-  // Check if the name is trivially convertible to an index and get
-  // the element if so.
-  if (name->AsArrayIndex(&index)) {
-    return GetElementOrCharAt(isolate, object, index);
-  } else {
-    return Object::GetProperty(object, name);
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, Runtime::GetObjectProperty(isolate, object, key));
-  return *result;
-}
-
-
-// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
-RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
-
-  // Fast cases for getting named properties of the receiver JSObject
-  // itself.
-  //
-  // The global proxy objects has to be excluded since LookupOwn on
-  // the global proxy object can return a valid result even though the
-  // global proxy object never has properties.  This is the case
-  // because the global proxy object forwards everything to its hidden
-  // prototype including own lookups.
-  //
-  // Additionally, we need to make sure that we do not cache results
-  // for objects that require access checks.
-  if (receiver_obj->IsJSObject()) {
-    if (!receiver_obj->IsJSGlobalProxy() &&
-        !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
-      DisallowHeapAllocation no_allocation;
-      Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
-      Handle<Name> key = Handle<Name>::cast(key_obj);
-      if (receiver->HasFastProperties()) {
-        // Attempt to use lookup cache.
-        Handle<Map> receiver_map(receiver->map(), isolate);
-        KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
-        int index = keyed_lookup_cache->Lookup(receiver_map, key);
-        if (index != -1) {
-          // Doubles are not cached, so raw read the value.
-          return receiver->RawFastPropertyAt(
-              FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
-        }
-        // Lookup cache miss.  Perform lookup and update the cache if
-        // appropriate.
-        LookupIterator it(receiver, key, LookupIterator::OWN);
-        if (it.state() == LookupIterator::DATA &&
-            it.property_details().type() == FIELD) {
-          FieldIndex field_index = it.GetFieldIndex();
-          // Do not track double fields in the keyed lookup cache. Reading
-          // double values requires boxing.
-          if (!it.representation().IsDouble()) {
-            keyed_lookup_cache->Update(receiver_map, key,
-                                       field_index.GetKeyedLookupCacheIndex());
-          }
-          AllowHeapAllocation allow_allocation;
-          return *JSObject::FastPropertyAt(receiver, it.representation(),
-                                           field_index);
-        }
-      } else {
-        // Attempt dictionary lookup.
-        NameDictionary* dictionary = receiver->property_dictionary();
-        int entry = dictionary->FindEntry(key);
-        if ((entry != NameDictionary::kNotFound) &&
-            (dictionary->DetailsAt(entry).type() == NORMAL)) {
-          Object* value = dictionary->ValueAt(entry);
-          if (!receiver->IsGlobalObject()) return value;
-          value = PropertyCell::cast(value)->value();
-          if (!value->IsTheHole()) return value;
-          // If value is the hole (meaning, absent) do the general lookup.
-        }
-      }
-    } else if (key_obj->IsSmi()) {
-      // JSObject without a name key. If the key is a Smi, check for a
-      // definite out-of-bounds access to elements, which is a strong indicator
-      // that subsequent accesses will also call the runtime. Proactively
-      // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
-      // doubles for those future calls in the case that the elements would
-      // become FAST_DOUBLE_ELEMENTS.
-      Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
-      ElementsKind elements_kind = js_object->GetElementsKind();
-      if (IsFastDoubleElementsKind(elements_kind)) {
-        Handle<Smi> key = Handle<Smi>::cast(key_obj);
-        if (key->value() >= js_object->elements()->length()) {
-          if (IsFastHoleyElementsKind(elements_kind)) {
-            elements_kind = FAST_HOLEY_ELEMENTS;
-          } else {
-            elements_kind = FAST_ELEMENTS;
-          }
-          RETURN_FAILURE_ON_EXCEPTION(
-              isolate, TransitionElements(js_object, elements_kind, isolate));
-        }
-      } else {
-        DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
-               !IsFastElementsKind(elements_kind));
-      }
-    }
-  } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
-    // Fast case for string indexing using [] with a smi index.
-    Handle<String> str = Handle<String>::cast(receiver_obj);
-    int index = args.smi_at(1);
-    if (index >= 0 && index < str->length()) {
-      return *GetCharAt(str, index);
-    }
-  }
-
-  // Fall back to GetObjectProperty.
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
-  return *result;
-}
-
-
-static bool IsValidAccessor(Handle<Object> obj) {
-  return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
-}
-
-
-// Transform getter or setter into something DefineAccessor can handle.
-static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
-                                                   Handle<Object> component) {
-  if (component->IsUndefined()) return isolate->factory()->undefined_value();
-  Handle<FunctionTemplateInfo> info =
-      Handle<FunctionTemplateInfo>::cast(component);
-  return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
-}
-
-
-RUNTIME_FUNCTION(Runtime_DefineApiAccessorProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
-  CONVERT_SMI_ARG_CHECKED(attribute, 4);
-  RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
-  RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
-  RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
-      static_cast<PropertyAttributes>(attribute)));
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate, JSObject::DefineAccessor(
-                   object, name, InstantiateAccessorComponent(isolate, getter),
-                   InstantiateAccessorComponent(isolate, setter),
-                   static_cast<PropertyAttributes>(attribute)));
-  return isolate->heap()->undefined_value();
-}
-
-
-// Implements part of 8.12.9 DefineOwnProperty.
-// There are 3 cases that lead here:
-// Step 4b - define a new accessor property.
-// Steps 9c & 12 - replace an existing data property with an accessor property.
-// Step 12 - update an existing accessor property with an accessor or generic
-//           descriptor.
-RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  RUNTIME_ASSERT(!obj->IsNull());
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
-  RUNTIME_ASSERT(IsValidAccessor(getter));
-  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
-  RUNTIME_ASSERT(IsValidAccessor(setter));
-  CONVERT_SMI_ARG_CHECKED(unchecked, 4);
-  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
-
-  bool fast = obj->HasFastProperties();
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
-  if (fast) JSObject::MigrateSlowToFast(obj, 0);
-  return isolate->heap()->undefined_value();
-}
-
-
-// Implements part of 8.12.9 DefineOwnProperty.
-// There are 3 cases that lead here:
-// Step 4a - define a new data property.
-// Steps 9b & 12 - replace an existing accessor property with a data property.
-// Step 12 - update an existing data property with a data or generic
-//           descriptor.
-RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
-  CONVERT_SMI_ARG_CHECKED(unchecked, 3);
-  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
-
-  LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
-  if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
-    if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
-      return isolate->heap()->undefined_value();
-    }
-    it.Next();
-  }
-
-  // Take special care when attributes are different and there is already
-  // a property.
-  if (it.state() == LookupIterator::ACCESSOR) {
-    // Use IgnoreAttributes version since a readonly property may be
-    // overridden and SetProperty does not allow this.
-    Handle<Object> result;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result,
-        JSObject::SetOwnPropertyIgnoreAttributes(
-            js_object, name, obj_value, attr, JSObject::DONT_FORCE_FIELD));
-    return *result;
-  }
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::DefineObjectProperty(js_object, name, obj_value, attr));
-  return *result;
-}
-
-
-// Return property without being observable by accessors or interceptors.
-RUNTIME_FUNCTION(Runtime_GetDataProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-  return *JSObject::GetDataProperty(object, key);
-}
-
-
-MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
-                                               Handle<Object> object,
-                                               Handle<Object> key,
-                                               Handle<Object> value,
-                                               StrictMode strict_mode) {
-  if (object->IsUndefined() || object->IsNull()) {
-    Handle<Object> args[2] = {key, object};
-    THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store",
-                                          HandleVector(args, 2)),
-                    Object);
-  }
-
-  if (object->IsJSProxy()) {
-    Handle<Object> name_object;
-    if (key->IsSymbol()) {
-      name_object = key;
-    } else {
-      ASSIGN_RETURN_ON_EXCEPTION(isolate, name_object,
-                                 Execution::ToString(isolate, key), Object);
-    }
-    Handle<Name> name = Handle<Name>::cast(name_object);
-    return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
-                               strict_mode);
-  }
-
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    // TODO(verwaest): Support non-JSObject receivers.
-    if (!object->IsJSObject()) return value;
-    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-
-    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
-    // of a string using [] notation.  We need to support this too in
-    // JavaScript.
-    // In the case of a String object we just need to redirect the assignment to
-    // the underlying string if the index is in range.  Since the underlying
-    // string does nothing with the assignment then we can ignore such
-    // assignments.
-    if (js_object->IsStringObjectWithCharacterAt(index)) {
-      return value;
-    }
-
-    JSObject::ValidateElements(js_object);
-    if (js_object->HasExternalArrayElements() ||
-        js_object->HasFixedTypedArrayElements()) {
-      if (!value->IsNumber() && !value->IsUndefined()) {
-        ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
-                                   Execution::ToNumber(isolate, value), Object);
-      }
-    }
-
-    MaybeHandle<Object> result = JSObject::SetElement(
-        js_object, index, value, NONE, strict_mode, true, SET_PROPERTY);
-    JSObject::ValidateElements(js_object);
-
-    return result.is_null() ? result : value;
-  }
-
-  if (key->IsName()) {
-    Handle<Name> name = Handle<Name>::cast(key);
-    if (name->AsArrayIndex(&index)) {
-      // TODO(verwaest): Support non-JSObject receivers.
-      if (!object->IsJSObject()) return value;
-      Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-      if (js_object->HasExternalArrayElements()) {
-        if (!value->IsNumber() && !value->IsUndefined()) {
-          ASSIGN_RETURN_ON_EXCEPTION(
-              isolate, value, Execution::ToNumber(isolate, value), Object);
-        }
-      }
-      return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
-                                  true, SET_PROPERTY);
-    } else {
-      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-      return Object::SetProperty(object, name, value, strict_mode);
-    }
-  }
-
-  // Call-back into JavaScript to convert the key to a string.
-  Handle<Object> converted;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
-                             Execution::ToString(isolate, key), Object);
-  Handle<String> name = Handle<String>::cast(converted);
-
-  if (name->AsArrayIndex(&index)) {
-    // TODO(verwaest): Support non-JSObject receivers.
-    if (!object->IsJSObject()) return value;
-    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-    return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
-                                true, SET_PROPERTY);
-  }
-  return Object::SetProperty(object, name, value, strict_mode);
-}
-
-
-MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
-                                                  Handle<Object> key,
-                                                  Handle<Object> value,
-                                                  PropertyAttributes attr) {
-  Isolate* isolate = js_object->GetIsolate();
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
-    // of a string using [] notation.  We need to support this too in
-    // JavaScript.
-    // In the case of a String object we just need to redirect the assignment to
-    // the underlying string if the index is in range.  Since the underlying
-    // string does nothing with the assignment then we can ignore such
-    // assignments.
-    if (js_object->IsStringObjectWithCharacterAt(index)) {
-      return value;
-    }
-
-    return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
-                                DEFINE_PROPERTY);
-  }
-
-  if (key->IsName()) {
-    Handle<Name> name = Handle<Name>::cast(key);
-    if (name->AsArrayIndex(&index)) {
-      return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
-                                  DEFINE_PROPERTY);
-    } else {
-      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-      return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
-                                                      attr);
-    }
-  }
-
-  // Call-back into JavaScript to convert the key to a string.
-  Handle<Object> converted;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
-                             Execution::ToString(isolate, key), Object);
-  Handle<String> name = Handle<String>::cast(converted);
-
-  if (name->AsArrayIndex(&index)) {
-    return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
-                                DEFINE_PROPERTY);
-  } else {
-    return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
-                                                    attr);
-  }
-}
-
-
-MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
-                                                  Handle<JSReceiver> receiver,
-                                                  Handle<Object> key,
-                                                  JSReceiver::DeleteMode mode) {
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    // In Firefox/SpiderMonkey, Safari and Opera you can access the
-    // characters of a string using [] notation.  In the case of a
-    // String object we just need to redirect the deletion to the
-    // underlying string if the index is in range.  Since the
-    // underlying string does nothing with the deletion, we can ignore
-    // such deletions.
-    if (receiver->IsStringObjectWithCharacterAt(index)) {
-      return isolate->factory()->true_value();
-    }
-
-    return JSReceiver::DeleteElement(receiver, index, mode);
-  }
-
-  Handle<Name> name;
-  if (key->IsName()) {
-    name = Handle<Name>::cast(key);
-  } else {
-    // Call-back into JavaScript to convert the key to a string.
-    Handle<Object> converted;
-    ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
-                               Execution::ToString(isolate, key), Object);
-    name = Handle<String>::cast(converted);
-  }
-
-  if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-  return JSReceiver::DeleteProperty(receiver, name, mode);
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  RUNTIME_ASSERT(key->IsUniqueName());
-  return *JSObject::SetHiddenProperty(object, key, value);
-}
-
-
-RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
-  RUNTIME_ASSERT(
-      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  // Compute attributes.
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(unchecked_attributes);
-
-#ifdef DEBUG
-  uint32_t index = 0;
-  DCHECK(!key->ToArrayIndex(&index));
-  LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
-  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  RUNTIME_ASSERT(!it.IsFound());
-#endif
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
-  RUNTIME_ASSERT(
-      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  // Compute attributes.
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(unchecked_attributes);
-
-#ifdef DEBUG
-  bool duplicate;
-  if (key->IsName()) {
-    LookupIterator it(object, Handle<Name>::cast(key),
-                      LookupIterator::OWN_SKIP_INTERCEPTOR);
-    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-    DCHECK(maybe.has_value);
-    duplicate = it.IsFound();
-  } else {
-    uint32_t index = 0;
-    RUNTIME_ASSERT(key->ToArrayIndex(&index));
-    Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
-    if (!maybe.has_value) return isolate->heap()->exception();
-    duplicate = maybe.value;
-  }
-  if (duplicate) {
-    Handle<Object> args[1] = {key};
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate,
-        NewTypeError("duplicate_template_property", HandleVector(args, 1)));
-  }
-#endif
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::DefineObjectProperty(object, key, value, attributes));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetProperty) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 3);
-  StrictMode strict_mode = strict_mode_arg;
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::SetObjectProperty(isolate, object, key, value, strict_mode));
-  return *result;
-}
-
-
-// Adds an element to an array.
-// This is used to create an indexed data property into an array.
-RUNTIME_FUNCTION(Runtime_AddElement) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
-  RUNTIME_ASSERT(
-      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  // Compute attributes.
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(unchecked_attributes);
-
-  uint32_t index = 0;
-  key->ToArrayIndex(&index);
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::SetElement(object, index, value, attributes,
-                                            SLOPPY, false, DEFINE_PROPERTY));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
-  JSObject::TransitionElementsKind(array, map->elements_kind());
-  return *array;
-}
-
-
-// Set the native flag on the function.
-// This is used to decide if we should transform null and undefined
-// into the global object when doing call and apply.
-RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
-  SealHandleScope shs(isolate);
-  RUNTIME_ASSERT(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(Object, object, 0);
-
-  if (object->IsJSFunction()) {
-    JSFunction* func = JSFunction::cast(object);
-    func->shared()->set_native(true);
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
-  SealHandleScope shs(isolate);
-  RUNTIME_ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-
-  if (object->IsJSFunction()) {
-    JSFunction* func = JSFunction::cast(*object);
-    func->shared()->set_inline_builtin(true);
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_SMI_ARG_CHECKED(store_index, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
-  CONVERT_SMI_ARG_CHECKED(literal_index, 4);
-
-  Object* raw_literal_cell = literals->get(literal_index);
-  JSArray* boilerplate = NULL;
-  if (raw_literal_cell->IsAllocationSite()) {
-    AllocationSite* site = AllocationSite::cast(raw_literal_cell);
-    boilerplate = JSArray::cast(site->transition_info());
-  } else {
-    boilerplate = JSArray::cast(raw_literal_cell);
-  }
-  Handle<JSArray> boilerplate_object(boilerplate);
-  ElementsKind elements_kind = object->GetElementsKind();
-  DCHECK(IsFastElementsKind(elements_kind));
-  // Smis should never trigger transitions.
-  DCHECK(!value->IsSmi());
-
-  if (value->IsNumber()) {
-    DCHECK(IsFastSmiElementsKind(elements_kind));
-    ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
-                                         ? FAST_HOLEY_DOUBLE_ELEMENTS
-                                         : FAST_DOUBLE_ELEMENTS;
-    if (IsMoreGeneralElementsKindTransition(
-            boilerplate_object->GetElementsKind(), transitioned_kind)) {
-      JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
-    }
-    JSObject::TransitionElementsKind(object, transitioned_kind);
-    DCHECK(IsFastDoubleElementsKind(object->GetElementsKind()));
-    FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
-    HeapNumber* number = HeapNumber::cast(*value);
-    double_array->set(store_index, number->Number());
-  } else {
-    if (!IsFastObjectElementsKind(elements_kind)) {
-      ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
-                                           ? FAST_HOLEY_ELEMENTS
-                                           : FAST_ELEMENTS;
-      JSObject::TransitionElementsKind(object, transitioned_kind);
-      ElementsKind boilerplate_elements_kind =
-          boilerplate_object->GetElementsKind();
-      if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
-                                              transitioned_kind)) {
-        JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
-      }
-    }
-    FixedArray* object_array = FixedArray::cast(object->elements());
-    object_array->set(store_index, *value);
-  }
-  return *object;
-}
-
-
-// Check whether debugger and is about to step into the callback that is passed
-// to a built-in function such as Array.forEach.
-RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
-  DCHECK(args.length() == 1);
-  if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
-    return isolate->heap()->false_value();
-  }
-  CONVERT_ARG_CHECKED(Object, callback, 0);
-  // We do not step into the callback if it's a builtin or not even a function.
-  return isolate->heap()->ToBoolean(callback->IsJSFunction() &&
-                                    !JSFunction::cast(callback)->IsBuiltin());
-}
-
-
-// Set one shot breakpoints for the callback function that is passed to a
-// built-in function such as Array.forEach to enable stepping into the callback.
-RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
-  DCHECK(args.length() == 1);
-  Debug* debug = isolate->debug();
-  if (!debug->IsStepping()) return isolate->heap()->undefined_value();
-
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
-  Handle<JSFunction> fun;
-  if (object->IsJSFunction()) {
-    fun = Handle<JSFunction>::cast(object);
-  } else {
-    fun = Handle<JSFunction>(
-        Handle<JSGeneratorObject>::cast(object)->function(), isolate);
-  }
-  // When leaving the function, step out has been activated, but not performed
-  // if we do not leave the builtin.  To be able to step into the function
-  // again, we need to clear the step out at this point.
-  debug->ClearStepOut();
-  debug->FloodWithOneShot(fun);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
-  DCHECK(args.length() == 1);
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
-  isolate->PushPromise(promise);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
-  DCHECK(args.length() == 0);
-  SealHandleScope shs(isolate);
-  isolate->PopPromise();
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
-  DCHECK(args.length() == 1);
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
-  isolate->debug()->OnPromiseEvent(data);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) {
-  DCHECK(args.length() == 2);
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-  isolate->debug()->OnPromiseReject(promise, value);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
-  DCHECK(args.length() == 1);
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
-  isolate->debug()->OnAsyncTaskEvent(data);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeleteProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
-  JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
-                                           ? JSReceiver::STRICT_DELETION
-                                           : JSReceiver::NORMAL_DELETION;
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSReceiver::DeleteProperty(object, key, delete_mode));
-  return *result;
-}
-
-
-static Object* HasOwnPropertyImplementation(Isolate* isolate,
-                                            Handle<JSObject> object,
-                                            Handle<Name> key) {
-  Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  if (maybe.value) return isolate->heap()->true_value();
-  // Handle hidden prototypes.  If there's a hidden prototype above this thing
-  // then we have to check it for properties, because they are supposed to
-  // look like they are on this object.
-  PrototypeIterator iter(isolate, object);
-  if (!iter.IsAtEnd() &&
-      Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))
-          ->map()
-          ->is_hidden_prototype()) {
-    // TODO(verwaest): The recursion is not necessary for keys that are array
-    // indices. Removing this.
-    return HasOwnPropertyImplementation(
-        isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
-        key);
-  }
-  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-  return isolate->heap()->false_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-
-  uint32_t index;
-  const bool key_is_array_index = key->AsArrayIndex(&index);
-
-  // Only JS objects can have properties.
-  if (object->IsJSObject()) {
-    Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
-    // Fast case: either the key is a real named property or it is not
-    // an array index and there are no interceptors or hidden
-    // prototypes.
-    Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key);
-    if (!maybe.has_value) return isolate->heap()->exception();
-    DCHECK(!isolate->has_pending_exception());
-    if (maybe.value) {
-      return isolate->heap()->true_value();
-    }
-    Map* map = js_obj->map();
-    if (!key_is_array_index && !map->has_named_interceptor() &&
-        !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
-      return isolate->heap()->false_value();
-    }
-    // Slow case.
-    return HasOwnPropertyImplementation(isolate, Handle<JSObject>(js_obj),
-                                        Handle<Name>(key));
-  } else if (object->IsString() && key_is_array_index) {
-    // Well, there is one exception:  Handle [] on strings.
-    Handle<String> string = Handle<String>::cast(object);
-    if (index < static_cast<uint32_t>(string->length())) {
-      return isolate->heap()->true_value();
-    }
-  }
-  return isolate->heap()->false_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_HasProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-
-  Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  return isolate->heap()->ToBoolean(maybe.value);
-}
-
-
-RUNTIME_FUNCTION(Runtime_HasElement) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_SMI_ARG_CHECKED(index, 1);
-
-  Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  return isolate->heap()->ToBoolean(maybe.value);
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-
-  Maybe<PropertyAttributes> maybe =
-      JSReceiver::GetOwnPropertyAttributes(object, key);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
-  return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
-  Handle<JSArray> result;
-
-  isolate->counters()->for_in()->Increment();
-  Handle<FixedArray> elements;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, elements,
-      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
-  return *isolate->factory()->NewJSArrayWithElements(elements);
-}
-
-
-// Returns either a FixedArray as Runtime_GetPropertyNames,
-// or, if the given object has an enum cache that contains
-// all enumerable properties of the object and its prototypes
-// have none, the map of the object. This is used to speed up
-// the check for deletions during a for-in.
-RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
-
-  if (raw_object->IsSimpleEnum()) return raw_object->map();
-
-  HandleScope scope(isolate);
-  Handle<JSReceiver> object(raw_object);
-  Handle<FixedArray> content;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, content,
-      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
-
-  // Test again, since cache may have been built by preceding call.
-  if (object->IsSimpleEnum()) return object->map();
-
-  return *content;
-}
-
-
-// Find the length of the prototype chain that is to be handled as one. If a
-// prototype object is hidden it is to be viewed as part of the the object it
-// is prototype for.
-static int OwnPrototypeChainLength(JSObject* obj) {
-  int count = 1;
-  for (PrototypeIterator iter(obj->GetIsolate(), obj);
-       !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
-    count++;
-  }
-  return count;
-}
-
-
-// Return the names of the own named properties.
-// args[0]: object
-// args[1]: PropertyAttributes as int
-RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  if (!args[0]->IsJSObject()) {
-    return isolate->heap()->undefined_value();
-  }
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_SMI_ARG_CHECKED(filter_value, 1);
-  PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
-
-  // Skip the global proxy as it has no properties and always delegates to the
-  // real global object.
-  if (obj->IsJSGlobalProxy()) {
-    // Only collect names if access is permitted.
-    if (obj->IsAccessCheckNeeded() &&
-        !isolate->MayNamedAccess(obj, isolate->factory()->undefined_value(),
-                                 v8::ACCESS_KEYS)) {
-      isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
-      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-      return *isolate->factory()->NewJSArray(0);
-    }
-    PrototypeIterator iter(isolate, obj);
-    obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-  }
-
-  // Find the number of objects making up this.
-  int length = OwnPrototypeChainLength(*obj);
-
-  // Find the number of own properties for each of the objects.
-  ScopedVector<int> own_property_count(length);
-  int total_property_count = 0;
-  {
-    PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
-    for (int i = 0; i < length; i++) {
-      DCHECK(!iter.IsAtEnd());
-      Handle<JSObject> jsproto =
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-      // Only collect names if access is permitted.
-      if (jsproto->IsAccessCheckNeeded() &&
-          !isolate->MayNamedAccess(jsproto,
-                                   isolate->factory()->undefined_value(),
-                                   v8::ACCESS_KEYS)) {
-        isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
-        RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-        return *isolate->factory()->NewJSArray(0);
-      }
-      int n;
-      n = jsproto->NumberOfOwnProperties(filter);
-      own_property_count[i] = n;
-      total_property_count += n;
-      iter.Advance();
-    }
-  }
-
-  // Allocate an array with storage for all the property names.
-  Handle<FixedArray> names =
-      isolate->factory()->NewFixedArray(total_property_count);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
 
-  // Get the property names.
-  int next_copy_index = 0;
-  int hidden_strings = 0;
-  {
-    PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
-    for (int i = 0; i < length; i++) {
-      DCHECK(!iter.IsAtEnd());
-      Handle<JSObject> jsproto =
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-      jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
-      if (i > 0) {
-        // Names from hidden prototypes may already have been added
-        // for inherited function template instances. Count the duplicates
-        // and stub them out; the final copy pass at the end ignores holes.
-        for (int j = next_copy_index;
-             j < next_copy_index + own_property_count[i]; j++) {
-          Object* name_from_hidden_proto = names->get(j);
-          for (int k = 0; k < next_copy_index; k++) {
-            if (names->get(k) != isolate->heap()->hidden_string()) {
-              Object* name = names->get(k);
-              if (name_from_hidden_proto == name) {
-                names->set(j, isolate->heap()->hidden_string());
-                hidden_strings++;
-                break;
-              }
-            }
+  // Fast cases for getting named properties of the receiver JSObject
+  // itself.
+  //
+  // The global proxy objects has to be excluded since LookupOwn on
+  // the global proxy object can return a valid result even though the
+  // global proxy object never has properties.  This is the case
+  // because the global proxy object forwards everything to its hidden
+  // prototype including own lookups.
+  //
+  // Additionally, we need to make sure that we do not cache results
+  // for objects that require access checks.
+  if (receiver_obj->IsJSObject()) {
+    if (!receiver_obj->IsJSGlobalProxy() &&
+        !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
+      DisallowHeapAllocation no_allocation;
+      Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
+      Handle<Name> key = Handle<Name>::cast(key_obj);
+      if (receiver->HasFastProperties()) {
+        // Attempt to use lookup cache.
+        Handle<Map> receiver_map(receiver->map(), isolate);
+        KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
+        int index = keyed_lookup_cache->Lookup(receiver_map, key);
+        if (index != -1) {
+          // Doubles are not cached, so raw read the value.
+          return receiver->RawFastPropertyAt(
+              FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
+        }
+        // Lookup cache miss.  Perform lookup and update the cache if
+        // appropriate.
+        LookupIterator it(receiver, key, LookupIterator::OWN);
+        if (it.state() == LookupIterator::DATA &&
+            it.property_details().type() == FIELD) {
+          FieldIndex field_index = it.GetFieldIndex();
+          // Do not track double fields in the keyed lookup cache. Reading
+          // double values requires boxing.
+          if (!it.representation().IsDouble()) {
+            keyed_lookup_cache->Update(receiver_map, key,
+                                       field_index.GetKeyedLookupCacheIndex());
           }
+          AllowHeapAllocation allow_allocation;
+          return *JSObject::FastPropertyAt(receiver, it.representation(),
+                                           field_index);
+        }
+      } else {
+        // Attempt dictionary lookup.
+        NameDictionary* dictionary = receiver->property_dictionary();
+        int entry = dictionary->FindEntry(key);
+        if ((entry != NameDictionary::kNotFound) &&
+            (dictionary->DetailsAt(entry).type() == NORMAL)) {
+          Object* value = dictionary->ValueAt(entry);
+          if (!receiver->IsGlobalObject()) return value;
+          value = PropertyCell::cast(value)->value();
+          if (!value->IsTheHole()) return value;
+          // If value is the hole (meaning, absent) do the general lookup.
         }
       }
-      next_copy_index += own_property_count[i];
-
-      // Hidden properties only show up if the filter does not skip strings.
-      if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
-        hidden_strings++;
+    } else if (key_obj->IsSmi()) {
+      // JSObject without a name key. If the key is a Smi, check for a
+      // definite out-of-bounds access to elements, which is a strong indicator
+      // that subsequent accesses will also call the runtime. Proactively
+      // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
+      // doubles for those future calls in the case that the elements would
+      // become FAST_DOUBLE_ELEMENTS.
+      Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
+      ElementsKind elements_kind = js_object->GetElementsKind();
+      if (IsFastDoubleElementsKind(elements_kind)) {
+        Handle<Smi> key = Handle<Smi>::cast(key_obj);
+        if (key->value() >= js_object->elements()->length()) {
+          if (IsFastHoleyElementsKind(elements_kind)) {
+            elements_kind = FAST_HOLEY_ELEMENTS;
+          } else {
+            elements_kind = FAST_ELEMENTS;
+          }
+          RETURN_FAILURE_ON_EXCEPTION(
+              isolate, TransitionElements(js_object, elements_kind, isolate));
+        }
+      } else {
+        DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
+               !IsFastElementsKind(elements_kind));
       }
-      iter.Advance();
     }
-  }
-
-  // Filter out name of hidden properties object and
-  // hidden prototype duplicates.
-  if (hidden_strings > 0) {
-    Handle<FixedArray> old_names = names;
-    names = isolate->factory()->NewFixedArray(names->length() - hidden_strings);
-    int dest_pos = 0;
-    for (int i = 0; i < total_property_count; i++) {
-      Object* name = old_names->get(i);
-      if (name == isolate->heap()->hidden_string()) {
-        hidden_strings--;
-        continue;
-      }
-      names->set(dest_pos++, name);
+  } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
+    // Fast case for string indexing using [] with a smi index.
+    Handle<String> str = Handle<String>::cast(receiver_obj);
+    int index = args.smi_at(1);
+    if (index >= 0 && index < str->length()) {
+      return *GetCharAt(str, index);
     }
-    DCHECK_EQ(0, hidden_strings);
   }
 
-  return *isolate->factory()->NewJSArrayWithElements(names);
+  // Fall back to GetObjectProperty.
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
+  return *result;
 }
 
 
-// Return the names of the own indexed properties.
-// args[0]: object
-RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  if (!args[0]->IsJSObject()) {
-    return isolate->heap()->undefined_value();
-  }
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+static bool IsValidAccessor(Handle<Object> obj) {
+  return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
+}
 
-  int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
-  Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
-  obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
-  return *isolate->factory()->NewJSArrayWithElements(names);
+
+// Transform getter or setter into something DefineAccessor can handle.
+static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
+                                                   Handle<Object> component) {
+  if (component->IsUndefined()) return isolate->factory()->undefined_value();
+  Handle<FunctionTemplateInfo> info =
+      Handle<FunctionTemplateInfo>::cast(component);
+  return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
 }
 
 
-// Return information on whether an object has a named or indexed interceptor.
-// args[0]: object
-RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
+RUNTIME_FUNCTION(Runtime_DefineApiAccessorProperty) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  if (!args[0]->IsJSObject()) {
-    return Smi::FromInt(0);
-  }
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-
-  int result = 0;
-  if (obj->HasNamedInterceptor()) result |= 2;
-  if (obj->HasIndexedInterceptor()) result |= 1;
-
-  return Smi::FromInt(result);
+  DCHECK(args.length() == 5);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
+  CONVERT_SMI_ARG_CHECKED(attribute, 4);
+  RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
+  RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
+  RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
+      static_cast<PropertyAttributes>(attribute)));
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::DefineAccessor(
+                   object, name, InstantiateAccessorComponent(isolate, getter),
+                   InstantiateAccessorComponent(isolate, setter),
+                   static_cast<PropertyAttributes>(attribute)));
+  return isolate->heap()->undefined_value();
 }
 
 
-// Return property names from named interceptor.
-// args[0]: object
-RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
+// Implements part of 8.12.9 DefineOwnProperty.
+// There are 3 cases that lead here:
+// Step 4b - define a new accessor property.
+// Steps 9c & 12 - replace an existing data property with an accessor property.
+// Step 12 - update an existing accessor property with an accessor or generic
+//           descriptor.
+RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
+  DCHECK(args.length() == 5);
   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  RUNTIME_ASSERT(!obj->IsNull());
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
+  RUNTIME_ASSERT(IsValidAccessor(getter));
+  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
+  RUNTIME_ASSERT(IsValidAccessor(setter));
+  CONVERT_SMI_ARG_CHECKED(unchecked, 4);
+  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
 
-  if (obj->HasNamedInterceptor()) {
-    Handle<JSObject> result;
-    if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
-      return *result;
-    }
-  }
+  bool fast = obj->HasFastProperties();
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
+  if (fast) JSObject::MigrateSlowToFast(obj, 0);
   return isolate->heap()->undefined_value();
 }
 
 
-// Return element names from indexed interceptor.
-// args[0]: object
-RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
+// Implements part of 8.12.9 DefineOwnProperty.
+// There are 3 cases that lead here:
+// Step 4a - define a new data property.
+// Steps 9b & 12 - replace an existing accessor property with a data property.
+// Step 12 - update an existing data property with a data or generic
+//           descriptor.
+RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked, 3);
+  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
 
-  if (obj->HasIndexedInterceptor()) {
-    Handle<JSObject> result;
-    if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
-      return *result;
+  LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
+  if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
+    if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
+      return isolate->heap()->undefined_value();
     }
+    it.Next();
   }
-  return isolate->heap()->undefined_value();
+
+  // Take special care when attributes are different and there is already
+  // a property.
+  if (it.state() == LookupIterator::ACCESSOR) {
+    // Use IgnoreAttributes version since a readonly property may be
+    // overridden and SetProperty does not allow this.
+    Handle<Object> result;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result,
+        JSObject::SetOwnPropertyIgnoreAttributes(
+            js_object, name, obj_value, attr, JSObject::DONT_FORCE_FIELD));
+    return *result;
+  }
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::DefineObjectProperty(js_object, name, obj_value, attr));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_OwnKeys) {
+// Return property without being observable by accessors or interceptors.
+RUNTIME_FUNCTION(Runtime_GetDataProperty) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
-  Handle<JSObject> object(raw_object);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+  return *JSObject::GetDataProperty(object, key);
+}
 
-  if (object->IsJSGlobalProxy()) {
-    // Do access checks before going to the global object.
-    if (object->IsAccessCheckNeeded() &&
-        !isolate->MayNamedAccess(object, isolate->factory()->undefined_value(),
-                                 v8::ACCESS_KEYS)) {
-      isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
-      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-      return *isolate->factory()->NewJSArray(0);
-    }
 
-    PrototypeIterator iter(isolate, object);
-    // If proxy is detached we simply return an empty array.
-    if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0);
-    object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
+                                               Handle<Object> object,
+                                               Handle<Object> key,
+                                               Handle<Object> value,
+                                               StrictMode strict_mode) {
+  if (object->IsUndefined() || object->IsNull()) {
+    Handle<Object> args[2] = {key, object};
+    THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store",
+                                          HandleVector(args, 2)),
+                    Object);
   }
 
-  Handle<FixedArray> contents;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, contents, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
-
-  // Some fast paths through GetKeysInFixedArrayFor reuse a cached
-  // property array and since the result is mutable we have to create
-  // a fresh clone on each invocation.
-  int length = contents->length();
-  Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
-  for (int i = 0; i < length; i++) {
-    Object* entry = contents->get(i);
-    if (entry->IsString()) {
-      copy->set(i, entry);
+  if (object->IsJSProxy()) {
+    Handle<Object> name_object;
+    if (key->IsSymbol()) {
+      name_object = key;
     } else {
-      DCHECK(entry->IsNumber());
-      HandleScope scope(isolate);
-      Handle<Object> entry_handle(entry, isolate);
-      Handle<Object> entry_str =
-          isolate->factory()->NumberToString(entry_handle);
-      copy->set(i, *entry_str);
+      ASSIGN_RETURN_ON_EXCEPTION(isolate, name_object,
+                                 Execution::ToString(isolate, key), Object);
     }
+    Handle<Name> name = Handle<Name>::cast(name_object);
+    return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
+                               strict_mode);
   }
-  return *isolate->factory()->NewJSArrayWithElements(copy);
-}
 
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    // TODO(verwaest): Support non-JSObject receivers.
+    if (!object->IsJSObject()) return value;
+    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
 
-RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
-
-  // Compute the frame holding the arguments.
-  JavaScriptFrameIterator it(isolate);
-  it.AdvanceToArgumentsFrame();
-  JavaScriptFrame* frame = it.frame();
+    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
+    // of a string using [] notation.  We need to support this too in
+    // JavaScript.
+    // In the case of a String object we just need to redirect the assignment to
+    // the underlying string if the index is in range.  Since the underlying
+    // string does nothing with the assignment then we can ignore such
+    // assignments.
+    if (js_object->IsStringObjectWithCharacterAt(index)) {
+      return value;
+    }
 
-  // Get the actual number of provided arguments.
-  const uint32_t n = frame->ComputeParametersCount();
+    JSObject::ValidateElements(js_object);
+    if (js_object->HasExternalArrayElements() ||
+        js_object->HasFixedTypedArrayElements()) {
+      if (!value->IsNumber() && !value->IsUndefined()) {
+        ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
+                                   Execution::ToNumber(isolate, value), Object);
+      }
+    }
 
-  // Try to convert the key to an index. If successful and within
-  // index return the the argument from the frame.
-  uint32_t index;
-  if (raw_key->ToArrayIndex(&index) && index < n) {
-    return frame->GetParameter(index);
-  }
+    MaybeHandle<Object> result = JSObject::SetElement(
+        js_object, index, value, NONE, strict_mode, true, SET_PROPERTY);
+    JSObject::ValidateElements(js_object);
 
-  HandleScope scope(isolate);
-  if (raw_key->IsSymbol()) {
-    Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key);
-    if (symbol->Equals(isolate->native_context()->iterator_symbol())) {
-      return isolate->native_context()->array_values_iterator();
-    }
-    // Lookup in the initial Object.prototype object.
-    Handle<Object> result;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result,
-        Object::GetProperty(isolate->initial_object_prototype(),
-                            Handle<Symbol>::cast(raw_key)));
-    return *result;
+    return result.is_null() ? result : value;
   }
 
-  // Convert the key to a string.
-  Handle<Object> converted;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, converted,
-                                     Execution::ToString(isolate, raw_key));
-  Handle<String> key = Handle<String>::cast(converted);
-
-  // Try to convert the string key into an array index.
-  if (key->AsArrayIndex(&index)) {
-    if (index < n) {
-      return frame->GetParameter(index);
+  if (key->IsName()) {
+    Handle<Name> name = Handle<Name>::cast(key);
+    if (name->AsArrayIndex(&index)) {
+      // TODO(verwaest): Support non-JSObject receivers.
+      if (!object->IsJSObject()) return value;
+      Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+      if (js_object->HasExternalArrayElements()) {
+        if (!value->IsNumber() && !value->IsUndefined()) {
+          ASSIGN_RETURN_ON_EXCEPTION(
+              isolate, value, Execution::ToNumber(isolate, value), Object);
+        }
+      }
+      return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
+                                  true, SET_PROPERTY);
     } else {
-      Handle<Object> initial_prototype(isolate->initial_object_prototype());
-      Handle<Object> result;
-      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-          isolate, result,
-          Object::GetElement(isolate, initial_prototype, index));
-      return *result;
+      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
+      return Object::SetProperty(object, name, value, strict_mode);
     }
   }
 
-  // Handle special arguments properties.
-  if (String::Equals(isolate->factory()->length_string(), key)) {
-    return Smi::FromInt(n);
-  }
-  if (String::Equals(isolate->factory()->callee_string(), key)) {
-    JSFunction* function = frame->function();
-    if (function->shared()->strict_mode() == STRICT) {
-      THROW_NEW_ERROR_RETURN_FAILURE(
-          isolate, NewTypeError("strict_arguments_callee",
-                                HandleVector<Object>(NULL, 0)));
-    }
-    return function;
-  }
+  // Call-back into JavaScript to convert the key to a string.
+  Handle<Object> converted;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
+                             Execution::ToString(isolate, key), Object);
+  Handle<String> name = Handle<String>::cast(converted);
 
-  // Lookup in the initial Object.prototype object.
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Object::GetProperty(isolate->initial_object_prototype(), key));
-  return *result;
+  if (name->AsArrayIndex(&index)) {
+    // TODO(verwaest): Support non-JSObject receivers.
+    if (!object->IsJSObject()) return value;
+    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+    return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
+                                true, SET_PROPERTY);
+  }
+  return Object::SetProperty(object, name, value, strict_mode);
 }
 
 
-RUNTIME_FUNCTION(Runtime_ToFastProperties) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  if (object->IsJSObject() && !object->IsGlobalObject()) {
-    JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0);
+MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
+                                                  Handle<Object> key,
+                                                  Handle<Object> value,
+                                                  PropertyAttributes attr) {
+  Isolate* isolate = js_object->GetIsolate();
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
+    // of a string using [] notation.  We need to support this too in
+    // JavaScript.
+    // In the case of a String object we just need to redirect the assignment to
+    // the underlying string if the index is in range.  Since the underlying
+    // string does nothing with the assignment then we can ignore such
+    // assignments.
+    if (js_object->IsStringObjectWithCharacterAt(index)) {
+      return value;
+    }
+
+    return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
+                                DEFINE_PROPERTY);
   }
-  return *object;
-}
 
+  if (key->IsName()) {
+    Handle<Name> name = Handle<Name>::cast(key);
+    if (name->AsArrayIndex(&index)) {
+      return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
+                                  DEFINE_PROPERTY);
+    } else {
+      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
+      return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
+                                                      attr);
+    }
+  }
 
-RUNTIME_FUNCTION(Runtime_ToBool) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, object, 0);
+  // Call-back into JavaScript to convert the key to a string.
+  Handle<Object> converted;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
+                             Execution::ToString(isolate, key), Object);
+  Handle<String> name = Handle<String>::cast(converted);
 
-  return isolate->heap()->ToBoolean(object->BooleanValue());
+  if (name->AsArrayIndex(&index)) {
+    return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
+                                DEFINE_PROPERTY);
+  } else {
+    return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
+                                                    attr);
+  }
 }
 
 
-// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
-// Possible optimizations: put the type string into the oddballs.
-RUNTIME_FUNCTION(Runtime_Typeof) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (obj->IsNumber()) return isolate->heap()->number_string();
-  HeapObject* heap_obj = HeapObject::cast(obj);
-
-  // typeof an undetectable object is 'undefined'
-  if (heap_obj->map()->is_undetectable()) {
-    return isolate->heap()->undefined_string();
-  }
+MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
+                                                  Handle<JSReceiver> receiver,
+                                                  Handle<Object> key,
+                                                  JSReceiver::DeleteMode mode) {
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    // In Firefox/SpiderMonkey, Safari and Opera you can access the
+    // characters of a string using [] notation.  In the case of a
+    // String object we just need to redirect the deletion to the
+    // underlying string if the index is in range.  Since the
+    // underlying string does nothing with the deletion, we can ignore
+    // such deletions.
+    if (receiver->IsStringObjectWithCharacterAt(index)) {
+      return isolate->factory()->true_value();
+    }
 
-  InstanceType instance_type = heap_obj->map()->instance_type();
-  if (instance_type < FIRST_NONSTRING_TYPE) {
-    return isolate->heap()->string_string();
+    return JSReceiver::DeleteElement(receiver, index, mode);
   }
 
-  switch (instance_type) {
-    case ODDBALL_TYPE:
-      if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
-        return isolate->heap()->boolean_string();
-      }
-      if (heap_obj->IsNull()) {
-        return isolate->heap()->object_string();
-      }
-      DCHECK(heap_obj->IsUndefined());
-      return isolate->heap()->undefined_string();
-    case SYMBOL_TYPE:
-      return isolate->heap()->symbol_string();
-    case JS_FUNCTION_TYPE:
-    case JS_FUNCTION_PROXY_TYPE:
-      return isolate->heap()->function_string();
-    default:
-      // For any kind of object not handled above, the spec rule for
-      // host objects gives that it is okay to return "object"
-      return isolate->heap()->object_string();
+  Handle<Name> name;
+  if (key->IsName()) {
+    name = Handle<Name>::cast(key);
+  } else {
+    // Call-back into JavaScript to convert the key to a string.
+    Handle<Object> converted;
+    ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
+                               Execution::ToString(isolate, key), Object);
+    name = Handle<String>::cast(converted);
   }
-}
-
 
-RUNTIME_FUNCTION(Runtime_Booleanize) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(Object, value_raw, 0);
-  CONVERT_SMI_ARG_CHECKED(token_raw, 1);
-  intptr_t value = reinterpret_cast<intptr_t>(value_raw);
-  Token::Value token = static_cast<Token::Value>(token_raw);
-  switch (token) {
-    case Token::EQ:
-    case Token::EQ_STRICT:
-      return isolate->heap()->ToBoolean(value == 0);
-    case Token::NE:
-    case Token::NE_STRICT:
-      return isolate->heap()->ToBoolean(value != 0);
-    case Token::LT:
-      return isolate->heap()->ToBoolean(value < 0);
-    case Token::GT:
-      return isolate->heap()->ToBoolean(value > 0);
-    case Token::LTE:
-      return isolate->heap()->ToBoolean(value <= 0);
-    case Token::GTE:
-      return isolate->heap()->ToBoolean(value >= 0);
-    default:
-      // This should only happen during natives fuzzing.
-      return isolate->heap()->undefined_value();
-  }
+  if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
+  return JSReceiver::DeleteProperty(receiver, name, mode);
 }
 
 
-static bool AreDigits(const uint8_t* s, int from, int to) {
-  for (int i = from; i < to; i++) {
-    if (s[i] < '0' || s[i] > '9') return false;
-  }
+RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 3);
 
-  return true;
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  RUNTIME_ASSERT(key->IsUniqueName());
+  return *JSObject::SetHiddenProperty(object, key, value);
 }
 
 
-static int ParseDecimalInteger(const uint8_t* s, int from, int to) {
-  DCHECK(to - from < 10);  // Overflow is not possible.
-  DCHECK(from < to);
-  int d = s[from] - '0';
+RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
 
-  for (int i = from + 1; i < to; i++) {
-    d = 10 * d + (s[i] - '0');
-  }
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+  RUNTIME_ASSERT(
+      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  // Compute attributes.
+  PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(unchecked_attributes);
+
+#ifdef DEBUG
+  uint32_t index = 0;
+  DCHECK(!key->ToArrayIndex(&index));
+  LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
+  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  RUNTIME_ASSERT(!it.IsFound());
+#endif
 
-  return d;
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_StringToNumber) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  subject = String::Flatten(subject);
+RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
 
-  // Fast case: short integer or some sorts of junk values.
-  if (subject->IsSeqOneByteString()) {
-    int len = subject->length();
-    if (len == 0) return Smi::FromInt(0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+  RUNTIME_ASSERT(
+      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  // Compute attributes.
+  PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(unchecked_attributes);
 
-    DisallowHeapAllocation no_gc;
-    uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
-    bool minus = (data[0] == '-');
-    int start_pos = (minus ? 1 : 0);
-
-    if (start_pos == len) {
-      return isolate->heap()->nan_value();
-    } else if (data[start_pos] > '9') {
-      // Fast check for a junk value. A valid string may start from a
-      // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
-      // or the 'I' character ('Infinity'). All of that have codes not greater
-      // than '9' except 'I' and &nbsp;.
-      if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
-        return isolate->heap()->nan_value();
-      }
-    } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
-      // The maximal/minimal smi has 10 digits. If the string has less digits
-      // we know it will fit into the smi-data type.
-      int d = ParseDecimalInteger(data, start_pos, len);
-      if (minus) {
-        if (d == 0) return isolate->heap()->minus_zero_value();
-        d = -d;
-      } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
-                 (len == 1 || data[0] != '0')) {
-        // String hash is not calculated yet but all the data are present.
-        // Update the hash field to speed up sequential convertions.
-        uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
 #ifdef DEBUG
-        subject->Hash();  // Force hash calculation.
-        DCHECK_EQ(static_cast<int>(subject->hash_field()),
-                  static_cast<int>(hash));
-#endif
-        subject->set_hash_field(hash);
-      }
-      return Smi::FromInt(d);
-    }
+  bool duplicate;
+  if (key->IsName()) {
+    LookupIterator it(object, Handle<Name>::cast(key),
+                      LookupIterator::OWN_SKIP_INTERCEPTOR);
+    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+    DCHECK(maybe.has_value);
+    duplicate = it.IsFound();
+  } else {
+    uint32_t index = 0;
+    RUNTIME_ASSERT(key->ToArrayIndex(&index));
+    Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
+    if (!maybe.has_value) return isolate->heap()->exception();
+    duplicate = maybe.value;
   }
-
-  // Slower case.
-  int flags = ALLOW_HEX;
-  if (FLAG_harmony_numeric_literals) {
-    // The current spec draft has not updated "ToNumber Applied to the String
-    // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
-    flags |= ALLOW_OCTAL | ALLOW_BINARY;
+  if (duplicate) {
+    Handle<Object> args[1] = {key};
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError("duplicate_template_property", HandleVector(args, 1)));
   }
+#endif
 
-  return *isolate->factory()->NewNumber(
-      StringToDouble(isolate->unicode_cache(), *subject, flags));
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::DefineObjectProperty(object, key, value, attributes));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_StringParseInt) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
-  RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
-
-  subject = String::Flatten(subject);
-  double value;
-
-  {
-    DisallowHeapAllocation no_gc;
-    String::FlatContent flat = subject->GetFlatContent();
+RUNTIME_FUNCTION(Runtime_SetProperty) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
 
-    // ECMA-262 section 15.1.2.3, empty string is NaN
-    if (flat.IsOneByte()) {
-      value =
-          StringToInt(isolate->unicode_cache(), flat.ToOneByteVector(), radix);
-    } else {
-      value = StringToInt(isolate->unicode_cache(), flat.ToUC16Vector(), radix);
-    }
-  }
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 3);
+  StrictMode strict_mode = strict_mode_arg;
 
-  return *isolate->factory()->NewNumber(value);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::SetObjectProperty(isolate, object, key, value, strict_mode));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_StringParseFloat) {
-  HandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-
-  subject = String::Flatten(subject);
-  double value = StringToDouble(isolate->unicode_cache(), *subject,
-                                ALLOW_TRAILING_JUNK, base::OS::nan_value());
+// Adds an element to an array.
+// This is used to create an indexed data property into an array.
+RUNTIME_FUNCTION(Runtime_AddElement) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
 
-  return *isolate->factory()->NewNumber(value);
-}
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+  RUNTIME_ASSERT(
+      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  // Compute attributes.
+  PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(unchecked_attributes);
 
+  uint32_t index = 0;
+  key->ToArrayIndex(&index);
 
-RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
-  return *Object::ToObject(isolate, value).ToHandleChecked();
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, JSObject::SetElement(object, index, value, attributes,
+                                            SLOPPY, false, DEFINE_PROPERTY));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberToStringRT) {
+RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
-
-  return *isolate->factory()->NumberToString(number);
+  RUNTIME_ASSERT(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
+  JSObject::TransitionElementsKind(array, map->elements_kind());
+  return *array;
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
+// Set the native flag on the function.
+// This is used to decide if we should transform null and undefined
+// into the global object when doing call and apply.
+RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
+  SealHandleScope shs(isolate);
+  RUNTIME_ASSERT(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(Object, object, 0);
 
-  return *isolate->factory()->NumberToString(number, false);
+  if (object->IsJSFunction()) {
+    JSFunction* func = JSFunction::cast(object);
+    func->shared()->set_native(true);
+  }
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberToInteger) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
+RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
+  SealHandleScope shs(isolate);
+  RUNTIME_ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
 
-  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-  return *isolate->factory()->NewNumber(DoubleToInteger(number));
+  if (object->IsJSFunction()) {
+    JSFunction* func = JSFunction::cast(*object);
+    func->shared()->set_inline_builtin(true);
+  }
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
+RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
+  RUNTIME_ASSERT(args.length() == 5);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_SMI_ARG_CHECKED(store_index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
+  CONVERT_SMI_ARG_CHECKED(literal_index, 4);
 
-  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-  double double_value = DoubleToInteger(number);
-  // Map both -0 and +0 to +0.
-  if (double_value == 0) double_value = 0;
+  Object* raw_literal_cell = literals->get(literal_index);
+  JSArray* boilerplate = NULL;
+  if (raw_literal_cell->IsAllocationSite()) {
+    AllocationSite* site = AllocationSite::cast(raw_literal_cell);
+    boilerplate = JSArray::cast(site->transition_info());
+  } else {
+    boilerplate = JSArray::cast(raw_literal_cell);
+  }
+  Handle<JSArray> boilerplate_object(boilerplate);
+  ElementsKind elements_kind = object->GetElementsKind();
+  DCHECK(IsFastElementsKind(elements_kind));
+  // Smis should never trigger transitions.
+  DCHECK(!value->IsSmi());
 
-  return *isolate->factory()->NewNumber(double_value);
+  if (value->IsNumber()) {
+    DCHECK(IsFastSmiElementsKind(elements_kind));
+    ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
+                                         ? FAST_HOLEY_DOUBLE_ELEMENTS
+                                         : FAST_DOUBLE_ELEMENTS;
+    if (IsMoreGeneralElementsKindTransition(
+            boilerplate_object->GetElementsKind(), transitioned_kind)) {
+      JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
+    }
+    JSObject::TransitionElementsKind(object, transitioned_kind);
+    DCHECK(IsFastDoubleElementsKind(object->GetElementsKind()));
+    FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
+    HeapNumber* number = HeapNumber::cast(*value);
+    double_array->set(store_index, number->Number());
+  } else {
+    if (!IsFastObjectElementsKind(elements_kind)) {
+      ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
+                                           ? FAST_HOLEY_ELEMENTS
+                                           : FAST_ELEMENTS;
+      JSObject::TransitionElementsKind(object, transitioned_kind);
+      ElementsKind boilerplate_elements_kind =
+          boilerplate_object->GetElementsKind();
+      if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
+                                              transitioned_kind)) {
+        JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
+      }
+    }
+    FixedArray* object_array = FixedArray::cast(object->elements());
+    object_array->set(store_index, *value);
+  }
+  return *object;
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
-  HandleScope scope(isolate);
+// Check whether debugger and is about to step into the callback that is passed
+// to a built-in function such as Array.forEach.
+RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
   DCHECK(args.length() == 1);
-
-  CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
-  return *isolate->factory()->NewNumberFromUint(number);
+  if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
+    return isolate->heap()->false_value();
+  }
+  CONVERT_ARG_CHECKED(Object, callback, 0);
+  // We do not step into the callback if it's a builtin or not even a function.
+  return isolate->heap()->ToBoolean(callback->IsJSFunction() &&
+                                    !JSFunction::cast(callback)->IsBuiltin());
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
-  HandleScope scope(isolate);
+// Set one shot breakpoints for the callback function that is passed to a
+// built-in function such as Array.forEach to enable stepping into the callback.
+RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
   DCHECK(args.length() == 1);
+  Debug* debug = isolate->debug();
+  if (!debug->IsStepping()) return isolate->heap()->undefined_value();
 
-  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-  return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
+  Handle<JSFunction> fun;
+  if (object->IsJSFunction()) {
+    fun = Handle<JSFunction>::cast(object);
+  } else {
+    fun = Handle<JSFunction>(
+        Handle<JSGeneratorObject>::cast(object)->function(), isolate);
+  }
+  // When leaving the function, step out has been activated, but not performed
+  // if we do not leave the builtin.  To be able to step into the function
+  // again, we need to clear the step out at this point.
+  debug->ClearStepOut();
+  debug->FloodWithOneShot(fun);
+  return isolate->heap()->undefined_value();
 }
 
 
-// Converts a Number to a Smi, if possible. Returns NaN if the number is not
-// a small integer.
-RUNTIME_FUNCTION(Runtime_NumberToSmi) {
-  SealHandleScope shs(isolate);
+RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
   DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (obj->IsSmi()) {
-    return obj;
-  }
-  if (obj->IsHeapNumber()) {
-    double value = HeapNumber::cast(obj)->value();
-    int int_value = FastD2I(value);
-    if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
-      return Smi::FromInt(int_value);
-    }
-  }
-  return isolate->heap()->nan_value();
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+  isolate->PushPromise(promise);
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
-  HandleScope scope(isolate);
+RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
   DCHECK(args.length() == 0);
-  return *isolate->factory()->NewHeapNumber(0);
+  SealHandleScope shs(isolate);
+  isolate->PopPromise();
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberAdd) {
+RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
+  DCHECK(args.length() == 1);
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(x + y);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
+  isolate->debug()->OnPromiseEvent(data);
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberSub) {
-  HandleScope scope(isolate);
+RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) {
   DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(x - y);
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+  isolate->debug()->OnPromiseReject(promise, value);
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberMul) {
+RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
+  DCHECK(args.length() == 1);
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(x * y);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
+  isolate->debug()->OnAsyncTaskEvent(data);
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
+RUNTIME_FUNCTION(Runtime_DeleteProperty) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
+  JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
+                                           ? JSReceiver::STRICT_DELETION
+                                           : JSReceiver::NORMAL_DELETION;
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, JSReceiver::DeleteProperty(object, key, delete_mode));
+  return *result;
+}
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return *isolate->factory()->NewNumber(-x);
+
+static Object* HasOwnPropertyImplementation(Isolate* isolate,
+                                            Handle<JSObject> object,
+                                            Handle<Name> key) {
+  Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  if (maybe.value) return isolate->heap()->true_value();
+  // Handle hidden prototypes.  If there's a hidden prototype above this thing
+  // then we have to check it for properties, because they are supposed to
+  // look like they are on this object.
+  PrototypeIterator iter(isolate, object);
+  if (!iter.IsAtEnd() &&
+      Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))
+          ->map()
+          ->is_hidden_prototype()) {
+    // TODO(verwaest): The recursion is not necessary for keys that are array
+    // indices. Removing this.
+    return HasOwnPropertyImplementation(
+        isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+        key);
+  }
+  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+  return isolate->heap()->false_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberDiv) {
+RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(x / y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberMod) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
+  uint32_t index;
+  const bool key_is_array_index = key->AsArrayIndex(&index);
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(modulo(x, y));
+  // Only JS objects can have properties.
+  if (object->IsJSObject()) {
+    Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
+    // Fast case: either the key is a real named property or it is not
+    // an array index and there are no interceptors or hidden
+    // prototypes.
+    Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key);
+    if (!maybe.has_value) return isolate->heap()->exception();
+    DCHECK(!isolate->has_pending_exception());
+    if (maybe.value) {
+      return isolate->heap()->true_value();
+    }
+    Map* map = js_obj->map();
+    if (!key_is_array_index && !map->has_named_interceptor() &&
+        !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
+      return isolate->heap()->false_value();
+    }
+    // Slow case.
+    return HasOwnPropertyImplementation(isolate, Handle<JSObject>(js_obj),
+                                        Handle<Name>(key));
+  } else if (object->IsString() && key_is_array_index) {
+    // Well, there is one exception:  Handle [] on strings.
+    Handle<String> string = Handle<String>::cast(object);
+    if (index < static_cast<uint32_t>(string->length())) {
+      return isolate->heap()->true_value();
+    }
+  }
+  return isolate->heap()->false_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberImul) {
+RUNTIME_FUNCTION(Runtime_HasProperty) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
 
-  // We rely on implementation-defined behavior below, but at least not on
-  // undefined behavior.
-  CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
-  int32_t product = static_cast<int32_t>(x * y);
-  return *isolate->factory()->NewNumberFromInt(product);
+  Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  return isolate->heap()->ToBoolean(maybe.value);
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberOr) {
+RUNTIME_FUNCTION(Runtime_HasElement) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
+  CONVERT_SMI_ARG_CHECKED(index, 1);
 
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(x | y);
+  Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  return isolate->heap()->ToBoolean(maybe.value);
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberAnd) {
+RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 2);
 
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(x & y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberXor) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
 
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(x ^ y);
+  Maybe<PropertyAttributes> maybe =
+      JSReceiver::GetOwnPropertyAttributes(object, key);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
+  return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberShl) {
+RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
+  Handle<JSArray> result;
 
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
+  isolate->counters()->for_in()->Increment();
+  Handle<FixedArray> elements;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, elements,
+      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
+  return *isolate->factory()->NewJSArrayWithElements(elements);
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberShr) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
+// Returns either a FixedArray as Runtime_GetPropertyNames,
+// or, if the given object has an enum cache that contains
+// all enumerable properties of the object and its prototypes
+// have none, the map of the object. This is used to speed up
+// the check for deletions during a for-in.
+RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
 
-  CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
-}
+  CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
 
+  if (raw_object->IsSimpleEnum()) return raw_object->map();
 
-RUNTIME_FUNCTION(Runtime_NumberSar) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(
-      ArithmeticShiftRight(x, y & 0x1f));
-}
-
+  Handle<JSReceiver> object(raw_object);
+  Handle<FixedArray> content;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, content,
+      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
 
-RUNTIME_FUNCTION(Runtime_NumberEquals) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
+  // Test again, since cache may have been built by preceding call.
+  if (object->IsSimpleEnum()) return object->map();
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
-  if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
-  if (x == y) return Smi::FromInt(EQUAL);
-  Object* result;
-  if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
-    result = Smi::FromInt(EQUAL);
-  } else {
-    result = Smi::FromInt(NOT_EQUAL);
-  }
-  return result;
+  return *content;
 }
 
 
-RUNTIME_FUNCTION(Runtime_NumberCompare) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
-  if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
-  if (x == y) return Smi::FromInt(EQUAL);
-  if (isless(x, y)) return Smi::FromInt(LESS);
-  return Smi::FromInt(GREATER);
+// Find the length of the prototype chain that is to be handled as one. If a
+// prototype object is hidden it is to be viewed as part of the the object it
+// is prototype for.
+static int OwnPrototypeChainLength(JSObject* obj) {
+  int count = 1;
+  for (PrototypeIterator iter(obj->GetIsolate(), obj);
+       !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
+    count++;
+  }
+  return count;
 }
 
 
-// Compare two Smis as if they were converted to strings and then
-// compared lexicographically.
-RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
-  SealHandleScope shs(isolate);
+// Return the names of the own named properties.
+// args[0]: object
+// args[1]: PropertyAttributes as int
+RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
+  HandleScope scope(isolate);
   DCHECK(args.length() == 2);
-  CONVERT_SMI_ARG_CHECKED(x_value, 0);
-  CONVERT_SMI_ARG_CHECKED(y_value, 1);
-
-  // If the integers are equal so are the string representations.
-  if (x_value == y_value) return Smi::FromInt(EQUAL);
-
-  // If one of the integers is zero the normal integer order is the
-  // same as the lexicographic order of the string representations.
-  if (x_value == 0 || y_value == 0)
-    return Smi::FromInt(x_value < y_value ? LESS : GREATER);
-
-  // If only one of the integers is negative the negative number is
-  // smallest because the char code of '-' is less than the char code
-  // of any digit.  Otherwise, we make both values positive.
+  if (!args[0]->IsJSObject()) {
+    return isolate->heap()->undefined_value();
+  }
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_SMI_ARG_CHECKED(filter_value, 1);
+  PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
 
-  // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
-  // architectures using 32-bit Smis.
-  uint32_t x_scaled = x_value;
-  uint32_t y_scaled = y_value;
-  if (x_value < 0 || y_value < 0) {
-    if (y_value >= 0) return Smi::FromInt(LESS);
-    if (x_value >= 0) return Smi::FromInt(GREATER);
-    x_scaled = -x_value;
-    y_scaled = -y_value;
+  // Skip the global proxy as it has no properties and always delegates to the
+  // real global object.
+  if (obj->IsJSGlobalProxy()) {
+    // Only collect names if access is permitted.
+    if (obj->IsAccessCheckNeeded() &&
+        !isolate->MayNamedAccess(obj, isolate->factory()->undefined_value(),
+                                 v8::ACCESS_KEYS)) {
+      isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
+      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+      return *isolate->factory()->NewJSArray(0);
+    }
+    PrototypeIterator iter(isolate, obj);
+    obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
   }
 
-  static const uint32_t kPowersOf10[] = {
-      1,                 10,                100,         1000,
-      10 * 1000,         100 * 1000,        1000 * 1000, 10 * 1000 * 1000,
-      100 * 1000 * 1000, 1000 * 1000 * 1000};
+  // Find the number of objects making up this.
+  int length = OwnPrototypeChainLength(*obj);
 
-  // If the integers have the same number of decimal digits they can be
-  // compared directly as the numeric order is the same as the
-  // lexicographic order.  If one integer has fewer digits, it is scaled
-  // by some power of 10 to have the same number of digits as the longer
-  // integer.  If the scaled integers are equal it means the shorter
-  // integer comes first in the lexicographic order.
+  // Find the number of own properties for each of the objects.
+  ScopedVector<int> own_property_count(length);
+  int total_property_count = 0;
+  {
+    PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+    for (int i = 0; i < length; i++) {
+      DCHECK(!iter.IsAtEnd());
+      Handle<JSObject> jsproto =
+          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      // Only collect names if access is permitted.
+      if (jsproto->IsAccessCheckNeeded() &&
+          !isolate->MayNamedAccess(jsproto,
+                                   isolate->factory()->undefined_value(),
+                                   v8::ACCESS_KEYS)) {
+        isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
+        RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+        return *isolate->factory()->NewJSArray(0);
+      }
+      int n;
+      n = jsproto->NumberOfOwnProperties(filter);
+      own_property_count[i] = n;
+      total_property_count += n;
+      iter.Advance();
+    }
+  }
 
-  // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
-  int x_log2 = IntegerLog2(x_scaled);
-  int x_log10 = ((x_log2 + 1) * 1233) >> 12;
-  x_log10 -= x_scaled < kPowersOf10[x_log10];
+  // Allocate an array with storage for all the property names.
+  Handle<FixedArray> names =
+      isolate->factory()->NewFixedArray(total_property_count);
 
-  int y_log2 = IntegerLog2(y_scaled);
-  int y_log10 = ((y_log2 + 1) * 1233) >> 12;
-  y_log10 -= y_scaled < kPowersOf10[y_log10];
+  // Get the property names.
+  int next_copy_index = 0;
+  int hidden_strings = 0;
+  {
+    PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+    for (int i = 0; i < length; i++) {
+      DCHECK(!iter.IsAtEnd());
+      Handle<JSObject> jsproto =
+          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
+      if (i > 0) {
+        // Names from hidden prototypes may already have been added
+        // for inherited function template instances. Count the duplicates
+        // and stub them out; the final copy pass at the end ignores holes.
+        for (int j = next_copy_index;
+             j < next_copy_index + own_property_count[i]; j++) {
+          Object* name_from_hidden_proto = names->get(j);
+          for (int k = 0; k < next_copy_index; k++) {
+            if (names->get(k) != isolate->heap()->hidden_string()) {
+              Object* name = names->get(k);
+              if (name_from_hidden_proto == name) {
+                names->set(j, isolate->heap()->hidden_string());
+                hidden_strings++;
+                break;
+              }
+            }
+          }
+        }
+      }
+      next_copy_index += own_property_count[i];
 
-  int tie = EQUAL;
+      // Hidden properties only show up if the filter does not skip strings.
+      if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
+        hidden_strings++;
+      }
+      iter.Advance();
+    }
+  }
 
-  if (x_log10 < y_log10) {
-    // X has fewer digits.  We would like to simply scale up X but that
-    // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
-    // be scaled up to 9_000_000_000. So we scale up by the next
-    // smallest power and scale down Y to drop one digit. It is OK to
-    // drop one digit from the longer integer since the final digit is
-    // past the length of the shorter integer.
-    x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
-    y_scaled /= 10;
-    tie = LESS;
-  } else if (y_log10 < x_log10) {
-    y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
-    x_scaled /= 10;
-    tie = GREATER;
+  // Filter out name of hidden properties object and
+  // hidden prototype duplicates.
+  if (hidden_strings > 0) {
+    Handle<FixedArray> old_names = names;
+    names = isolate->factory()->NewFixedArray(names->length() - hidden_strings);
+    int dest_pos = 0;
+    for (int i = 0; i < total_property_count; i++) {
+      Object* name = old_names->get(i);
+      if (name == isolate->heap()->hidden_string()) {
+        hidden_strings--;
+        continue;
+      }
+      names->set(dest_pos++, name);
+    }
+    DCHECK_EQ(0, hidden_strings);
   }
 
-  if (x_scaled < y_scaled) return Smi::FromInt(LESS);
-  if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
-  return Smi::FromInt(tie);
+  return *isolate->factory()->NewJSArrayWithElements(names);
 }
 
 
+// Return the names of the own indexed properties.
+// args[0]: object
+RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  if (!args[0]->IsJSObject()) {
+    return isolate->heap()->undefined_value();
+  }
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
 
+  int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
+  Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
+  obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
+  return *isolate->factory()->NewJSArrayWithElements(names);
+}
 
 
-#define RUNTIME_UNARY_MATH(Name, name)                       \
-  RUNTIME_FUNCTION(Runtime_Math##Name) {                     \
-    HandleScope scope(isolate);                              \
-    DCHECK(args.length() == 1);                              \
-    isolate->counters()->math_##name()->Increment();         \
-    CONVERT_DOUBLE_ARG_CHECKED(x, 0);                        \
-    return *isolate->factory()->NewHeapNumber(std::name(x)); \
+// Return information on whether an object has a named or indexed interceptor.
+// args[0]: object
+RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  if (!args[0]->IsJSObject()) {
+    return Smi::FromInt(0);
   }
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
 
-RUNTIME_UNARY_MATH(Acos, acos)
-RUNTIME_UNARY_MATH(Asin, asin)
-RUNTIME_UNARY_MATH(Atan, atan)
-RUNTIME_UNARY_MATH(LogRT, log)
-#undef RUNTIME_UNARY_MATH
-
+  int result = 0;
+  if (obj->HasNamedInterceptor()) result |= 2;
+  if (obj->HasIndexedInterceptor()) result |= 1;
 
-RUNTIME_FUNCTION(Runtime_DoubleHi) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  uint64_t integer = double_to_uint64(x);
-  integer = (integer >> 32) & 0xFFFFFFFFu;
-  return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
+  return Smi::FromInt(result);
 }
 
 
-RUNTIME_FUNCTION(Runtime_DoubleLo) {
+// Return property names from named interceptor.
+// args[0]: object
+RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return *isolate->factory()->NewNumber(
-      static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+
+  if (obj->HasNamedInterceptor()) {
+    Handle<JSObject> result;
+    if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
+      return *result;
+    }
+  }
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_ConstructDouble) {
+// Return element names from indexed interceptor.
+// args[0]: object
+RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
-  CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
-  uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
-  return *isolate->factory()->NewNumber(uint64_to_double(result));
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+
+  if (obj->HasIndexedInterceptor()) {
+    Handle<JSObject> result;
+    if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
+      return *result;
+    }
+  }
+  return isolate->heap()->undefined_value();
 }
 
 
-RUNTIME_FUNCTION(Runtime_RemPiO2) {
-  HandleScope handle_scope(isolate);
+RUNTIME_FUNCTION(Runtime_OwnKeys) {
+  HandleScope scope(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  Factory* factory = isolate->factory();
-  double y[2];
-  int n = fdlibm::rempio2(x, y);
-  Handle<FixedArray> array = factory->NewFixedArray(3);
-  Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
-  Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
-  array->set(0, Smi::FromInt(n));
-  array->set(1, *y0);
-  array->set(2, *y1);
-  return *factory->NewJSArrayWithElements(array);
-}
-
+  CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
+  Handle<JSObject> object(raw_object);
 
-static const double kPiDividedBy4 = 0.78539816339744830962;
+  if (object->IsJSGlobalProxy()) {
+    // Do access checks before going to the global object.
+    if (object->IsAccessCheckNeeded() &&
+        !isolate->MayNamedAccess(object, isolate->factory()->undefined_value(),
+                                 v8::ACCESS_KEYS)) {
+      isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
+      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+      return *isolate->factory()->NewJSArray(0);
+    }
 
+    PrototypeIterator iter(isolate, object);
+    // If proxy is detached we simply return an empty array.
+    if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0);
+    object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+  }
 
-RUNTIME_FUNCTION(Runtime_MathAtan2) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  isolate->counters()->math_atan2()->Increment();
+  Handle<FixedArray> contents;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, contents, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  double result;
-  if (std::isinf(x) && std::isinf(y)) {
-    // Make sure that the result in case of two infinite arguments
-    // is a multiple of Pi / 4. The sign of the result is determined
-    // by the first argument (x) and the sign of the second argument
-    // determines the multiplier: one or three.
-    int multiplier = (x < 0) ? -1 : 1;
-    if (y < 0) multiplier *= 3;
-    result = multiplier * kPiDividedBy4;
-  } else {
-    result = std::atan2(x, y);
+  // Some fast paths through GetKeysInFixedArrayFor reuse a cached
+  // property array and since the result is mutable we have to create
+  // a fresh clone on each invocation.
+  int length = contents->length();
+  Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
+  for (int i = 0; i < length; i++) {
+    Object* entry = contents->get(i);
+    if (entry->IsString()) {
+      copy->set(i, entry);
+    } else {
+      DCHECK(entry->IsNumber());
+      HandleScope scope(isolate);
+      Handle<Object> entry_handle(entry, isolate);
+      Handle<Object> entry_str =
+          isolate->factory()->NumberToString(entry_handle);
+      copy->set(i, *entry_str);
+    }
   }
-  return *isolate->factory()->NewNumber(result);
+  return *isolate->factory()->NewJSArrayWithElements(copy);
 }
 
 
-RUNTIME_FUNCTION(Runtime_MathExpRT) {
-  HandleScope scope(isolate);
+RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
+  SealHandleScope shs(isolate);
   DCHECK(args.length() == 1);
-  isolate->counters()->math_exp()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  lazily_initialize_fast_exp();
-  return *isolate->factory()->NewNumber(fast_exp(x));
-}
-
+  CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
 
-RUNTIME_FUNCTION(Runtime_MathFloorRT) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  isolate->counters()->math_floor()->Increment();
+  // Compute the frame holding the arguments.
+  JavaScriptFrameIterator it(isolate);
+  it.AdvanceToArgumentsFrame();
+  JavaScriptFrame* frame = it.frame();
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return *isolate->factory()->NewNumber(Floor(x));
-}
+  // Get the actual number of provided arguments.
+  const uint32_t n = frame->ComputeParametersCount();
 
+  // Try to convert the key to an index. If successful and within
+  // index return the the argument from the frame.
+  uint32_t index;
+  if (raw_key->ToArrayIndex(&index) && index < n) {
+    return frame->GetParameter(index);
+  }
 
-// Slow version of Math.pow.  We check for fast paths for special cases.
-// Used if VFP3 is not available.
-RUNTIME_FUNCTION(Runtime_MathPowSlow) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  isolate->counters()->math_pow()->Increment();
+  if (raw_key->IsSymbol()) {
+    Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key);
+    if (symbol->Equals(isolate->native_context()->iterator_symbol())) {
+      return isolate->native_context()->array_values_iterator();
+    }
+    // Lookup in the initial Object.prototype object.
+    Handle<Object> result;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result,
+        Object::GetProperty(isolate->initial_object_prototype(),
+                            Handle<Symbol>::cast(raw_key)));
+    return *result;
+  }
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  // Convert the key to a string.
+  Handle<Object> converted;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, converted,
+                                     Execution::ToString(isolate, raw_key));
+  Handle<String> key = Handle<String>::cast(converted);
 
-  // If the second argument is a smi, it is much faster to call the
-  // custom powi() function than the generic pow().
-  if (args[1]->IsSmi()) {
-    int y = args.smi_at(1);
-    return *isolate->factory()->NewNumber(power_double_int(x, y));
+  // Try to convert the string key into an array index.
+  if (key->AsArrayIndex(&index)) {
+    if (index < n) {
+      return frame->GetParameter(index);
+    } else {
+      Handle<Object> initial_prototype(isolate->initial_object_prototype());
+      Handle<Object> result;
+      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+          isolate, result,
+          Object::GetElement(isolate, initial_prototype, index));
+      return *result;
+    }
+  }
+
+  // Handle special arguments properties.
+  if (String::Equals(isolate->factory()->length_string(), key)) {
+    return Smi::FromInt(n);
+  }
+  if (String::Equals(isolate->factory()->callee_string(), key)) {
+    JSFunction* function = frame->function();
+    if (function->shared()->strict_mode() == STRICT) {
+      THROW_NEW_ERROR_RETURN_FAILURE(
+          isolate, NewTypeError("strict_arguments_callee",
+                                HandleVector<Object>(NULL, 0)));
+    }
+    return function;
   }
 
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  double result = power_helper(x, y);
-  if (std::isnan(result)) return isolate->heap()->nan_value();
-  return *isolate->factory()->NewNumber(result);
+  // Lookup in the initial Object.prototype object.
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Object::GetProperty(isolate->initial_object_prototype(), key));
+  return *result;
 }
 
 
-// Fast version of Math.pow if we know that y is not an integer and y is not
-// -0.5 or 0.5.  Used as slow case from full codegen.
-RUNTIME_FUNCTION(Runtime_MathPowRT) {
+RUNTIME_FUNCTION(Runtime_ToFastProperties) {
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  isolate->counters()->math_pow()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  if (y == 0) {
-    return Smi::FromInt(1);
-  } else {
-    double result = power_double_double(x, y);
-    if (std::isnan(result)) return isolate->heap()->nan_value();
-    return *isolate->factory()->NewNumber(result);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  if (object->IsJSObject() && !object->IsGlobalObject()) {
+    JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0);
   }
+  return *object;
 }
 
 
-RUNTIME_FUNCTION(Runtime_RoundNumber) {
-  HandleScope scope(isolate);
+RUNTIME_FUNCTION(Runtime_ToBool) {
+  SealHandleScope shs(isolate);
   DCHECK(args.length() == 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
-  isolate->counters()->math_round()->Increment();
+  CONVERT_ARG_CHECKED(Object, object, 0);
 
-  if (!input->IsHeapNumber()) {
-    DCHECK(input->IsSmi());
-    return *input;
-  }
+  return isolate->heap()->ToBoolean(object->BooleanValue());
+}
 
-  Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
 
-  double value = number->value();
-  int exponent = number->get_exponent();
-  int sign = number->get_sign();
+// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
+// Possible optimizations: put the type string into the oddballs.
+RUNTIME_FUNCTION(Runtime_Typeof) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (obj->IsNumber()) return isolate->heap()->number_string();
+  HeapObject* heap_obj = HeapObject::cast(obj);
 
-  if (exponent < -1) {
-    // Number in range ]-0.5..0.5[. These always round to +/-zero.
-    if (sign) return isolate->heap()->minus_zero_value();
-    return Smi::FromInt(0);
+  // typeof an undetectable object is 'undefined'
+  if (heap_obj->map()->is_undetectable()) {
+    return isolate->heap()->undefined_string();
   }
 
-  // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
-  // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
-  // argument holds for 32-bit smis).
-  if (!sign && exponent < kSmiValueSize - 2) {
-    return Smi::FromInt(static_cast<int>(value + 0.5));
+  InstanceType instance_type = heap_obj->map()->instance_type();
+  if (instance_type < FIRST_NONSTRING_TYPE) {
+    return isolate->heap()->string_string();
   }
 
-  // If the magnitude is big enough, there's no place for fraction part. If we
-  // try to add 0.5 to this number, 1.0 will be added instead.
-  if (exponent >= 52) {
-    return *number;
+  switch (instance_type) {
+    case ODDBALL_TYPE:
+      if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
+        return isolate->heap()->boolean_string();
+      }
+      if (heap_obj->IsNull()) {
+        return isolate->heap()->object_string();
+      }
+      DCHECK(heap_obj->IsUndefined());
+      return isolate->heap()->undefined_string();
+    case SYMBOL_TYPE:
+      return isolate->heap()->symbol_string();
+    case JS_FUNCTION_TYPE:
+    case JS_FUNCTION_PROXY_TYPE:
+      return isolate->heap()->function_string();
+    default:
+      // For any kind of object not handled above, the spec rule for
+      // host objects gives that it is okay to return "object"
+      return isolate->heap()->object_string();
   }
+}
 
-  if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
 
-  // Do not call NumberFromDouble() to avoid extra checks.
-  return *isolate->factory()->NewNumber(Floor(value + 0.5));
+RUNTIME_FUNCTION(Runtime_Booleanize) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(Object, value_raw, 0);
+  CONVERT_SMI_ARG_CHECKED(token_raw, 1);
+  intptr_t value = reinterpret_cast<intptr_t>(value_raw);
+  Token::Value token = static_cast<Token::Value>(token_raw);
+  switch (token) {
+    case Token::EQ:
+    case Token::EQ_STRICT:
+      return isolate->heap()->ToBoolean(value == 0);
+    case Token::NE:
+    case Token::NE_STRICT:
+      return isolate->heap()->ToBoolean(value != 0);
+    case Token::LT:
+      return isolate->heap()->ToBoolean(value < 0);
+    case Token::GT:
+      return isolate->heap()->ToBoolean(value > 0);
+    case Token::LTE:
+      return isolate->heap()->ToBoolean(value <= 0);
+    case Token::GTE:
+      return isolate->heap()->ToBoolean(value >= 0);
+    default:
+      // This should only happen during natives fuzzing.
+      return isolate->heap()->undefined_value();
+  }
 }
 
 
-RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
+RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
-  isolate->counters()->math_sqrt()->Increment();
+  CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
+  return *Object::ToObject(isolate, value).ToHandleChecked();
+}
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return *isolate->factory()->NewNumber(fast_sqrt(x));
+
+RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  return *isolate->factory()->NewHeapNumber(0);
 }
 
 
-RUNTIME_FUNCTION(Runtime_MathFround) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
 
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  float xf = DoubleToFloat32(x);
-  return *isolate->factory()->NewNumber(xf);
-}
 
 
 RUNTIME_FUNCTION(Runtime_DateMakeDay) {
@@ -5471,584 +3648,122 @@ RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
       JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
       isolate);
   DCHECK(!bound_function->IsJSFunction() ||
-         !Handle<JSFunction>::cast(bound_function)->shared()->bound());
-
-  int total_argc = 0;
-  SmartArrayPointer<Handle<Object> > param_data =
-      GetCallerArguments(isolate, bound_argc, &total_argc);
-  for (int i = 0; i < bound_argc; i++) {
-    param_data[i] = Handle<Object>(
-        bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate);
-  }
-
-  if (!bound_function->IsJSFunction()) {
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, bound_function,
-        Execution::TryGetConstructorDelegate(isolate, bound_function));
-  }
-  DCHECK(bound_function->IsJSFunction());
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, Execution::New(Handle<JSFunction>::cast(bound_function),
-                                      total_argc, param_data.get()));
-  return *result;
-}
-
-
-static Object* Runtime_NewObjectHelper(Isolate* isolate,
-                                       Handle<Object> constructor,
-                                       Handle<AllocationSite> site) {
-  // If the constructor isn't a proper function we throw a type error.
-  if (!constructor->IsJSFunction()) {
-    Vector<Handle<Object> > arguments = HandleVector(&constructor, 1);
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
-                                   NewTypeError("not_constructor", arguments));
-  }
-
-  Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
-
-  // If function should not have prototype, construction is not allowed. In this
-  // case generated code bailouts here, since function has no initial_map.
-  if (!function->should_have_prototype() && !function->shared()->bound()) {
-    Vector<Handle<Object> > arguments = HandleVector(&constructor, 1);
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
-                                   NewTypeError("not_constructor", arguments));
-  }
-
-  Debug* debug = isolate->debug();
-  // Handle stepping into constructors if step into is active.
-  if (debug->StepInActive()) {
-    debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
-  }
-
-  if (function->has_initial_map()) {
-    if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
-      // The 'Function' function ignores the receiver object when
-      // called using 'new' and creates a new JSFunction object that
-      // is returned.  The receiver object is only used for error
-      // reporting if an error occurs when constructing the new
-      // JSFunction. Factory::NewJSObject() should not be used to
-      // allocate JSFunctions since it does not properly initialize
-      // the shared part of the function. Since the receiver is
-      // ignored anyway, we use the global object as the receiver
-      // instead of a new JSFunction object. This way, errors are
-      // reported the same way whether or not 'Function' is called
-      // using 'new'.
-      return isolate->global_proxy();
-    }
-  }
-
-  // The function should be compiled for the optimization hints to be
-  // available.
-  Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
-
-  Handle<JSObject> result;
-  if (site.is_null()) {
-    result = isolate->factory()->NewJSObject(function);
-  } else {
-    result = isolate->factory()->NewJSObjectWithMemento(function, site);
-  }
-
-  isolate->counters()->constructed_objects()->Increment();
-  isolate->counters()->constructed_objects_runtime()->Increment();
-
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewObject) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
-  return Runtime_NewObjectHelper(isolate, constructor,
-                                 Handle<AllocationSite>::null());
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
-  Handle<AllocationSite> site;
-  if (feedback->IsAllocationSite()) {
-    // The feedback can be an AllocationSite or undefined.
-    site = Handle<AllocationSite>::cast(feedback);
-  }
-  return Runtime_NewObjectHelper(isolate, constructor, site);
-}
-
-
-RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  function->CompleteInobjectSlackTracking();
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_CompileLazy) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-#ifdef DEBUG
-  if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
-    PrintF("[unoptimized: ");
-    function->PrintName();
-    PrintF("]\n");
-  }
-#endif
-
-  // Compile the target function.
-  DCHECK(function->shared()->allows_lazy_compilation());
-
-  Handle<Code> code;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
-                                     Compiler::GetLazyCode(function));
-  DCHECK(code->kind() == Code::FUNCTION ||
-         code->kind() == Code::OPTIMIZED_FUNCTION);
-  function->ReplaceCode(*code);
-  return *code;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CompileOptimized) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
-
-  Handle<Code> unoptimized(function->shared()->code());
-  if (!isolate->use_crankshaft() ||
-      function->shared()->optimization_disabled() ||
-      isolate->DebuggerHasBreakPoints()) {
-    // If the function is not optimizable or debugger is active continue
-    // using the code from the full compiler.
-    if (FLAG_trace_opt) {
-      PrintF("[failed to optimize ");
-      function->PrintName();
-      PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
-             function->shared()->optimization_disabled() ? "F" : "T",
-             isolate->DebuggerHasBreakPoints() ? "T" : "F");
-    }
-    function->ReplaceCode(*unoptimized);
-    return function->code();
-  }
-
-  Compiler::ConcurrencyMode mode =
-      concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
-  Handle<Code> code;
-  if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) {
-    function->ReplaceCode(*code);
-  } else {
-    function->ReplaceCode(function->shared()->code());
-  }
-
-  DCHECK(function->code()->kind() == Code::FUNCTION ||
-         function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
-         function->IsInOptimizationQueue());
-  return function->code();
-}
-
-
-class ActivationsFinder : public ThreadVisitor {
- public:
-  Code* code_;
-  bool has_code_activations_;
-
-  explicit ActivationsFinder(Code* code)
-      : code_(code), has_code_activations_(false) {}
-
-  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
-    JavaScriptFrameIterator it(isolate, top);
-    VisitFrames(&it);
-  }
-
-  void VisitFrames(JavaScriptFrameIterator* it) {
-    for (; !it->done(); it->Advance()) {
-      JavaScriptFrame* frame = it->frame();
-      if (code_->contains(frame->pc())) has_code_activations_ = true;
-    }
-  }
-};
-
-
-RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
-  DCHECK(AllowHeapAllocation::IsAllowed());
-  delete deoptimizer;
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_SMI_ARG_CHECKED(type_arg, 0);
-  Deoptimizer::BailoutType type =
-      static_cast<Deoptimizer::BailoutType>(type_arg);
-  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
-  DCHECK(AllowHeapAllocation::IsAllowed());
-
-  Handle<JSFunction> function = deoptimizer->function();
-  Handle<Code> optimized_code = deoptimizer->compiled_code();
-
-  DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
-  DCHECK(type == deoptimizer->bailout_type());
-
-  // Make sure to materialize objects before causing any allocation.
-  JavaScriptFrameIterator it(isolate);
-  deoptimizer->MaterializeHeapObjects(&it);
-  delete deoptimizer;
-
-  JavaScriptFrame* frame = it.frame();
-  RUNTIME_ASSERT(frame->function()->IsJSFunction());
-  DCHECK(frame->function() == *function);
-
-  // Avoid doing too much work when running with --always-opt and keep
-  // the optimized code around.
-  if (FLAG_always_opt || type == Deoptimizer::LAZY) {
-    return isolate->heap()->undefined_value();
-  }
-
-  // Search for other activations of the same function and code.
-  ActivationsFinder activations_finder(*optimized_code);
-  activations_finder.VisitFrames(&it);
-  isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
-
-  if (!activations_finder.has_code_activations_) {
-    if (function->code() == *optimized_code) {
-      if (FLAG_trace_deopt) {
-        PrintF("[removing optimized code for: ");
-        function->PrintName();
-        PrintF("]\n");
-      }
-      function->ReplaceCode(function->shared()->code());
-      // Evict optimized code for this function from the cache so that it
-      // doesn't get used for new closures.
-      function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
-                                                    "notify deoptimized");
-    }
-  } else {
-    // TODO(titzer): we should probably do DeoptimizeCodeList(code)
-    // unconditionally if the code is not already marked for deoptimization.
-    // If there is an index by shared function info, all the better.
-    Deoptimizer::DeoptimizeFunction(*function);
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  if (!function->IsOptimized()) return isolate->heap()->undefined_value();
-
-  // TODO(turbofan): Deoptimization is not supported yet.
-  if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
-    return isolate->heap()->undefined_value();
-  }
-
-  Deoptimizer::DeoptimizeFunction(*function);
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  function->shared()->ClearTypeFeedbackInfo();
-  Code* unoptimized = function->shared()->code();
-  if (unoptimized->kind() == Code::FUNCTION) {
-    unoptimized->ClearInlineCaches();
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-#if defined(USE_SIMULATOR)
-  return isolate->heap()->true_value();
-#else
-  return isolate->heap()->false_value();
-#endif
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  return isolate->heap()->ToBoolean(
-      isolate->concurrent_recompilation_enabled());
-}
-
-
-RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  // The following two assertions are lifted from the DCHECKs inside
-  // JSFunction::MarkForOptimization().
-  RUNTIME_ASSERT(!function->shared()->is_generator());
-  RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
-                 (function->code()->kind() == Code::FUNCTION &&
-                  function->code()->optimizable()));
-
-  // If the function is optimized, just return.
-  if (function->IsOptimized()) return isolate->heap()->undefined_value();
-
-  function->MarkForOptimization();
-
-  Code* unoptimized = function->shared()->code();
-  if (args.length() == 2 && unoptimized->kind() == Code::FUNCTION) {
-    CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
-    if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
-      // Start patching from the currently patched loop nesting level.
-      DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
-      isolate->runtime_profiler()->AttemptOnStackReplacement(
-          *function, Code::kMaxLoopNestingMarker);
-    } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
-               isolate->concurrent_recompilation_enabled()) {
-      function->MarkForConcurrentOptimization();
-    }
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, function, 0);
-  function->shared()->set_optimization_disabled(true);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
-  if (!isolate->use_crankshaft()) {
-    return Smi::FromInt(4);  // 4 == "never".
-  }
-  bool sync_with_compiler_thread = true;
-  if (args.length() == 2) {
-    CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
-    if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
-      sync_with_compiler_thread = false;
-    }
-  }
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  if (isolate->concurrent_recompilation_enabled() &&
-      sync_with_compiler_thread) {
-    while (function->IsInOptimizationQueue()) {
-      isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
-      base::OS::Sleep(50);
-    }
-  }
-  if (FLAG_always_opt) {
-    // We may have always opt, but that is more best-effort than a real
-    // promise, so we still say "no" if it is not optimized.
-    return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
-                                   : Smi::FromInt(2);  // 2 == "no".
-  }
-  if (FLAG_deopt_every_n_times) {
-    return Smi::FromInt(6);  // 6 == "maybe deopted".
-  }
-  if (function->IsOptimized() && function->code()->is_turbofanned()) {
-    return Smi::FromInt(7);  // 7 == "TurboFan compiler".
-  }
-  return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
-                                 : Smi::FromInt(2);  // 2 == "no".
-}
-
-
-RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
-  DCHECK(args.length() == 0);
-  RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
-  RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
-  isolate->optimizing_compiler_thread()->Unblock();
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  return Smi::FromInt(function->shared()->opt_count());
-}
+         !Handle<JSFunction>::cast(bound_function)->shared()->bound());
 
+  int total_argc = 0;
+  SmartArrayPointer<Handle<Object> > param_data =
+      GetCallerArguments(isolate, bound_argc, &total_argc);
+  for (int i = 0; i < bound_argc; i++) {
+    param_data[i] = Handle<Object>(
+        bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate);
+  }
 
-static bool IsSuitableForOnStackReplacement(Isolate* isolate,
-                                            Handle<JSFunction> function,
-                                            Handle<Code> current_code) {
-  // Keep track of whether we've succeeded in optimizing.
-  if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
-  // If we are trying to do OSR when there are already optimized
-  // activations of the function, it means (a) the function is directly or
-  // indirectly recursive and (b) an optimized invocation has been
-  // deoptimized so that we are currently in an unoptimized activation.
-  // Check for optimized activations of this function.
-  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
-    JavaScriptFrame* frame = it.frame();
-    if (frame->is_optimized() && frame->function() == *function) return false;
+  if (!bound_function->IsJSFunction()) {
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, bound_function,
+        Execution::TryGetConstructorDelegate(isolate, bound_function));
   }
+  DCHECK(bound_function->IsJSFunction());
 
-  return true;
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, Execution::New(Handle<JSFunction>::cast(bound_function),
+                                      total_argc, param_data.get()));
+  return *result;
 }
 
 
-RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  Handle<Code> caller_code(function->shared()->code());
-
-  // We're not prepared to handle a function with arguments object.
-  DCHECK(!function->shared()->uses_arguments());
-
-  RUNTIME_ASSERT(FLAG_use_osr);
-
-  // Passing the PC in the javascript frame from the caller directly is
-  // not GC safe, so we walk the stack to get it.
-  JavaScriptFrameIterator it(isolate);
-  JavaScriptFrame* frame = it.frame();
-  if (!caller_code->contains(frame->pc())) {
-    // Code on the stack may not be the code object referenced by the shared
-    // function info.  It may have been replaced to include deoptimization data.
-    caller_code = Handle<Code>(frame->LookupCode());
+static Object* Runtime_NewObjectHelper(Isolate* isolate,
+                                       Handle<Object> constructor,
+                                       Handle<AllocationSite> site) {
+  // If the constructor isn't a proper function we throw a type error.
+  if (!constructor->IsJSFunction()) {
+    Vector<Handle<Object> > arguments = HandleVector(&constructor, 1);
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+                                   NewTypeError("not_constructor", arguments));
   }
 
-  uint32_t pc_offset =
-      static_cast<uint32_t>(frame->pc() - caller_code->instruction_start());
+  Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
 
-#ifdef DEBUG
-  DCHECK_EQ(frame->function(), *function);
-  DCHECK_EQ(frame->LookupCode(), *caller_code);
-  DCHECK(caller_code->contains(frame->pc()));
-#endif  // DEBUG
+  // If function should not have prototype, construction is not allowed. In this
+  // case generated code bailouts here, since function has no initial_map.
+  if (!function->should_have_prototype() && !function->shared()->bound()) {
+    Vector<Handle<Object> > arguments = HandleVector(&constructor, 1);
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+                                   NewTypeError("not_constructor", arguments));
+  }
 
+  Debug* debug = isolate->debug();
+  // Handle stepping into constructors if step into is active.
+  if (debug->StepInActive()) {
+    debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
+  }
 
-  BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
-  DCHECK(!ast_id.IsNone());
-
-  Compiler::ConcurrencyMode mode =
-      isolate->concurrent_osr_enabled() &&
-              (function->shared()->ast_node_count() > 512)
-          ? Compiler::CONCURRENT
-          : Compiler::NOT_CONCURRENT;
-  Handle<Code> result = Handle<Code>::null();
-
-  OptimizedCompileJob* job = NULL;
-  if (mode == Compiler::CONCURRENT) {
-    // Gate the OSR entry with a stack check.
-    BackEdgeTable::AddStackCheck(caller_code, pc_offset);
-    // Poll already queued compilation jobs.
-    OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
-    if (thread->IsQueuedForOSR(function, ast_id)) {
-      if (FLAG_trace_osr) {
-        PrintF("[OSR - Still waiting for queued: ");
-        function->PrintName();
-        PrintF(" at AST id %d]\n", ast_id.ToInt());
-      }
-      return NULL;
+  if (function->has_initial_map()) {
+    if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
+      // The 'Function' function ignores the receiver object when
+      // called using 'new' and creates a new JSFunction object that
+      // is returned.  The receiver object is only used for error
+      // reporting if an error occurs when constructing the new
+      // JSFunction. Factory::NewJSObject() should not be used to
+      // allocate JSFunctions since it does not properly initialize
+      // the shared part of the function. Since the receiver is
+      // ignored anyway, we use the global object as the receiver
+      // instead of a new JSFunction object. This way, errors are
+      // reported the same way whether or not 'Function' is called
+      // using 'new'.
+      return isolate->global_proxy();
     }
-
-    job = thread->FindReadyOSRCandidate(function, ast_id);
   }
 
-  if (job != NULL) {
-    if (FLAG_trace_osr) {
-      PrintF("[OSR - Found ready: ");
-      function->PrintName();
-      PrintF(" at AST id %d]\n", ast_id.ToInt());
-    }
-    result = Compiler::GetConcurrentlyOptimizedCode(job);
-  } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
-    if (FLAG_trace_osr) {
-      PrintF("[OSR - Compiling: ");
-      function->PrintName();
-      PrintF(" at AST id %d]\n", ast_id.ToInt());
-    }
-    MaybeHandle<Code> maybe_result =
-        Compiler::GetOptimizedCode(function, caller_code, mode, ast_id);
-    if (maybe_result.ToHandle(&result) &&
-        result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
-      // Optimization is queued.  Return to check later.
-      return NULL;
-    }
+  // The function should be compiled for the optimization hints to be
+  // available.
+  Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
+
+  Handle<JSObject> result;
+  if (site.is_null()) {
+    result = isolate->factory()->NewJSObject(function);
+  } else {
+    result = isolate->factory()->NewJSObjectWithMemento(function, site);
   }
 
-  // Revert the patched back edge table, regardless of whether OSR succeeds.
-  BackEdgeTable::Revert(isolate, *caller_code);
+  isolate->counters()->constructed_objects()->Increment();
+  isolate->counters()->constructed_objects_runtime()->Increment();
 
-  // Check whether we ended up with usable optimized code.
-  if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
-    DeoptimizationInputData* data =
-        DeoptimizationInputData::cast(result->deoptimization_data());
+  return *result;
+}
 
-    if (data->OsrPcOffset()->value() >= 0) {
-      DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
-      if (FLAG_trace_osr) {
-        PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
-               ast_id.ToInt(), data->OsrPcOffset()->value());
-      }
-      // TODO(titzer): this is a massive hack to make the deopt counts
-      // match. Fix heuristics for reenabling optimizations!
-      function->shared()->increment_deopt_count();
 
-      // TODO(titzer): Do not install code into the function.
-      function->ReplaceCode(*result);
-      return *result;
-    }
-  }
+RUNTIME_FUNCTION(Runtime_NewObject) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
+  return Runtime_NewObjectHelper(isolate, constructor,
+                                 Handle<AllocationSite>::null());
+}
 
-  // Failed.
-  if (FLAG_trace_osr) {
-    PrintF("[OSR - Failed: ");
-    function->PrintName();
-    PrintF(" at AST id %d]\n", ast_id.ToInt());
-  }
 
-  if (!function->IsOptimized()) {
-    function->ReplaceCode(function->shared()->code());
+RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
+  Handle<AllocationSite> site;
+  if (feedback->IsAllocationSite()) {
+    // The feedback can be an AllocationSite or undefined.
+    site = Handle<AllocationSite>::cast(feedback);
   }
-  return NULL;
+  return Runtime_NewObjectHelper(isolate, constructor, site);
 }
 
 
-RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2 || args.length() == 3);
-#ifdef DEBUG
-  CONVERT_SMI_ARG_CHECKED(interval, 0);
-  CONVERT_SMI_ARG_CHECKED(timeout, 1);
-  isolate->heap()->set_allocation_timeout(timeout);
-  FLAG_gc_interval = interval;
-  if (args.length() == 3) {
-    // Enable/disable inline allocation if requested.
-    CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
-    if (inline_allocation) {
-      isolate->heap()->EnableInlineAllocation();
-    } else {
-      isolate->heap()->DisableInlineAllocation();
-    }
-  }
-#endif
+RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  function->CompleteInobjectSlackTracking();
+
   return isolate->heap()->undefined_value();
 }
 
@@ -6653,24 +4368,6 @@ RUNTIME_FUNCTION(Runtime_StackGuard) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-
-  // First check if this is a real stack overflow.
-  StackLimitCheck check(isolate);
-  if (check.JsHasOverflowed()) {
-    SealHandleScope shs(isolate);
-    return isolate->StackOverflow();
-  }
-
-  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
-  return (function->IsOptimized()) ? function->code()
-                                   : function->shared()->code();
-}
-
-
 RUNTIME_FUNCTION(Runtime_Interrupt) {
   SealHandleScope shs(isolate);
   DCHECK(args.length() == 0);
@@ -6725,45 +4422,6 @@ RUNTIME_FUNCTION(Runtime_TraceExit) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_DebugPrint) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  OFStream os(stdout);
-#ifdef DEBUG
-  if (args[0]->IsString()) {
-    // If we have a string, assume it's a code "marker"
-    // and print some interesting cpu debugging info.
-    JavaScriptFrameIterator it(isolate);
-    JavaScriptFrame* frame = it.frame();
-    os << "fp = " << frame->fp() << ", sp = " << frame->sp()
-       << ", caller_sp = " << frame->caller_sp() << ": ";
-  } else {
-    os << "DebugPrint: ";
-  }
-  args[0]->Print(os);
-  if (args[0]->IsHeapObject()) {
-    os << "\n";
-    HeapObject::cast(args[0])->map()->Print(os);
-  }
-#else
-  // ShortPrint is available in release mode. Print is not.
-  os << Brief(args[0]);
-#endif
-  os << endl;
-
-  return args[0];  // return TOS
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugTrace) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  isolate->PrintStack(stdout);
-  return isolate->heap()->undefined_value();
-}
-
-
 RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 0);
@@ -6886,114 +4544,6 @@ RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
 }
 
 
-bool CodeGenerationFromStringsAllowed(Isolate* isolate,
-                                      Handle<Context> context) {
-  DCHECK(context->allow_code_gen_from_strings()->IsFalse());
-  // Check with callback if set.
-  AllowCodeGenerationFromStringsCallback callback =
-      isolate->allow_code_gen_callback();
-  if (callback == NULL) {
-    // No callback set and code generation disallowed.
-    return false;
-  } else {
-    // Callback set. Let it decide if code generation is allowed.
-    VMState<EXTERNAL> state(isolate);
-    return callback(v8::Utils::ToLocal(context));
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_CompileString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
-  CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
-
-  // Extract native context.
-  Handle<Context> context(isolate->native_context());
-
-  // Check if native context allows code generation from
-  // strings. Throw an exception if it doesn't.
-  if (context->allow_code_gen_from_strings()->IsFalse() &&
-      !CodeGenerationFromStringsAllowed(isolate, context)) {
-    Handle<Object> error_message =
-        context->ErrorMessageForCodeGenerationFromStrings();
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewEvalError("code_gen_from_strings",
-                              HandleVector<Object>(&error_message, 1)));
-  }
-
-  // Compile source string in the native context.
-  ParseRestriction restriction = function_literal_only
-                                     ? ONLY_SINGLE_FUNCTION_LITERAL
-                                     : NO_PARSE_RESTRICTION;
-  Handle<JSFunction> fun;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, fun,
-      Compiler::GetFunctionFromEval(source, context, SLOPPY, restriction,
-                                    RelocInfo::kNoPosition));
-  return *fun;
-}
-
-
-static ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source,
-                                    Handle<Object> receiver,
-                                    StrictMode strict_mode,
-                                    int scope_position) {
-  Handle<Context> context = Handle<Context>(isolate->context());
-  Handle<Context> native_context = Handle<Context>(context->native_context());
-
-  // Check if native context allows code generation from
-  // strings. Throw an exception if it doesn't.
-  if (native_context->allow_code_gen_from_strings()->IsFalse() &&
-      !CodeGenerationFromStringsAllowed(isolate, native_context)) {
-    Handle<Object> error_message =
-        native_context->ErrorMessageForCodeGenerationFromStrings();
-    Handle<Object> error;
-    MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
-        "code_gen_from_strings", HandleVector<Object>(&error_message, 1));
-    if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
-    return MakePair(isolate->heap()->exception(), NULL);
-  }
-
-  // Deal with a normal eval call with a string argument. Compile it
-  // and return the compiled function bound in the local context.
-  static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
-  Handle<JSFunction> compiled;
-  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-      isolate, compiled,
-      Compiler::GetFunctionFromEval(source, context, strict_mode, restriction,
-                                    scope_position),
-      MakePair(isolate->heap()->exception(), NULL));
-  return MakePair(*compiled, *receiver);
-}
-
-
-RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 5);
-
-  Handle<Object> callee = args.at<Object>(0);
-
-  // If "eval" didn't refer to the original GlobalEval, it's not a
-  // direct call to eval.
-  // (And even if it is, but the first argument isn't a string, just let
-  // execution default to an indirect call to eval, which will also return
-  // the first argument without doing anything).
-  if (*callee != isolate->native_context()->global_eval_fun() ||
-      !args[1]->IsString()) {
-    return MakePair(*callee, isolate->heap()->undefined_value());
-  }
-
-  DCHECK(args[3]->IsSmi());
-  DCHECK(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
-  StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
-  DCHECK(args[4]->IsSmi());
-  return CompileGlobalEval(isolate, args.at<String>(1), args.at<Object>(2),
-                           strict_mode, args.smi_at(4));
-}
-
-
 RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 1);
@@ -7735,23 +5285,6 @@ RUNTIME_FUNCTION(Runtime_ArrayConcat) {
 }
 
 
-// This will not allocate (flatten the string), but it may run
-// very slowly for very deeply nested ConsStrings.  For debugging use only.
-RUNTIME_FUNCTION(Runtime_GlobalPrint) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(String, string, 0);
-  ConsStringIteratorOp op;
-  StringCharacterStream stream(string, &op);
-  while (stream.HasMore()) {
-    uint16_t character = stream.GetNext();
-    PrintF("%c", character);
-  }
-  return string;
-}
-
-
 // Moves all own elements of an object, that are below a limit, to positions
 // starting at zero. All undefined values are placed after non-undefined values,
 // and are followed by non-existing element. Does not change the length
@@ -10358,14 +7891,6 @@ RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_SystemBreak) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  base::OS::DebugBreak();
-  return isolate->heap()->undefined_value();
-}
-
-
 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
   HandleScope scope(isolate);
 #ifdef DEBUG
@@ -10747,18 +8272,6 @@ RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
 }
 
 
-// Sets a v8 flag.
-RUNTIME_FUNCTION(Runtime_SetFlags) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(String, arg, 0);
-  SmartArrayPointer<char> flags =
-      arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-  FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
-  return isolate->heap()->undefined_value();
-}
-
-
 // Performs a GC.
 // Presently, it only does a full GC.
 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
@@ -10921,48 +8434,6 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_Abort) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_SMI_ARG_CHECKED(message_id, 0);
-  const char* message =
-      GetBailoutReason(static_cast<BailoutReason>(message_id));
-  base::OS::PrintError("abort: %s\n", message);
-  isolate->PrintStack(stderr);
-  base::OS::Abort();
-  UNREACHABLE();
-  return NULL;
-}
-
-
-RUNTIME_FUNCTION(Runtime_AbortJS) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
-  base::OS::PrintError("abort: %s\n", message->ToCString().get());
-  isolate->PrintStack(stderr);
-  base::OS::Abort();
-  UNREACHABLE();
-  return NULL;
-}
-
-
-RUNTIME_FUNCTION(Runtime_FlattenString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
-  return *String::Flatten(str);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  isolate->heap()->NotifyContextDisposed();
-  return isolate->heap()->undefined_value();
-}
-
-
 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
   HandleScope scope(isolate);
   DCHECK(args.length() == 2);
@@ -11162,26 +8633,6 @@ RUNTIME_FUNCTION(Runtime_IS_VAR) {
 }
 
 
-#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)       \
-  RUNTIME_FUNCTION(Runtime_Has##Name) {                  \
-    CONVERT_ARG_CHECKED(JSObject, obj, 0);               \
-    return isolate->heap()->ToBoolean(obj->Has##Name()); \
-  }
-
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
-// Properties test sitting with elements tests - not fooling anyone.
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
-
-#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
-
-
 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \
   RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {                  \
     CONVERT_ARG_CHECKED(JSObject, obj, 0);                                 \
@@ -11204,15 +8655,6 @@ TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
 
 
-RUNTIME_FUNCTION(Runtime_HaveSameMap) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(JSObject, obj1, 0);
-  CONVERT_ARG_CHECKED(JSObject, obj2, 1);
-  return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
-}
-
-
 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
   SealHandleScope shs(isolate);
   DCHECK(args.length() == 1);
@@ -11270,20 +8712,6 @@ RUNTIME_FUNCTION(Runtime_GetObservationState) {
 }
 
 
-RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  // TODO(adamk): Currently this runtime function is only called three times per
-  // isolate. If it's called more often, the map should be moved into the
-  // strong root list.
-  Handle<Map> map =
-      isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
-  Handle<JSWeakMap> weakmap =
-      Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
-  return *WeakCollectionInitialize(isolate, weakmap);
-}
-
-
 static bool ContextsHaveSameOrigin(Handle<Context> context1,
                                    Handle<Context> context2) {
   return context1->security_token() == context2->security_token();
@@ -11749,22 +9177,6 @@ RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) {
 }
 
 
-RUNTIME_FUNCTION(RuntimeReference_MathPow) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_MathPowSlow(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
-  HeapNumber* number = HeapNumber::cast(obj);
-  return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
-}
-
-
 RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) {
   SealHandleScope shs(isolate);
   DCHECK(args.length() == 1);
@@ -11816,12 +9228,6 @@ RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
 }
 
 
-RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_NumberToStringRT(args, isolate);
-}
-
-
 RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
   SealHandleScope shs(isolate);
   return Smi::FromInt(isolate->debug()->is_active());
index 22a1564..ee391c3 100644 (file)
         '../../src/rewriter.h',
         '../../src/runtime-profiler.cc',
         '../../src/runtime-profiler.h',
+        '../../src/runtime/runtime-collections.cc',
+        '../../src/runtime/runtime-compiler.cc',
         '../../src/runtime/runtime-i18n.cc',
         '../../src/runtime/runtime-json.cc',
+        '../../src/runtime/runtime-maths.cc',
+        '../../src/runtime/runtime-numbers.cc',
         '../../src/runtime/runtime-regexp.cc',
         '../../src/runtime/runtime-strings.cc',
+        '../../src/runtime/runtime-test.cc',
+        '../../src/runtime/runtime-typedarray.cc',
         '../../src/runtime/runtime-uri.cc',
         '../../src/runtime/runtime-utils.h',
         '../../src/runtime/runtime.cc',