// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "v8.h"

#include "api.h"
#include "arguments.h"
#include "bootstrapper.h"
#include "builtins.h"
#include "gdb-jit.h"
#include "ic-inl.h"
#include "heap-profiler.h"
#include "mark-compact.h"
#include "stub-cache.h"
#include "vm-state-inl.h"

namespace v8 {
namespace internal {

namespace {

// Arguments object passed to C++ builtins.
template <BuiltinExtraArguments extra_args>
class BuiltinArguments : public Arguments {
 public:
  BuiltinArguments(int length, Object** arguments)
      : Arguments(length, arguments) { }

  Object*& operator[] (int index) {
    ASSERT(index < length());
    return Arguments::operator[](index);
  }

  template <class S> Handle<S> at(int index) {
    ASSERT(index < length());
    return Arguments::at<S>(index);
  }

  Handle<Object> receiver() {
    return Arguments::at<Object>(0);
  }

  Handle<JSFunction> called_function() {
    STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION);
    return Arguments::at<JSFunction>(Arguments::length() - 1);
  }

  // Gets the total number of arguments including the receiver (but
  // excluding extra arguments).
  int length() const {
    STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS);
    return Arguments::length();
  }

#ifdef DEBUG
  void Verify() {
    // Check we have at least the receiver.
    ASSERT(Arguments::length() >= 1);
  }
#endif
};


// Specialize BuiltinArguments for the called function extra argument.

template <>
int BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const {
  return Arguments::length() - 1;
}

#ifdef DEBUG
template <>
void BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() {
  // Check we have at least the receiver and the called function.
  ASSERT(Arguments::length() >= 2);
  // Make sure cast to JSFunction succeeds.
  called_function();
}
#endif


#define DEF_ARG_TYPE(name, spec)                      \
  typedef BuiltinArguments<spec> name##ArgumentsType;
BUILTIN_LIST_C(DEF_ARG_TYPE)
#undef DEF_ARG_TYPE

}  // namespace

// ----------------------------------------------------------------------------
// Support macro for defining builtins in C++.
// ----------------------------------------------------------------------------
//
// A builtin function is defined by writing:
//
//   BUILTIN(name) {
//     ...
//   }
//
// In the body of the builtin function the arguments can be accessed
// through the BuiltinArguments object args.

#ifdef DEBUG

#define BUILTIN(name)                                            \
  MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name(       \
      name##ArgumentsType args, Isolate* isolate);               \
  MUST_USE_RESULT static MaybeObject* Builtin_##name(            \
      int args_length, Object** args_object, Isolate* isolate) { \
    name##ArgumentsType args(args_length, args_object);          \
    ASSERT(isolate == Isolate::Current());                       \
    args.Verify();                                               \
    return Builtin_Impl_##name(args, isolate);                   \
  }                                                              \
  MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name(       \
      name##ArgumentsType args, Isolate* isolate)

#else  // For release mode.

#define BUILTIN(name)                                            \
  static MaybeObject* Builtin_impl##name(                        \
      name##ArgumentsType args, Isolate* isolate);               \
  static MaybeObject* Builtin_##name(                            \
      int args_length, Object** args_object, Isolate* isolate) { \
    name##ArgumentsType args(args_length, args_object);          \
    return Builtin_impl##name(args, isolate);                    \
  }                                                              \
  static MaybeObject* Builtin_impl##name(                        \
      name##ArgumentsType args, Isolate* isolate)
#endif


static inline bool CalledAsConstructor(Isolate* isolate) {
#ifdef DEBUG
  // Calculate the result using a full stack frame iterator and check
  // that the state of the stack is as we assume it to be in the
  // code below.
  StackFrameIterator it(isolate);
  ASSERT(it.frame()->is_exit());
  it.Advance();
  StackFrame* frame = it.frame();
  bool reference_result = frame->is_construct();
#endif
  Address fp = Isolate::c_entry_fp(isolate->thread_local_top());
  // Because we know fp points to an exit frame we can use the relevant
  // part of ExitFrame::ComputeCallerState directly.
  const int kCallerOffset = ExitFrameConstants::kCallerFPOffset;
  Address caller_fp = Memory::Address_at(fp + kCallerOffset);
  // This inlines the part of StackFrame::ComputeType that grabs the
  // type of the current frame.  Note that StackFrame::ComputeType
  // has been specialized for each architecture so if any one of them
  // changes this code has to be changed as well.
  const int kMarkerOffset = StandardFrameConstants::kMarkerOffset;
  const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT);
  Object* marker = Memory::Object_at(caller_fp + kMarkerOffset);
  bool result = (marker == kConstructMarker);
  ASSERT_EQ(result, reference_result);
  return result;
}

// ----------------------------------------------------------------------------

BUILTIN(Illegal) {
  UNREACHABLE();
  return isolate->heap()->undefined_value();  // Make compiler happy.
}


BUILTIN(EmptyFunction) {
  return isolate->heap()->undefined_value();
}


static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
                                           Isolate* isolate,
                                           JSFunction* constructor) {
  ASSERT(args->length() >= 1);
  Heap* heap = isolate->heap();
  isolate->counters()->array_function_runtime()->Increment();

  JSArray* array;
  if (CalledAsConstructor(isolate)) {
    array = JSArray::cast((*args)[0]);
    // Initialize elements and length in case later allocations fail so that the
    // array object is initialized in a valid state.
    MaybeObject* maybe_array = array->Initialize(0);
    if (maybe_array->IsFailure()) return maybe_array;

    AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(array);
    ElementsKind to_kind = array->GetElementsKind();
    if (info != NULL && info->GetElementsKindPayload(&to_kind)) {
      if (IsMoreGeneralElementsKindTransition(array->GetElementsKind(),
                                              to_kind)) {
        // We have advice that we should change the elements kind
        if (FLAG_trace_track_allocation_sites) {
          PrintF("AllocationSiteInfo: pre-transitioning array %p(%s->%s)\n",
                 reinterpret_cast<void*>(array),
                 ElementsKindToString(array->GetElementsKind()),
                 ElementsKindToString(to_kind));
        }

        maybe_array = array->TransitionElementsKind(to_kind);
        if (maybe_array->IsFailure()) return maybe_array;
      }
    }

    if (!FLAG_smi_only_arrays) {
      Context* native_context = isolate->context()->native_context();
      if (array->GetElementsKind() == GetInitialFastElementsKind() &&
          !native_context->js_array_maps()->IsUndefined()) {
        FixedArray* map_array =
            FixedArray::cast(native_context->js_array_maps());
        array->set_map(Map::cast(map_array->
                                 get(TERMINAL_FAST_ELEMENTS_KIND)));
      }
    }
  } else {
    // Allocate the JS Array
    MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
    if (!maybe_obj->To(&array)) return maybe_obj;
  }

  Arguments adjusted_arguments(args->length() - 1, args->arguments() - 1);
  ASSERT(adjusted_arguments.length() < 1 ||
         adjusted_arguments[0] == (*args)[1]);
  return ArrayConstructInitializeElements(array, &adjusted_arguments);
}


BUILTIN(InternalArrayCodeGeneric) {
  return ArrayCodeGenericCommon(
      &args,
      isolate,
      isolate->context()->native_context()->internal_array_function());
}


BUILTIN(ArrayCodeGeneric) {
  return ArrayCodeGenericCommon(
      &args,
      isolate,
      isolate->context()->native_context()->array_function());
}


static void MoveDoubleElements(FixedDoubleArray* dst,
                               int dst_index,
                               FixedDoubleArray* src,
                               int src_index,
                               int len) {
  if (len == 0) return;
  OS::MemMove(dst->data_start() + dst_index,
              src->data_start() + src_index,
              len * kDoubleSize);
}


static void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
  ASSERT(dst->map() != heap->fixed_cow_array_map());
  MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
}


static void FillWithHoles(FixedDoubleArray* dst, int from, int to) {
  for (int i = from; i < to; i++) {
    dst->set_the_hole(i);
  }
}


static FixedArrayBase* LeftTrimFixedArray(Heap* heap,
                                          FixedArrayBase* elms,
                                          int to_trim) {
  Map* map = elms->map();
  int entry_size;
  if (elms->IsFixedArray()) {
    entry_size = kPointerSize;
  } else {
    entry_size = kDoubleSize;
  }
  ASSERT(elms->map() != HEAP->fixed_cow_array_map());
  // For now this trick is only applied to fixed arrays in new and paged space.
  // In large object space the object's start must coincide with chunk
  // and thus the trick is just not applicable.
  ASSERT(!HEAP->lo_space()->Contains(elms));

  STATIC_ASSERT(FixedArrayBase::kMapOffset == 0);
  STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize);
  STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize);

  Object** former_start = HeapObject::RawField(elms, 0);

  const int len = elms->length();

  if (to_trim * entry_size > FixedArrayBase::kHeaderSize &&
      elms->IsFixedArray() &&
      !heap->new_space()->Contains(elms)) {
    // If we are doing a big trim in old space then we zap the space that was
    // formerly part of the array so that the GC (aided by the card-based
    // remembered set) won't find pointers to new-space there.
    Object** zap = reinterpret_cast<Object**>(elms->address());
    zap++;  // Header of filler must be at least one word so skip that.
    for (int i = 1; i < to_trim; i++) {
      *zap++ = Smi::FromInt(0);
    }
  }
  // Technically in new space this write might be omitted (except for
  // debug mode which iterates through the heap), but to play safer
  // we still do it.
  heap->CreateFillerObjectAt(elms->address(), to_trim * entry_size);

  int new_start_index = to_trim * (entry_size / kPointerSize);
  former_start[new_start_index] = map;
  former_start[new_start_index + 1] = Smi::FromInt(len - to_trim);

  // Maintain marking consistency for HeapObjectIterator and
  // IncrementalMarking.
  int size_delta = to_trim * entry_size;
  if (heap->marking()->TransferMark(elms->address(),
                                    elms->address() + size_delta)) {
    MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
  }

  HEAP_PROFILE(heap, ObjectMoveEvent(elms->address(),
                                     elms->address() + size_delta));
  return FixedArrayBase::cast(HeapObject::FromAddress(
      elms->address() + to_trim * entry_size));
}


static bool ArrayPrototypeHasNoElements(Heap* heap,
                                        Context* native_context,
                                        JSObject* array_proto) {
  // This method depends on non writability of Object and Array prototype
  // fields.
  if (array_proto->elements() != heap->empty_fixed_array()) return false;
  // Object.prototype
  Object* proto = array_proto->GetPrototype();
  if (proto == heap->null_value()) return false;
  array_proto = JSObject::cast(proto);
  if (array_proto != native_context->initial_object_prototype()) return false;
  if (array_proto->elements() != heap->empty_fixed_array()) return false;
  return array_proto->GetPrototype()->IsNull();
}


MUST_USE_RESULT
static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
    Heap* heap, Object* receiver, Arguments* args, int first_added_arg) {
  if (!receiver->IsJSArray()) return NULL;
  JSArray* array = JSArray::cast(receiver);
  HeapObject* elms = array->elements();
  Map* map = elms->map();
  if (map == heap->fixed_array_map()) {
    if (args == NULL || array->HasFastObjectElements()) return elms;
  } else if (map == heap->fixed_cow_array_map()) {
    MaybeObject* maybe_writable_result = array->EnsureWritableFastElements();
    if (args == NULL || array->HasFastObjectElements() ||
        !maybe_writable_result->To(&elms)) {
      return maybe_writable_result;
    }
  } else if (map == heap->fixed_double_array_map()) {
    if (args == NULL) return elms;
  } else {
    return NULL;
  }

  // Need to ensure that the arguments passed in args can be contained in
  // the array.
  int args_length = args->length();
  if (first_added_arg >= args_length) return array->elements();

  ElementsKind origin_kind = array->map()->elements_kind();
  ASSERT(!IsFastObjectElementsKind(origin_kind));
  ElementsKind target_kind = origin_kind;
  int arg_count = args->length() - first_added_arg;
  Object** arguments = args->arguments() - first_added_arg - (arg_count - 1);
  for (int i = 0; i < arg_count; i++) {
    Object* arg = arguments[i];
    if (arg->IsHeapObject()) {
      if (arg->IsHeapNumber()) {
        target_kind = FAST_DOUBLE_ELEMENTS;
      } else {
        target_kind = FAST_ELEMENTS;
        break;
      }
    }
  }
  if (target_kind != origin_kind) {
    MaybeObject* maybe_failure = array->TransitionElementsKind(target_kind);
    if (maybe_failure->IsFailure()) return maybe_failure;
    return array->elements();
  }
  return elms;
}


static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
                                                     JSArray* receiver) {
  if (!FLAG_clever_optimizations) return false;
  Context* native_context = heap->isolate()->context()->native_context();
  JSObject* array_proto =
      JSObject::cast(native_context->array_function()->prototype());
  return receiver->GetPrototype() == array_proto &&
         ArrayPrototypeHasNoElements(heap, native_context, array_proto);
}


MUST_USE_RESULT static MaybeObject* CallJsBuiltin(
    Isolate* isolate,
    const char* name,
    BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
  HandleScope handleScope(isolate);

  Handle<Object> js_builtin =
      GetProperty(Handle<JSObject>(isolate->native_context()->builtins()),
                  name);
  Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin);
  int argc = args.length() - 1;
  ScopedVector<Handle<Object> > argv(argc);
  for (int i = 0; i < argc; ++i) {
    argv[i] = args.at<Object>(i + 1);
  }
  bool pending_exception;
  Handle<Object> result = Execution::Call(function,
                                          args.receiver(),
                                          argc,
                                          argv.start(),
                                          &pending_exception);
  if (pending_exception) return Failure::Exception();
  return *result;
}


BUILTIN(ArrayPush) {
  Heap* heap = isolate->heap();
  Object* receiver = *args.receiver();
  FixedArrayBase* elms_obj;
  MaybeObject* maybe_elms_obj =
      EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 1);
  if (maybe_elms_obj == NULL) {
    return CallJsBuiltin(isolate, "ArrayPush", args);
  }
  if (!maybe_elms_obj->To(&elms_obj)) return maybe_elms_obj;

  JSArray* array = JSArray::cast(receiver);
  ASSERT(!array->map()->is_observed());

  ElementsKind kind = array->GetElementsKind();

  if (IsFastSmiOrObjectElementsKind(kind)) {
    FixedArray* elms = FixedArray::cast(elms_obj);

    int len = Smi::cast(array->length())->value();
    int to_add = args.length() - 1;
    if (to_add == 0) {
      return Smi::FromInt(len);
    }
    // Currently fixed arrays cannot grow too big, so
    // we should never hit this case.
    ASSERT(to_add <= (Smi::kMaxValue - len));

    int new_length = len + to_add;

    if (new_length > elms->length()) {
      // New backing storage is needed.
      int capacity = new_length + (new_length >> 1) + 16;
      FixedArray* new_elms;
      MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
      if (!maybe_obj->To(&new_elms)) return maybe_obj;

      ElementsAccessor* accessor = array->GetElementsAccessor();
      MaybeObject* maybe_failure = accessor->CopyElements(
           NULL, 0, kind, new_elms, 0,
           ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
      ASSERT(!maybe_failure->IsFailure());
      USE(maybe_failure);

      elms = new_elms;
    }

    // Add the provided values.
    DisallowHeapAllocation no_gc;
    WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
    for (int index = 0; index < to_add; index++) {
      elms->set(index + len, args[index + 1], mode);
    }

    if (elms != array->elements()) {
      array->set_elements(elms);
    }

    // Set the length.
    array->set_length(Smi::FromInt(new_length));
    return Smi::FromInt(new_length);
  } else {
    int len = Smi::cast(array->length())->value();
    int elms_len = elms_obj->length();

    int to_add = args.length() - 1;
    if (to_add == 0) {
      return Smi::FromInt(len);
    }
    // Currently fixed arrays cannot grow too big, so
    // we should never hit this case.
    ASSERT(to_add <= (Smi::kMaxValue - len));

    int new_length = len + to_add;

    FixedDoubleArray* new_elms;

    if (new_length > elms_len) {
      // New backing storage is needed.
      int capacity = new_length + (new_length >> 1) + 16;
      MaybeObject* maybe_obj =
          heap->AllocateUninitializedFixedDoubleArray(capacity);
      if (!maybe_obj->To(&new_elms)) return maybe_obj;

      ElementsAccessor* accessor = array->GetElementsAccessor();
      MaybeObject* maybe_failure = accessor->CopyElements(
              NULL, 0, kind, new_elms, 0,
              ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
      ASSERT(!maybe_failure->IsFailure());
      USE(maybe_failure);
    } else {
      // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the
      // empty_fixed_array.
      new_elms = FixedDoubleArray::cast(elms_obj);
    }

    // Add the provided values.
    DisallowHeapAllocation no_gc;
    int index;
    for (index = 0; index < to_add; index++) {
      Object* arg = args[index + 1];
      new_elms->set(index + len, arg->Number());
    }

    if (new_elms != array->elements()) {
      array->set_elements(new_elms);
    }

    // Set the length.
    array->set_length(Smi::FromInt(new_length));
    return Smi::FromInt(new_length);
  }
}


BUILTIN(ArrayPop) {
  Heap* heap = isolate->heap();
  Object* receiver = *args.receiver();
  FixedArrayBase* elms_obj;
  MaybeObject* maybe_elms =
      EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
  if (maybe_elms == NULL) return CallJsBuiltin(isolate, "ArrayPop", args);
  if (!maybe_elms->To(&elms_obj)) return maybe_elms;

  JSArray* array = JSArray::cast(receiver);
  ASSERT(!array->map()->is_observed());

  int len = Smi::cast(array->length())->value();
  if (len == 0) return heap->undefined_value();

  ElementsAccessor* accessor = array->GetElementsAccessor();
  int new_length = len - 1;
  MaybeObject* maybe_result;
  if (accessor->HasElement(array, array, new_length, elms_obj)) {
    maybe_result = accessor->Get(array, array, new_length, elms_obj);
  } else {
    maybe_result = array->GetPrototype()->GetElement(len - 1);
  }
  if (maybe_result->IsFailure()) return maybe_result;
  MaybeObject* maybe_failure =
      accessor->SetLength(array, Smi::FromInt(new_length));
  if (maybe_failure->IsFailure()) return maybe_failure;
  return maybe_result;
}


BUILTIN(ArrayShift) {
  Heap* heap = isolate->heap();
  Object* receiver = *args.receiver();
  FixedArrayBase* elms_obj;
  MaybeObject* maybe_elms_obj =
      EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
  if (maybe_elms_obj == NULL)
      return CallJsBuiltin(isolate, "ArrayShift", args);
  if (!maybe_elms_obj->To(&elms_obj)) return maybe_elms_obj;

  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
    return CallJsBuiltin(isolate, "ArrayShift", args);
  }
  JSArray* array = JSArray::cast(receiver);
  ASSERT(!array->map()->is_observed());

  int len = Smi::cast(array->length())->value();
  if (len == 0) return heap->undefined_value();

  // Get first element
  ElementsAccessor* accessor = array->GetElementsAccessor();
  Object* first;
  MaybeObject* maybe_first = accessor->Get(receiver, array, 0, elms_obj);
  if (!maybe_first->To(&first)) return maybe_first;
  if (first->IsTheHole()) {
    first = heap->undefined_value();
  }

  if (!heap->lo_space()->Contains(elms_obj)) {
    array->set_elements(LeftTrimFixedArray(heap, elms_obj, 1));
  } else {
    // Shift the elements.
    if (elms_obj->IsFixedArray()) {
      FixedArray* elms = FixedArray::cast(elms_obj);
      DisallowHeapAllocation no_gc;
      heap->MoveElements(elms, 0, 1, len - 1);
      elms->set(len - 1, heap->the_hole_value());
    } else {
      FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
      MoveDoubleElements(elms, 0, elms, 1, len - 1);
      elms->set_the_hole(len - 1);
    }
  }

  // Set the length.
  array->set_length(Smi::FromInt(len - 1));

  return first;
}


BUILTIN(ArrayUnshift) {
  Heap* heap = isolate->heap();
  Object* receiver = *args.receiver();
  FixedArrayBase* elms_obj;
  MaybeObject* maybe_elms_obj =
      EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
  if (maybe_elms_obj == NULL)
      return CallJsBuiltin(isolate, "ArrayUnshift", args);
  if (!maybe_elms_obj->To(&elms_obj)) return maybe_elms_obj;

  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
    return CallJsBuiltin(isolate, "ArrayUnshift", args);
  }
  JSArray* array = JSArray::cast(receiver);
  ASSERT(!array->map()->is_observed());
  if (!array->HasFastSmiOrObjectElements()) {
    return CallJsBuiltin(isolate, "ArrayUnshift", args);
  }
  FixedArray* elms = FixedArray::cast(elms_obj);

  int len = Smi::cast(array->length())->value();
  int to_add = args.length() - 1;
  int new_length = len + to_add;
  // Currently fixed arrays cannot grow too big, so
  // we should never hit this case.
  ASSERT(to_add <= (Smi::kMaxValue - len));

  MaybeObject* maybe_object =
      array->EnsureCanContainElements(&args, 1, to_add,
                                      DONT_ALLOW_DOUBLE_ELEMENTS);
  if (maybe_object->IsFailure()) return maybe_object;

  if (new_length > elms->length()) {
    // New backing storage is needed.
    int capacity = new_length + (new_length >> 1) + 16;
    FixedArray* new_elms;
    MaybeObject* maybe_elms = heap->AllocateUninitializedFixedArray(capacity);
    if (!maybe_elms->To(&new_elms)) return maybe_elms;

    ElementsKind kind = array->GetElementsKind();
    ElementsAccessor* accessor = array->GetElementsAccessor();
    MaybeObject* maybe_failure = accessor->CopyElements(
            NULL, 0, kind, new_elms, to_add,
            ElementsAccessor::kCopyToEndAndInitializeToHole, elms);
    ASSERT(!maybe_failure->IsFailure());
    USE(maybe_failure);

    elms = new_elms;
    array->set_elements(elms);
  } else {
    DisallowHeapAllocation no_gc;
    heap->MoveElements(elms, to_add, 0, len);
  }

  // Add the provided values.
  DisallowHeapAllocation no_gc;
  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
  for (int i = 0; i < to_add; i++) {
    elms->set(i, args[i + 1], mode);
  }

  // Set the length.
  array->set_length(Smi::FromInt(new_length));
  return Smi::FromInt(new_length);
}


BUILTIN(ArraySlice) {
  Heap* heap = isolate->heap();
  Object* receiver = *args.receiver();
  FixedArrayBase* elms;
  int len = -1;
  if (receiver->IsJSArray()) {
    JSArray* array = JSArray::cast(receiver);
    if (!IsJSArrayFastElementMovingAllowed(heap, array)) {
      return CallJsBuiltin(isolate, "ArraySlice", args);
    }

    if (array->HasFastElements()) {
      elms = array->elements();
    } else {
      return CallJsBuiltin(isolate, "ArraySlice", args);
    }

    len = Smi::cast(array->length())->value();
  } else {
    // Array.slice(arguments, ...) is quite a common idiom (notably more
    // than 50% of invocations in Web apps).  Treat it in C++ as well.
    Map* arguments_map =
        isolate->context()->native_context()->arguments_boilerplate()->map();

    bool is_arguments_object_with_fast_elements =
        receiver->IsJSObject() &&
        JSObject::cast(receiver)->map() == arguments_map;
    if (!is_arguments_object_with_fast_elements) {
      return CallJsBuiltin(isolate, "ArraySlice", args);
    }
    JSObject* object = JSObject::cast(receiver);

    if (object->HasFastElements()) {
      elms = object->elements();
    } else {
      return CallJsBuiltin(isolate, "ArraySlice", args);
    }
    Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
    if (!len_obj->IsSmi()) {
      return CallJsBuiltin(isolate, "ArraySlice", args);
    }
    len = Smi::cast(len_obj)->value();
    if (len > elms->length()) {
      return CallJsBuiltin(isolate, "ArraySlice", args);
    }
  }

  JSObject* object = JSObject::cast(receiver);

  ASSERT(len >= 0);
  int n_arguments = args.length() - 1;

  // Note carefully choosen defaults---if argument is missing,
  // it's undefined which gets converted to 0 for relative_start
  // and to len for relative_end.
  int relative_start = 0;
  int relative_end = len;
  if (n_arguments > 0) {
    Object* arg1 = args[1];
    if (arg1->IsSmi()) {
      relative_start = Smi::cast(arg1)->value();
    } else if (arg1->IsHeapNumber()) {
      double start = HeapNumber::cast(arg1)->value();
      if (start < kMinInt || start > kMaxInt) {
        return CallJsBuiltin(isolate, "ArraySlice", args);
      }
      relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
    } else if (!arg1->IsUndefined()) {
      return CallJsBuiltin(isolate, "ArraySlice", args);
    }
    if (n_arguments > 1) {
      Object* arg2 = args[2];
      if (arg2->IsSmi()) {
        relative_end = Smi::cast(arg2)->value();
      } else if (arg2->IsHeapNumber()) {
        double end = HeapNumber::cast(arg2)->value();
        if (end < kMinInt || end > kMaxInt) {
          return CallJsBuiltin(isolate, "ArraySlice", args);
        }
        relative_end = std::isnan(end) ? 0 : static_cast<int>(end);
      } else if (!arg2->IsUndefined()) {
        return CallJsBuiltin(isolate, "ArraySlice", args);
      }
    }
  }

  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
  int k = (relative_start < 0) ? Max(len + relative_start, 0)
                               : Min(relative_start, len);

  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
  int final = (relative_end < 0) ? Max(len + relative_end, 0)
                                 : Min(relative_end, len);

  // Calculate the length of result array.
  int result_len = Max(final - k, 0);

  ElementsKind kind = object->GetElementsKind();
  if (IsHoleyElementsKind(kind)) {
    bool packed = true;
    ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
    for (int i = k; i < final; i++) {
      if (!accessor->HasElement(object, object, i, elms)) {
        packed = false;
        break;
      }
    }
    if (packed) {
      kind = GetPackedElementsKind(kind);
    } else if (!receiver->IsJSArray()) {
      return CallJsBuiltin(isolate, "ArraySlice", args);
    }
  }

  JSArray* result_array;
  MaybeObject* maybe_array = heap->AllocateJSArrayAndStorage(kind,
                                                             result_len,
                                                             result_len);

  DisallowHeapAllocation no_gc;
  if (result_len == 0) return maybe_array;
  if (!maybe_array->To(&result_array)) return maybe_array;

  ElementsAccessor* accessor = object->GetElementsAccessor();
  MaybeObject* maybe_failure = accessor->CopyElements(
      NULL, k, kind, result_array->elements(), 0, result_len, elms);
  ASSERT(!maybe_failure->IsFailure());
  USE(maybe_failure);

  return result_array;
}


BUILTIN(ArraySplice) {
  Heap* heap = isolate->heap();
  Object* receiver = *args.receiver();
  FixedArrayBase* elms_obj;
  MaybeObject* maybe_elms =
      EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3);
  if (maybe_elms == NULL) {
    return CallJsBuiltin(isolate, "ArraySplice", args);
  }
  if (!maybe_elms->To(&elms_obj)) return maybe_elms;

  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
    return CallJsBuiltin(isolate, "ArraySplice", args);
  }
  JSArray* array = JSArray::cast(receiver);
  ASSERT(!array->map()->is_observed());

  int len = Smi::cast(array->length())->value();

  int n_arguments = args.length() - 1;

  int relative_start = 0;
  if (n_arguments > 0) {
    Object* arg1 = args[1];
    if (arg1->IsSmi()) {
      relative_start = Smi::cast(arg1)->value();
    } else if (arg1->IsHeapNumber()) {
      double start = HeapNumber::cast(arg1)->value();
      if (start < kMinInt || start > kMaxInt) {
        return CallJsBuiltin(isolate, "ArraySplice", args);
      }
      relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
    } else if (!arg1->IsUndefined()) {
      return CallJsBuiltin(isolate, "ArraySplice", args);
    }
  }
  int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
                                          : Min(relative_start, len);

  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
  // given as a request to delete all the elements from the start.
  // And it differs from the case of undefined delete count.
  // This does not follow ECMA-262, but we do the same for
  // compatibility.
  int actual_delete_count;
  if (n_arguments == 1) {
    ASSERT(len - actual_start >= 0);
    actual_delete_count = len - actual_start;
  } else {
    int value = 0;  // ToInteger(undefined) == 0
    if (n_arguments > 1) {
      Object* arg2 = args[2];
      if (arg2->IsSmi()) {
        value = Smi::cast(arg2)->value();
      } else {
        return CallJsBuiltin(isolate, "ArraySplice", args);
      }
    }
    actual_delete_count = Min(Max(value, 0), len - actual_start);
  }

  ElementsKind elements_kind = array->GetElementsKind();

  int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
  int new_length = len - actual_delete_count + item_count;

  // For double mode we do not support changing the length.
  if (new_length > len && IsFastDoubleElementsKind(elements_kind)) {
    return CallJsBuiltin(isolate, "ArraySplice", args);
  }

  if (new_length == 0) {
    MaybeObject* maybe_array = heap->AllocateJSArrayWithElements(
        elms_obj, elements_kind, actual_delete_count);
    if (maybe_array->IsFailure()) return maybe_array;
    array->set_elements(heap->empty_fixed_array());
    array->set_length(Smi::FromInt(0));
    return maybe_array;
  }

  JSArray* result_array = NULL;
  MaybeObject* maybe_array =
      heap->AllocateJSArrayAndStorage(elements_kind,
                                      actual_delete_count,
                                      actual_delete_count);
  if (!maybe_array->To(&result_array)) return maybe_array;

  if (actual_delete_count > 0) {
    DisallowHeapAllocation no_gc;
    ElementsAccessor* accessor = array->GetElementsAccessor();
    MaybeObject* maybe_failure = accessor->CopyElements(
        NULL, actual_start, elements_kind, result_array->elements(),
        0, actual_delete_count, elms_obj);
    // Cannot fail since the origin and target array are of the same elements
    // kind.
    ASSERT(!maybe_failure->IsFailure());
    USE(maybe_failure);
  }

  bool elms_changed = false;
  if (item_count < actual_delete_count) {
    // Shrink the array.
    const bool trim_array = !heap->lo_space()->Contains(elms_obj) &&
      ((actual_start + item_count) <
          (len - actual_delete_count - actual_start));
    if (trim_array) {
      const int delta = actual_delete_count - item_count;

      if (elms_obj->IsFixedDoubleArray()) {
        FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
        MoveDoubleElements(elms, delta, elms, 0, actual_start);
      } else {
        FixedArray* elms = FixedArray::cast(elms_obj);
        DisallowHeapAllocation no_gc;
        heap->MoveElements(elms, delta, 0, actual_start);
      }

      elms_obj = LeftTrimFixedArray(heap, elms_obj, delta);

      elms_changed = true;
    } else {
      if (elms_obj->IsFixedDoubleArray()) {
        FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
        MoveDoubleElements(elms, actual_start + item_count,
                           elms, actual_start + actual_delete_count,
                           (len - actual_delete_count - actual_start));
        FillWithHoles(elms, new_length, len);
      } else {
        FixedArray* elms = FixedArray::cast(elms_obj);
        DisallowHeapAllocation no_gc;
        heap->MoveElements(elms, actual_start + item_count,
                           actual_start + actual_delete_count,
                           (len - actual_delete_count - actual_start));
        FillWithHoles(heap, elms, new_length, len);
      }
    }
  } else if (item_count > actual_delete_count) {
    FixedArray* elms = FixedArray::cast(elms_obj);
    // Currently fixed arrays cannot grow too big, so
    // we should never hit this case.
    ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len));

    // Check if array need to grow.
    if (new_length > elms->length()) {
      // New backing storage is needed.
      int capacity = new_length + (new_length >> 1) + 16;
      FixedArray* new_elms;
      MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
      if (!maybe_obj->To(&new_elms)) return maybe_obj;

      DisallowHeapAllocation no_gc;

      ElementsKind kind = array->GetElementsKind();
      ElementsAccessor* accessor = array->GetElementsAccessor();
      if (actual_start > 0) {
        // Copy the part before actual_start as is.
        MaybeObject* maybe_failure = accessor->CopyElements(
            NULL, 0, kind, new_elms, 0, actual_start, elms);
        ASSERT(!maybe_failure->IsFailure());
        USE(maybe_failure);
      }
      MaybeObject* maybe_failure = accessor->CopyElements(
          NULL, actual_start + actual_delete_count, kind, new_elms,
          actual_start + item_count,
          ElementsAccessor::kCopyToEndAndInitializeToHole, elms);
      ASSERT(!maybe_failure->IsFailure());
      USE(maybe_failure);

      elms_obj = new_elms;
      elms_changed = true;
    } else {
      DisallowHeapAllocation no_gc;
      heap->MoveElements(elms, actual_start + item_count,
                         actual_start + actual_delete_count,
                         (len - actual_delete_count - actual_start));
    }
  }

  if (IsFastDoubleElementsKind(elements_kind)) {
    FixedDoubleArray* elms = FixedDoubleArray::cast(elms_obj);
    for (int k = actual_start; k < actual_start + item_count; k++) {
      Object* arg = args[3 + k - actual_start];
      if (arg->IsSmi()) {
        elms->set(k, Smi::cast(arg)->value());
      } else {
        elms->set(k, HeapNumber::cast(arg)->value());
      }
    }
  } else {
    FixedArray* elms = FixedArray::cast(elms_obj);
    DisallowHeapAllocation no_gc;
    WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
    for (int k = actual_start; k < actual_start + item_count; k++) {
      elms->set(k, args[3 + k - actual_start], mode);
    }
  }

  if (elms_changed) {
    array->set_elements(elms_obj);
  }
  // Set the length.
  array->set_length(Smi::FromInt(new_length));

  return result_array;
}


BUILTIN(ArrayConcat) {
  Heap* heap = isolate->heap();
  Context* native_context = isolate->context()->native_context();
  JSObject* array_proto =
      JSObject::cast(native_context->array_function()->prototype());
  if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) {
    return CallJsBuiltin(isolate, "ArrayConcat", args);
  }

  // Iterate through all the arguments performing checks
  // and calculating total length.
  int n_arguments = args.length();
  int result_len = 0;
  ElementsKind elements_kind = GetInitialFastElementsKind();
  bool has_double = false;
  bool is_holey = false;
  for (int i = 0; i < n_arguments; i++) {
    Object* arg = args[i];
    if (!arg->IsJSArray() ||
        !JSArray::cast(arg)->HasFastElements() ||
        JSArray::cast(arg)->GetPrototype() != array_proto) {
      return CallJsBuiltin(isolate, "ArrayConcat", args);
    }
    int len = Smi::cast(JSArray::cast(arg)->length())->value();

    // We shouldn't overflow when adding another len.
    const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
    STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
    USE(kHalfOfMaxInt);
    result_len += len;
    ASSERT(result_len >= 0);

    if (result_len > FixedDoubleArray::kMaxLength) {
      return CallJsBuiltin(isolate, "ArrayConcat", args);
    }

    ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind();
    has_double = has_double || IsFastDoubleElementsKind(arg_kind);
    is_holey = is_holey || IsFastHoleyElementsKind(arg_kind);
    if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) {
      elements_kind = arg_kind;
    }
  }

  if (is_holey) elements_kind = GetHoleyElementsKind(elements_kind);

  // If a double array is concatted into a fast elements array, the fast
  // elements array needs to be initialized to contain proper holes, since
  // boxing doubles may cause incremental marking.
  ArrayStorageAllocationMode mode =
      has_double && IsFastObjectElementsKind(elements_kind)
      ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS;
  JSArray* result_array;
  // Allocate result.
  MaybeObject* maybe_array =
      heap->AllocateJSArrayAndStorage(elements_kind,
                                      result_len,
                                      result_len,
                                      mode);
  if (!maybe_array->To(&result_array)) return maybe_array;
  if (result_len == 0) return result_array;

  int j = 0;
  FixedArrayBase* storage = result_array->elements();
  ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
  for (int i = 0; i < n_arguments; i++) {
    JSArray* array = JSArray::cast(args[i]);
    int len = Smi::cast(array->length())->value();
    ElementsKind from_kind = array->GetElementsKind();
    if (len > 0) {
      MaybeObject* maybe_failure =
          accessor->CopyElements(array, 0, from_kind, storage, j, len);
      if (maybe_failure->IsFailure()) return maybe_failure;
      j += len;
    }
  }

  ASSERT(j == result_len);

  return result_array;
}


// -----------------------------------------------------------------------------
// Strict mode poison pills


BUILTIN(StrictModePoisonPill) {
  HandleScope scope(isolate);
  return isolate->Throw(*isolate->factory()->NewTypeError(
      "strict_poison_pill", HandleVector<Object>(NULL, 0)));
}

// -----------------------------------------------------------------------------
//


// Searches the hidden prototype chain of the given object for the first
// object that is an instance of the given type.  If no such object can
// be found then Heap::null_value() is returned.
static inline Object* FindHidden(Heap* heap,
                                 Object* object,
                                 FunctionTemplateInfo* type) {
  if (object->IsInstanceOf(type)) return object;
  Object* proto = object->GetPrototype(heap->isolate());
  if (proto->IsJSObject() &&
      JSObject::cast(proto)->map()->is_hidden_prototype()) {
    return FindHidden(heap, proto, type);
  }
  return heap->null_value();
}


// Returns the holder JSObject if the function can legally be called
// with this receiver.  Returns Heap::null_value() if the call is
// illegal.  Any arguments that don't fit the expected type is
// overwritten with undefined.  Note that holder and the arguments are
// implicitly rewritten with the first object in the hidden prototype
// chain that actually has the expected type.
static inline Object* TypeCheck(Heap* heap,
                                int argc,
                                Object** argv,
                                FunctionTemplateInfo* info) {
  Object* recv = argv[0];
  // API calls are only supported with JSObject receivers.
  if (!recv->IsJSObject()) return heap->null_value();
  Object* sig_obj = info->signature();
  if (sig_obj->IsUndefined()) return recv;
  SignatureInfo* sig = SignatureInfo::cast(sig_obj);
  // If necessary, check the receiver
  Object* recv_type = sig->receiver();
  Object* holder = recv;
  if (!recv_type->IsUndefined()) {
    holder = FindHidden(heap, holder, FunctionTemplateInfo::cast(recv_type));
    if (holder == heap->null_value()) return heap->null_value();
  }
  Object* args_obj = sig->args();
  // If there is no argument signature we're done
  if (args_obj->IsUndefined()) return holder;
  FixedArray* args = FixedArray::cast(args_obj);
  int length = args->length();
  if (argc <= length) length = argc - 1;
  for (int i = 0; i < length; i++) {
    Object* argtype = args->get(i);
    if (argtype->IsUndefined()) continue;
    Object** arg = &argv[-1 - i];
    Object* current = *arg;
    current = FindHidden(heap, current, FunctionTemplateInfo::cast(argtype));
    if (current == heap->null_value()) current = heap->undefined_value();
    *arg = current;
  }
  return holder;
}


template <bool is_construct>
MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
    BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) {
  ASSERT(is_construct == CalledAsConstructor(isolate));
  Heap* heap = isolate->heap();

  HandleScope scope(isolate);
  Handle<JSFunction> function = args.called_function();
  ASSERT(function->shared()->IsApiFunction());

  FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data();
  if (is_construct) {
    Handle<FunctionTemplateInfo> desc(fun_data, isolate);
    bool pending_exception = false;
    isolate->factory()->ConfigureInstance(
        desc, Handle<JSObject>::cast(args.receiver()), &pending_exception);
    ASSERT(isolate->has_pending_exception() == pending_exception);
    if (pending_exception) return Failure::Exception();
    fun_data = *desc;
  }

  Object* raw_holder = TypeCheck(heap, args.length(), &args[0], fun_data);

  if (raw_holder->IsNull()) {
    // This function cannot be called with the given receiver.  Abort!
    Handle<Object> obj =
        isolate->factory()->NewTypeError(
            "illegal_invocation", HandleVector(&function, 1));
    return isolate->Throw(*obj);
  }

  Object* raw_call_data = fun_data->call_code();
  if (!raw_call_data->IsUndefined()) {
    CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
    Object* callback_obj = call_data->callback();
    v8::InvocationCallback callback =
        v8::ToCData<v8::InvocationCallback>(callback_obj);
    Object* data_obj = call_data->data();
    Object* result;

    LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
    ASSERT(raw_holder->IsJSObject());

    FunctionCallbackArguments custom(isolate,
                                     data_obj,
                                     *function,
                                     raw_holder,
                                     &args[0] - 1,
                                     args.length() - 1,
                                     is_construct);

    v8::Handle<v8::Value> value = custom.Call(callback);
    if (value.IsEmpty()) {
      result = heap->undefined_value();
    } else {
      result = *reinterpret_cast<Object**>(*value);
      result->VerifyApiCallResultType();
    }

    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
    if (!is_construct || result->IsJSObject()) return result;
  }

  return *args.receiver();
}


BUILTIN(HandleApiCall) {
  return HandleApiCallHelper<false>(args, isolate);
}


BUILTIN(HandleApiCallConstruct) {
  return HandleApiCallHelper<true>(args, isolate);
}


// Helper function to handle calls to non-function objects created through the
// API. The object can be called as either a constructor (using new) or just as
// a function (without new).
MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
    Isolate* isolate,
    bool is_construct_call,
    BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
  // Non-functions are never called as constructors. Even if this is an object
  // called as a constructor the delegate call is not a construct call.
  ASSERT(!CalledAsConstructor(isolate));
  Heap* heap = isolate->heap();

  Handle<Object> receiver = args.receiver();

  // Get the object called.
  JSObject* obj = JSObject::cast(*receiver);

  // Get the invocation callback from the function descriptor that was
  // used to create the called object.
  ASSERT(obj->map()->has_instance_call_handler());
  JSFunction* constructor = JSFunction::cast(obj->map()->constructor());
  ASSERT(constructor->shared()->IsApiFunction());
  Object* handler =
      constructor->shared()->get_api_func_data()->instance_call_handler();
  ASSERT(!handler->IsUndefined());
  CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
  Object* callback_obj = call_data->callback();
  v8::InvocationCallback callback =
      v8::ToCData<v8::InvocationCallback>(callback_obj);

  // Get the data for the call and perform the callback.
  Object* result;
  {
    HandleScope scope(isolate);
    LOG(isolate, ApiObjectAccess("call non-function", obj));

    FunctionCallbackArguments custom(isolate,
                                     call_data->data(),
                                     constructor,
                                     obj,
                                     &args[0] - 1,
                                     args.length() - 1,
                                     is_construct_call);
    v8::Handle<v8::Value> value = custom.Call(callback);
    if (value.IsEmpty()) {
      result = heap->undefined_value();
    } else {
      result = *reinterpret_cast<Object**>(*value);
      result->VerifyApiCallResultType();
    }
  }
  // Check for exceptions and return result.
  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
  return result;
}


// Handle calls to non-function objects created through the API. This delegate
// function is used when the call is a normal function call.
BUILTIN(HandleApiCallAsFunction) {
  return HandleApiCallAsFunctionOrConstructor(isolate, false, args);
}


// Handle calls to non-function objects created through the API. This delegate
// function is used when the call is a construct call.
BUILTIN(HandleApiCallAsConstructor) {
  return HandleApiCallAsFunctionOrConstructor(isolate, true, args);
}


static void Generate_LoadIC_Initialize(MacroAssembler* masm) {
  LoadIC::GenerateInitialize(masm);
}


static void Generate_LoadIC_PreMonomorphic(MacroAssembler* masm) {
  LoadIC::GeneratePreMonomorphic(masm);
}


static void Generate_LoadIC_Miss(MacroAssembler* masm) {
  LoadIC::GenerateMiss(masm);
}


static void Generate_LoadIC_Megamorphic(MacroAssembler* masm) {
  LoadIC::GenerateMegamorphic(masm);
}


static void Generate_LoadIC_Normal(MacroAssembler* masm) {
  LoadIC::GenerateNormal(masm);
}


static void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
  LoadStubCompiler::GenerateLoadViaGetter(masm, Handle<JSFunction>());
}


static void Generate_LoadIC_Slow(MacroAssembler* masm) {
  LoadIC::GenerateRuntimeGetProperty(masm);
}


static void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
  KeyedLoadIC::GenerateInitialize(masm);
}


static void Generate_KeyedLoadIC_Slow(MacroAssembler* masm) {
  KeyedLoadIC::GenerateRuntimeGetProperty(masm);
}


static void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) {
  KeyedLoadIC::GenerateMiss(masm, MISS);
}


static void Generate_KeyedLoadIC_MissForceGeneric(MacroAssembler* masm) {
  KeyedLoadIC::GenerateMiss(masm, MISS_FORCE_GENERIC);
}


static void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) {
  KeyedLoadIC::GenerateGeneric(masm);
}


static void Generate_KeyedLoadIC_String(MacroAssembler* masm) {
  KeyedLoadIC::GenerateString(masm);
}


static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
  KeyedLoadIC::GeneratePreMonomorphic(masm);
}

static void Generate_KeyedLoadIC_IndexedInterceptor(MacroAssembler* masm) {
  KeyedLoadIC::GenerateIndexedInterceptor(masm);
}

static void Generate_KeyedLoadIC_NonStrictArguments(MacroAssembler* masm) {
  KeyedLoadIC::GenerateNonStrictArguments(masm);
}

static void Generate_StoreIC_Slow(MacroAssembler* masm) {
  StoreIC::GenerateSlow(masm);
}


static void Generate_StoreIC_Initialize(MacroAssembler* masm) {
  StoreIC::GenerateInitialize(masm);
}


static void Generate_StoreIC_Initialize_Strict(MacroAssembler* masm) {
  StoreIC::GenerateInitialize(masm);
}


static void Generate_StoreIC_Miss(MacroAssembler* masm) {
  StoreIC::GenerateMiss(masm);
}


static void Generate_StoreIC_Normal(MacroAssembler* masm) {
  StoreIC::GenerateNormal(masm);
}


static void Generate_StoreIC_Normal_Strict(MacroAssembler* masm) {
  StoreIC::GenerateNormal(masm);
}


static void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
  StoreIC::GenerateMegamorphic(masm, kNonStrictMode);
}


static void Generate_StoreIC_Megamorphic_Strict(MacroAssembler* masm) {
  StoreIC::GenerateMegamorphic(masm, kStrictMode);
}


static void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) {
  StoreIC::GenerateRuntimeSetProperty(masm, kNonStrictMode);
}


static void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) {
  StoreIC::GenerateRuntimeSetProperty(masm, kStrictMode);
}


static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
  StoreStubCompiler::GenerateStoreViaSetter(masm, Handle<JSFunction>());
}


static void Generate_StoreIC_Generic(MacroAssembler* masm) {
  StoreIC::GenerateRuntimeSetProperty(masm, kNonStrictMode);
}


static void Generate_StoreIC_Generic_Strict(MacroAssembler* masm) {
  StoreIC::GenerateRuntimeSetProperty(masm, kStrictMode);
}


static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
  KeyedStoreIC::GenerateGeneric(masm, kNonStrictMode);
}


static void Generate_KeyedStoreIC_Generic_Strict(MacroAssembler* masm) {
  KeyedStoreIC::GenerateGeneric(masm, kStrictMode);
}


static void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
  KeyedStoreIC::GenerateMiss(masm, MISS);
}


static void Generate_KeyedStoreIC_MissForceGeneric(MacroAssembler* masm) {
  KeyedStoreIC::GenerateMiss(masm, MISS_FORCE_GENERIC);
}


static void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) {
  KeyedStoreIC::GenerateSlow(masm);
}


static void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) {
  KeyedStoreIC::GenerateInitialize(masm);
}


static void Generate_KeyedStoreIC_Initialize_Strict(MacroAssembler* masm) {
  KeyedStoreIC::GenerateInitialize(masm);
}

static void Generate_KeyedStoreIC_NonStrictArguments(MacroAssembler* masm) {
  KeyedStoreIC::GenerateNonStrictArguments(masm);
}

static void Generate_TransitionElementsSmiToDouble(MacroAssembler* masm) {
  KeyedStoreIC::GenerateTransitionElementsSmiToDouble(masm);
}

static void Generate_TransitionElementsDoubleToObject(MacroAssembler* masm) {
  KeyedStoreIC::GenerateTransitionElementsDoubleToObject(masm);
}

#ifdef ENABLE_DEBUGGER_SUPPORT
static void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateLoadICDebugBreak(masm);
}


static void Generate_StoreIC_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateStoreICDebugBreak(masm);
}


static void Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateKeyedLoadICDebugBreak(masm);
}


static void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateKeyedStoreICDebugBreak(masm);
}


static void Generate_CompareNilIC_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateCompareNilICDebugBreak(masm);
}


static void Generate_Return_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateReturnDebugBreak(masm);
}


static void Generate_CallFunctionStub_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateCallFunctionStubDebugBreak(masm);
}


static void Generate_CallFunctionStub_Recording_DebugBreak(
    MacroAssembler* masm) {
  Debug::GenerateCallFunctionStubRecordDebugBreak(masm);
}


static void Generate_CallConstructStub_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateCallConstructStubDebugBreak(masm);
}


static void Generate_CallConstructStub_Recording_DebugBreak(
    MacroAssembler* masm) {
  Debug::GenerateCallConstructStubRecordDebugBreak(masm);
}


static void Generate_Slot_DebugBreak(MacroAssembler* masm) {
  Debug::GenerateSlotDebugBreak(masm);
}


static void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) {
  Debug::GeneratePlainReturnLiveEdit(masm);
}


static void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) {
  Debug::GenerateFrameDropperLiveEdit(masm);
}
#endif


Builtins::Builtins() : initialized_(false) {
  memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
  memset(names_, 0, sizeof(names_[0]) * builtin_count);
}


Builtins::~Builtins() {
}


#define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name),
Address const Builtins::c_functions_[cfunction_count] = {
  BUILTIN_LIST_C(DEF_ENUM_C)
};
#undef DEF_ENUM_C

#define DEF_JS_NAME(name, ignore) #name,
#define DEF_JS_ARGC(ignore, argc) argc,
const char* const Builtins::javascript_names_[id_count] = {
  BUILTINS_LIST_JS(DEF_JS_NAME)
};

int const Builtins::javascript_argc_[id_count] = {
  BUILTINS_LIST_JS(DEF_JS_ARGC)
};
#undef DEF_JS_NAME
#undef DEF_JS_ARGC

struct BuiltinDesc {
  byte* generator;
  byte* c_code;
  const char* s_name;  // name is only used for generating log information.
  int name;
  Code::Flags flags;
  BuiltinExtraArguments extra_args;
};

#define BUILTIN_FUNCTION_TABLE_INIT { V8_ONCE_INIT, {} }

class BuiltinFunctionTable {
 public:
  BuiltinDesc* functions() {
    CallOnce(&once_, &Builtins::InitBuiltinFunctionTable);
    return functions_;
  }

  OnceType once_;
  BuiltinDesc functions_[Builtins::builtin_count + 1];

  friend class Builtins;
};

static BuiltinFunctionTable builtin_function_table =
    BUILTIN_FUNCTION_TABLE_INIT;

// Define array of pointers to generators and C builtin functions.
// We do this in a sort of roundabout way so that we can do the initialization
// within the lexical scope of Builtins:: and within a context where
// Code::Flags names a non-abstract type.
void Builtins::InitBuiltinFunctionTable() {
  BuiltinDesc* functions = builtin_function_table.functions_;
  functions[builtin_count].generator = NULL;
  functions[builtin_count].c_code = NULL;
  functions[builtin_count].s_name = NULL;
  functions[builtin_count].name = builtin_count;
  functions[builtin_count].flags = static_cast<Code::Flags>(0);
  functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS;

#define DEF_FUNCTION_PTR_C(aname, aextra_args)                         \
    functions->generator = FUNCTION_ADDR(Generate_Adaptor);            \
    functions->c_code = FUNCTION_ADDR(Builtin_##aname);                \
    functions->s_name = #aname;                                        \
    functions->name = c_##aname;                                       \
    functions->flags = Code::ComputeFlags(Code::BUILTIN);              \
    functions->extra_args = aextra_args;                               \
    ++functions;

#define DEF_FUNCTION_PTR_A(aname, kind, state, extra)                       \
    functions->generator = FUNCTION_ADDR(Generate_##aname);                 \
    functions->c_code = NULL;                                               \
    functions->s_name = #aname;                                             \
    functions->name = k##aname;                                             \
    functions->flags = Code::ComputeFlags(Code::kind,                       \
                                          state,                            \
                                          extra);                           \
    functions->extra_args = NO_EXTRA_ARGUMENTS;                             \
    ++functions;

  BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
  BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
  BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)

#undef DEF_FUNCTION_PTR_C
#undef DEF_FUNCTION_PTR_A
}

void Builtins::SetUp(bool create_heap_objects) {
  ASSERT(!initialized_);
  Isolate* isolate = Isolate::Current();
  Heap* heap = isolate->heap();

  // Create a scope for the handles in the builtins.
  HandleScope scope(isolate);

  const BuiltinDesc* functions = builtin_function_table.functions();

  // For now we generate builtin adaptor code into a stack-allocated
  // buffer, before copying it into individual code objects. Be careful
  // with alignment, some platforms don't like unaligned code.
  union { int force_alignment; byte buffer[8*KB]; } u;

  // Traverse the list of builtins and generate an adaptor in a
  // separate code object for each one.
  for (int i = 0; i < builtin_count; i++) {
    if (create_heap_objects) {
      MacroAssembler masm(isolate, u.buffer, sizeof u.buffer);
      // Generate the code/adaptor.
      typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments);
      Generator g = FUNCTION_CAST<Generator>(functions[i].generator);
      // We pass all arguments to the generator, but it may not use all of
      // them.  This works because the first arguments are on top of the
      // stack.
      ASSERT(!masm.has_frame());
      g(&masm, functions[i].name, functions[i].extra_args);
      // Move the code into the object heap.
      CodeDesc desc;
      masm.GetCode(&desc);
      Code::Flags flags =  functions[i].flags;
      Object* code = NULL;
      {
        // During startup it's OK to always allocate and defer GC to later.
        // This simplifies things because we don't need to retry.
        AlwaysAllocateScope __scope__;
        { MaybeObject* maybe_code =
              heap->CreateCode(desc, flags, masm.CodeObject());
          if (!maybe_code->ToObject(&code)) {
            v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
          }
        }
      }
      // Log the event and add the code to the builtins array.
      PROFILE(isolate,
              CodeCreateEvent(Logger::BUILTIN_TAG,
                              Code::cast(code),
                              functions[i].s_name));
      GDBJIT(AddCode(GDBJITInterface::BUILTIN,
                     functions[i].s_name,
                     Code::cast(code)));
      builtins_[i] = code;
#ifdef ENABLE_DISASSEMBLER
      if (FLAG_print_builtin_code) {
        PrintF("Builtin: %s\n", functions[i].s_name);
        Code::cast(code)->Disassemble(functions[i].s_name);
        PrintF("\n");
      }
#endif
    } else {
      // Deserializing. The values will be filled in during IterateBuiltins.
      builtins_[i] = NULL;
    }
    names_[i] = functions[i].s_name;
  }

  // Mark as initialized.
  initialized_ = true;
}


void Builtins::TearDown() {
  initialized_ = false;
}


void Builtins::IterateBuiltins(ObjectVisitor* v) {
  v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count);
}


const char* Builtins::Lookup(byte* pc) {
  // may be called during initialization (disassembler!)
  if (initialized_) {
    for (int i = 0; i < builtin_count; i++) {
      Code* entry = Code::cast(builtins_[i]);
      if (entry->contains(pc)) {
        return names_[i];
      }
    }
  }
  return NULL;
}


#define DEFINE_BUILTIN_ACCESSOR_C(name, ignore)               \
Handle<Code> Builtins::name() {                               \
  Code** code_address =                                       \
      reinterpret_cast<Code**>(builtin_address(k##name));     \
  return Handle<Code>(code_address);                          \
}
#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
Handle<Code> Builtins::name() {                             \
  Code** code_address =                                     \
      reinterpret_cast<Code**>(builtin_address(k##name));   \
  return Handle<Code>(code_address);                        \
}
BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
#undef DEFINE_BUILTIN_ACCESSOR_C
#undef DEFINE_BUILTIN_ACCESSOR_A


} }  // namespace v8::internal
