13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arguments.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bootstrapper.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "builtins.h"
34b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "gdb-jit.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ic-inl.h"
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "heap-profiler.h"
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "mark-compact.h"
38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h"
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkenamespace {
44e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
45e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Arguments object passed to C++ builtins.
46e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketemplate <BuiltinExtraArguments extra_args>
47e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeclass BuiltinArguments : public Arguments {
48e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke public:
49e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  BuiltinArguments(int length, Object** arguments)
50e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      : Arguments(length, arguments) { }
51e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
52e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Object*& operator[] (int index) {
53e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    ASSERT(index < length());
54e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::operator[](index);
55e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
56e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
57e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  template <class S> Handle<S> at(int index) {
58e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    ASSERT(index < length());
59e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::at<S>(index);
60e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
61e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
62e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Handle<Object> receiver() {
63e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::at<Object>(0);
64e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
65e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
66e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Handle<JSFunction> called_function() {
67e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION);
68e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::at<JSFunction>(Arguments::length() - 1);
69e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
70e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
71e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Gets the total number of arguments including the receiver (but
72e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // excluding extra arguments).
73e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  int length() const {
74e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS);
75e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::length();
76e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
77e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
78e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG
79e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Verify() {
80e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    // Check we have at least the receiver.
81e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    ASSERT(Arguments::length() >= 1);
82e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
83e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif
84e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke};
85e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
86e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
87e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Specialize BuiltinArguments for the called function extra argument.
88e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
89e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketemplate <>
90e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeint BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const {
91e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return Arguments::length() - 1;
92e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
93e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
94e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG
95e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketemplate <>
96e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() {
97e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Check we have at least the receiver and the called function.
98e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(Arguments::length() >= 2);
99e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Make sure cast to JSFunction succeeds.
100e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  called_function();
101e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
102e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif
103e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
104e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
105e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#define DEF_ARG_TYPE(name, spec)                      \
106e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  typedef BuiltinArguments<spec> name##ArgumentsType;
107e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBUILTIN_LIST_C(DEF_ARG_TYPE)
108e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#undef DEF_ARG_TYPE
109e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
110e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}  // namespace
111e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
113e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Support macro for defining builtins in C++.
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A builtin function is defined by writing:
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   BUILTIN(name) {
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     ...
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   }
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// In the body of the builtin function the arguments can be accessed
123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// through the BuiltinArguments object args.
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
125e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define BUILTIN(name)                                      \
12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      name##ArgumentsType args, Isolate* isolate);         \
13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MUST_USE_RESULT static MaybeObject* Builtin_##name(      \
13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      name##ArgumentsType args, Isolate* isolate) {        \
13244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(isolate == Isolate::Current());                 \
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    args.Verify();                                         \
13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return Builtin_Impl_##name(args, isolate);             \
13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }                                                        \
13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      name##ArgumentsType args, Isolate* isolate)
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#else  // For release mode.
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define BUILTIN(name)                                      \
14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static MaybeObject* Builtin_##name(name##ArgumentsType args, Isolate* isolate)
143e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
144e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic inline bool CalledAsConstructor(Isolate* isolate) {
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calculate the result using a full stack frame iterator and check
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // that the state of the stack is as we assume it to be in the
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // code below.
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrameIterator it;
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(it.frame()->is_exit());
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  it.Advance();
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrame* frame = it.frame();
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool reference_result = frame->is_construct();
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
15844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address fp = Isolate::c_entry_fp(isolate->thread_local_top());
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Because we know fp points to an exit frame we can use the relevant
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // part of ExitFrame::ComputeCallerState directly.
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const int kCallerOffset = ExitFrameConstants::kCallerFPOffset;
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address caller_fp = Memory::Address_at(fp + kCallerOffset);
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This inlines the part of StackFrame::ComputeType that grabs the
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // type of the current frame.  Note that StackFrame::ComputeType
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // has been specialized for each architecture so if any one of them
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // changes this code has to be changed as well.
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const int kMarkerOffset = StandardFrameConstants::kMarkerOffset;
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT);
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* marker = Memory::Object_at(caller_fp + kMarkerOffset);
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result = (marker == kConstructMarker);
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT_EQ(result, reference_result);
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(Illegal) {
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
17944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->undefined_value();  // Make compiler happy.
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(EmptyFunction) {
18444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->undefined_value();
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic MaybeObject* ArrayCodeGenericCommon(Arguments* args,
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           Isolate* isolate,
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                           JSFunction* constructor) {
19144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
19244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->counters()->array_function_runtime()->Increment();
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSArray* array;
19544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (CalledAsConstructor(isolate)) {
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array = JSArray::cast((*args)[0]);
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Initialize elements and length in case later allocations fail so that the
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // array object is initialized in a valid state.
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array->set_length(Smi::FromInt(0));
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array->set_elements(heap->empty_fixed_array());
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!FLAG_smi_only_arrays) {
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Context* global_context = isolate->context()->global_context();
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (array->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          !global_context->object_js_array_map()->IsUndefined()) {
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        array->set_map(Map::cast(global_context->object_js_array_map()));
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Allocate the JS Array
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!maybe_obj->To(&array)) return maybe_obj;
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optimize the case where there is one argument and the argument is a
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // small smi.
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (args->length() == 2) {
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* obj = (*args)[1];
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (obj->IsSmi()) {
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int len = Smi::cast(obj)->value();
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Object* fixed_array;
22244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len);
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          if (!maybe_obj->ToObject(&fixed_array)) return maybe_obj;
2245913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        }
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // We do not use SetContent to skip the unnecessary elements type check.
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        array->set_elements(FixedArray::cast(fixed_array));
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        array->set_length(Smi::cast(obj));
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return array;
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Take the argument as the length.
2325913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    { MaybeObject* maybe_obj = array->Initialize(0);
2335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2345913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return array->SetElementsLength((*args)[1]);
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optimize the case where there are no parameters passed.
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (args->length() == 1) {
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return array->Initialize(JSArray::kPreallocatedArrayElements);
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set length and elements on the array.
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int number_of_elements = args->length() - 1;
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MaybeObject* maybe_object =
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      array->EnsureCanContainElements(args, 1, number_of_elements,
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      ALLOW_CONVERTED_DOUBLE_ELEMENTS);
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (maybe_object->IsFailure()) return maybe_object;
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Allocate an appropriately typed elements array.
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MaybeObject* maybe_elms;
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ElementsKind elements_kind = array->GetElementsKind();
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (elements_kind == FAST_DOUBLE_ELEMENTS) {
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    maybe_elms = heap->AllocateUninitializedFixedDoubleArray(
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        number_of_elements);
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    maybe_elms = heap->AllocateFixedArrayWithHoles(number_of_elements);
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FixedArrayBase* elms;
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!maybe_elms->To<FixedArrayBase>(&elms)) return maybe_elms;
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
262c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // Fill in the content
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  switch (array->GetElementsKind()) {
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case FAST_SMI_ONLY_ELEMENTS: {
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FixedArray* smi_elms = FixedArray::cast(elms);
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      for (int index = 0; index < number_of_elements; index++) {
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        smi_elms->set(index, (*args)[index+1], SKIP_WRITE_BARRIER);
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case FAST_ELEMENTS: {
2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      AssertNoAllocation no_gc;
2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FixedArray* object_elms = FixedArray::cast(elms);
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      for (int index = 0; index < number_of_elements; index++) {
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        object_elms->set(index, (*args)[index+1], mode);
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    case FAST_DOUBLE_ELEMENTS: {
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FixedDoubleArray* double_elms = FixedDoubleArray::cast(elms);
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      for (int index = 0; index < number_of_elements; index++) {
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        double_elms->set(index, (*args)[index+1]->Number());
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    default:
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      UNREACHABLE();
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      break;
290c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  }
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  array->set_elements(elms);
2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  array->set_length(Smi::FromInt(number_of_elements));
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return array;
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochBUILTIN(InternalArrayCodeGeneric) {
2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ArrayCodeGenericCommon(
3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      &args,
3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate,
3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate->context()->global_context()->internal_array_function());
30385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch}
30485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
30585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochBUILTIN(ArrayCodeGeneric) {
3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return ArrayCodeGenericCommon(
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      &args,
3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate,
3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      isolate->context()->global_context()->array_function());
311c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch}
312c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
313c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic void MoveElements(Heap* heap,
31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                         AssertNoAllocation* no_gc,
3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         FixedArray* dst,
3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int dst_index,
3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         FixedArray* src,
3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int src_index,
3206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int len) {
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (len == 0) return;
32244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(dst->map() != HEAP->fixed_cow_array_map());
3236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  memmove(dst->data_start() + dst_index,
3246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          src->data_start() + src_index,
3256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          len * kPointerSize);
3266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
3276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (mode == UPDATE_WRITE_BARRIER) {
32844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
3296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  heap->incremental_marking()->RecordWrites(dst);
3316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
33444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(dst->map() != heap->fixed_cow_array_map());
33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
3376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
34044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic FixedArray* LeftTrimFixedArray(Heap* heap,
34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                      FixedArray* elms,
34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                      int to_trim) {
34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(elms->map() != HEAP->fixed_cow_array_map());
344791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // For now this trick is only applied to fixed arrays in new and paged space.
3456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // In large object space the object's start must coincide with chunk
3466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and thus the trick is just not applicable.
34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!HEAP->lo_space()->Contains(elms));
3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  STATIC_ASSERT(FixedArray::kMapOffset == 0);
3506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  STATIC_ASSERT(FixedArray::kLengthOffset == kPointerSize);
3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  STATIC_ASSERT(FixedArray::kHeaderSize == 2 * kPointerSize);
3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object** former_start = HeapObject::RawField(elms, 0);
3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const int len = elms->length();
3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
357791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  if (to_trim > FixedArray::kHeaderSize / kPointerSize &&
35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      !heap->new_space()->Contains(elms)) {
359791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    // If we are doing a big trim in old space then we zap the space that was
360791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    // formerly part of the array so that the GC (aided by the card-based
361791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    // remembered set) won't find pointers to new-space there.
362791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    Object** zap = reinterpret_cast<Object**>(elms->address());
363791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    zap++;  // Header of filler must be at least one word so skip that.
364791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    for (int i = 1; i < to_trim; i++) {
365791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block      *zap++ = Smi::FromInt(0);
366791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    }
367791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  }
3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Technically in new space this write might be omitted (except for
3696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // debug mode which iterates through the heap), but to play safer
3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // we still do it.
37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  heap->CreateFillerObjectAt(elms->address(), to_trim * kPointerSize);
3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  former_start[to_trim] = heap->fixed_array_map();
3747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  former_start[to_trim + 1] = Smi::FromInt(len - to_trim);
3756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Maintain marking consistency for HeapObjectIterator and
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // IncrementalMarking.
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int size_delta = to_trim * kPointerSize;
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (heap->marking()->TransferMark(elms->address(),
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    elms->address() + size_delta)) {
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP_PROFILE(heap, ObjectMoveEvent(elms->address(),
3853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     elms->address() + size_delta));
386791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  return FixedArray::cast(HeapObject::FromAddress(
387791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block      elms->address() + to_trim * kPointerSize));
3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
39144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic bool ArrayPrototypeHasNoElements(Heap* heap,
39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                        Context* global_context,
39325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                                        JSObject* array_proto) {
3946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // This method depends on non writability of Object and Array prototype
3956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // fields.
39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (array_proto->elements() != heap->empty_fixed_array()) return false;
3976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Object.prototype
3981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Object* proto = array_proto->GetPrototype();
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (proto == heap->null_value()) return false;
4001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  array_proto = JSObject::cast(proto);
40125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  if (array_proto != global_context->initial_object_prototype()) return false;
40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (array_proto->elements() != heap->empty_fixed_array()) return false;
403053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  return array_proto->GetPrototype()->IsNull();
4046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4075913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMUST_USE_RESULT
4085913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckstatic inline MaybeObject* EnsureJSArrayWithWritableFastElements(
4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Heap* heap, Object* receiver, Arguments* args, int first_added_arg) {
410756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (!receiver->IsJSArray()) return NULL;
4116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
4129fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  HeapObject* elms = array->elements();
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Map* map = elms->map();
4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (map == heap->fixed_array_map()) {
4155710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch    if (args == NULL || array->HasFastElements()) return elms;
4165710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch    if (array->HasFastDoubleElements()) {
4175710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch      ASSERT(elms == heap->empty_fixed_array());
4185710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch      MaybeObject* maybe_transition =
4195710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch          array->TransitionElementsKind(FAST_ELEMENTS);
4205710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch      if (maybe_transition->IsFailure()) return maybe_transition;
4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return elms;
4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (map == heap->fixed_cow_array_map()) {
4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MaybeObject* maybe_writable_result = array->EnsureWritableFastElements();
4255710ceac03e2cf7a164ad7393b5a6b6114ea45e6Ben Murdoch    if (args == NULL || array->HasFastElements() ||
4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        maybe_writable_result->IsFailure()) {
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return maybe_writable_result;
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return NULL;
4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Need to ensure that the arguments passed in args can be contained in
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the array.
4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int args_length = args->length();
4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (first_added_arg >= args_length) return array->elements();
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MaybeObject* maybe_array = array->EnsureCanContainElements(
4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      args,
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      first_added_arg,
4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      args_length - first_added_arg,
4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      DONT_ALLOW_DOUBLE_ELEMENTS);
4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (maybe_array->IsFailure()) return maybe_array;
4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return array->elements();
4456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
44844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                                     JSArray* receiver) {
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!FLAG_clever_optimizations) return false;
45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Context* global_context = heap->isolate()->context()->global_context();
45225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  JSObject* array_proto =
45325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      JSObject::cast(global_context->array_function()->prototype());
454756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return receiver->GetPrototype() == array_proto &&
45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block         ArrayPrototypeHasNoElements(heap, global_context, array_proto);
45625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
45725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
45825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
4595913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMUST_USE_RESULT static MaybeObject* CallJsBuiltin(
46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate,
4615913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    const char* name,
4625913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
46344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope handleScope(isolate);
4646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<Object> js_builtin =
4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      GetProperty(Handle<JSObject>(isolate->global_context()->builtins()),
4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  name);
4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin);
4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int argc = args.length() - 1;
4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ScopedVector<Handle<Object> > argv(argc);
4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < argc; ++i) {
4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    argv[i] = args.at<Object>(i + 1);
473592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  }
4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool pending_exception;
4756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<Object> result = Execution::Call(function,
4766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          args.receiver(),
4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          argc,
4786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          argv.start(),
4796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          &pending_exception);
4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (pending_exception) return Failure::Exception();
4816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return *result;
4826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(ArrayPush) {
48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
4885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
4895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 1);
49144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL) {
49244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArrayPush", args);
49344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
4945913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
4955913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
496756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
4976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int len = Smi::cast(array->length())->value();
500402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int to_add = args.length() - 1;
501402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (to_add == 0) {
502402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    return Smi::FromInt(len);
503402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
504402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Currently fixed arrays cannot grow too big, so
505402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // we should never hit this case.
506402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(to_add <= (Smi::kMaxValue - len));
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
508402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int new_length = len + to_add;
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
510402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (new_length > elms->length()) {
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // New backing storage is needed.
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int capacity = new_length + (new_length >> 1) + 16;
5135913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* obj;
51444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
5155913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
5165913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
5176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    FixedArray* new_elms = FixedArray::cast(obj);
5184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               new_elms, FAST_ELEMENTS, 0, len);
52144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    FillWithHoles(heap, new_elms, new_length, capacity);
5226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
523402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    elms = new_elms;
524402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
525402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
5266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Add the provided values.
527402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  AssertNoAllocation no_gc;
528402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
529402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  for (int index = 0; index < to_add; index++) {
530402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    elms->set(index + len, args[index + 1], mode);
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
532402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (elms != array->elements()) {
5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array->set_elements(elms);
5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the length.
5384515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  array->set_length(Smi::FromInt(new_length));
539402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return Smi::FromInt(new_length);
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(ArrayPop) {
54444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
5456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
5465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
5475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
54944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL) return CallJsBuiltin(isolate, "ArrayPop", args);
5505913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
5515913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
552756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
5536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int len = Smi::cast(array->length())->value();
55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (len == 0) return heap->undefined_value();
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get top element
5595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* top = elms->get(len - 1);
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the length.
5624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  array->set_length(Smi::FromInt(len - 1));
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!top->IsTheHole()) {
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Delete the top element.
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    elms->set_the_hole(len - 1);
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return top;
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  top = array->GetPrototype()->GetElement(len - 1);
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return top;
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
576402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(ArrayShift) {
57744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
5786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
5795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
5805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
58244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL)
58344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArrayShift", args);
5845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
5855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
58644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
58744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return CallJsBuiltin(isolate, "ArrayShift", args);
5886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
589756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
5906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(array->HasFastTypeElements());
592402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
593402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int len = Smi::cast(array->length())->value();
59444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (len == 0) return heap->undefined_value();
595402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
596402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Get first element
597402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Object* first = elms->get(0);
598402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (first->IsTheHole()) {
59944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    first = heap->undefined_value();
600402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
601402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!heap->lo_space()->Contains(elms)) {
6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array->set_elements(LeftTrimFixedArray(heap, elms, 1));
6046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
6056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Shift the elements.
6066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    AssertNoAllocation no_gc;
60744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    MoveElements(heap, &no_gc, elms, 0, elms, 1, len - 1);
60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    elms->set(len - 1, heap->the_hole_value());
609402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
610402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
611402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Set the length.
612402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  array->set_length(Smi::FromInt(len - 1));
613402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
614402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return first;
615402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
616402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
617402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
618402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(ArrayUnshift) {
61944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
6206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
6215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
6225913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
62444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL)
62544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArrayUnshift", args);
6265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
6275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
62844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
62944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return CallJsBuiltin(isolate, "ArrayUnshift", args);
6306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
631756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
6326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(array->HasFastTypeElements());
634402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
635402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int len = Smi::cast(array->length())->value();
636402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int to_add = args.length() - 1;
637402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int new_length = len + to_add;
638402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Currently fixed arrays cannot grow too big, so
639402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // we should never hit this case.
640402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(to_add <= (Smi::kMaxValue - len));
641402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MaybeObject* maybe_object =
6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      array->EnsureCanContainElements(&args, 1, to_add,
6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      DONT_ALLOW_DOUBLE_ELEMENTS);
6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (maybe_object->IsFailure()) return maybe_object;
6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
647402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (new_length > elms->length()) {
648402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // New backing storage is needed.
649402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    int capacity = new_length + (new_length >> 1) + 16;
6505913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* obj;
65144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
6525913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6535913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
6546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    FixedArray* new_elms = FixedArray::cast(obj);
6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               new_elms, FAST_ELEMENTS, to_add, len);
65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    FillWithHoles(heap, new_elms, new_length, capacity);
658402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    elms = new_elms;
659402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    array->set_elements(elms);
660402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  } else {
661402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    AssertNoAllocation no_gc;
66244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    MoveElements(heap, &no_gc, elms, to_add, elms, 0, len);
663402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
664402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
665402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Add the provided values.
666402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  AssertNoAllocation no_gc;
667402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
668402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  for (int i = 0; i < to_add; i++) {
669402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    elms->set(i, args[i + 1], mode);
670402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
671402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
672402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Set the length.
673402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  array->set_length(Smi::FromInt(new_length));
674402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return Smi::FromInt(new_length);
675402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
676402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
677402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
678402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(ArraySlice) {
67944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
6806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FixedArray* elms;
682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int len = -1;
6839fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  if (receiver->IsJSArray()) {
6849fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    JSArray* array = JSArray::cast(receiver);
6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!array->HasFastTypeElements() ||
68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        !IsJSArrayFastElementMovingAllowed(heap, array)) {
68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
6889fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    }
6899fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
6909fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    elms = FixedArray::cast(array->elements());
6919fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    len = Smi::cast(array->length())->value();
6929fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  } else {
6939fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    // Array.slice(arguments, ...) is quite a common idiom (notably more
6949fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    // than 50% of invocations in Web apps).  Treat it in C++ as well.
6959fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    Map* arguments_map =
69644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate->context()->global_context()->arguments_boilerplate()->map();
6979fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
6989fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    bool is_arguments_object_with_fast_elements =
6999fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block        receiver->IsJSObject()
7009fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block        && JSObject::cast(receiver)->map() == arguments_map
7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        && JSObject::cast(receiver)->HasFastTypeElements();
7029fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    if (!is_arguments_object_with_fast_elements) {
70344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
7049fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    }
7059fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    elms = FixedArray::cast(JSObject::cast(receiver)->elements());
706b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    Object* len_obj = JSObject::cast(receiver)
70744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        ->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
708b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (!len_obj->IsSmi()) {
70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
710b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
711b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    len = Smi::cast(len_obj)->value();
712b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (len > elms->length()) {
71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
714b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
715b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    for (int i = 0; i < len; i++) {
71644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      if (elms->get(i) == heap->the_hole_value()) {
71744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArraySlice", args);
718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
719b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
720b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
721b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(len >= 0);
722402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int n_arguments = args.length() - 1;
723402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
724402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Note carefully choosen defaults---if argument is missing,
7256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // it's undefined which gets converted to 0 for relative_start
7266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and to len for relative_end.
7276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int relative_start = 0;
7286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int relative_end = len;
729402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (n_arguments > 0) {
730402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    Object* arg1 = args[1];
731402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    if (arg1->IsSmi()) {
7326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      relative_start = Smi::cast(arg1)->value();
733402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    } else if (!arg1->IsUndefined()) {
73444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
735402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
736402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    if (n_arguments > 1) {
737402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      Object* arg2 = args[2];
738402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      if (arg2->IsSmi()) {
7396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        relative_end = Smi::cast(arg2)->value();
740402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      } else if (!arg2->IsUndefined()) {
74144f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArraySlice", args);
742402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      }
743402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
744402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
745402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
746402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
7476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int k = (relative_start < 0) ? Max(len + relative_start, 0)
7486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               : Min(relative_start, len);
749402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
750402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
7516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int final = (relative_end < 0) ? Max(len + relative_end, 0)
7526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 : Min(relative_end, len);
753402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ElementsKind elements_kind = JSObject::cast(receiver)->GetElementsKind();
75585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Calculate the length of result array.
7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int result_len = Max(final - k, 0);
758402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MaybeObject* maybe_array =
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap->AllocateJSArrayAndStorage(elements_kind,
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      result_len,
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      result_len);
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSArray* result_array;
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!maybe_array->To(&result_array)) return maybe_array;
765402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CopyObjectToObjectElements(elms, FAST_ELEMENTS, k,
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             FixedArray::cast(result_array->elements()),
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             FAST_ELEMENTS, 0, result_len);
769592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
770402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return result_array;
771402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
772402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
773402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
774402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(ArraySplice) {
77544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
7766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
7775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
7785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3);
78044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL)
78144f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArraySplice", args);
7825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
7835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
78544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return CallJsBuiltin(isolate, "ArraySplice", args);
7866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
787756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
7886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(array->HasFastTypeElements());
790402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
791402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int len = Smi::cast(array->length())->value();
792402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
793402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int n_arguments = args.length() - 1;
794402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
7956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int relative_start = 0;
7961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (n_arguments > 0) {
7971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Object* arg1 = args[1];
7981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (arg1->IsSmi()) {
7991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      relative_start = Smi::cast(arg1)->value();
8001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    } else if (!arg1->IsUndefined()) {
80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySplice", args);
8021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
803402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
8046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
8056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          : Min(relative_start, len);
806402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
807402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
8081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // given as a request to delete all the elements from the start.
8091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // And it differs from the case of undefined delete count.
810402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // This does not follow ECMA-262, but we do the same for
811402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // compatibility.
8121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int actual_delete_count;
8131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (n_arguments == 1) {
8141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    ASSERT(len - actual_start >= 0);
8151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    actual_delete_count = len - actual_start;
8161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
8171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    int value = 0;  // ToInteger(undefined) == 0
8181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (n_arguments > 1) {
8191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      Object* arg2 = args[2];
8201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      if (arg2->IsSmi()) {
8211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        value = Smi::cast(arg2)->value();
8221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      } else {
82344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArraySplice", args);
8241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      }
825402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
8261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    actual_delete_count = Min(Max(value, 0), len - actual_start);
827402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
828402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* result_array = NULL;
8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ElementsKind elements_kind =
8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      JSObject::cast(receiver)->GetElementsKind();
8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MaybeObject* maybe_array =
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap->AllocateJSArrayAndStorage(elements_kind,
8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      actual_delete_count,
8353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      actual_delete_count);
8363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!maybe_array->To(&result_array)) return maybe_array;
837402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  {
8396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Fill newly created array.
8403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CopyObjectToObjectElements(elms, FAST_ELEMENTS, actual_start,
8413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               FixedArray::cast(result_array->elements()),
8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               FAST_ELEMENTS, 0, actual_delete_count);
843402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
844402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
8466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int new_length = len - actual_delete_count + item_count;
847402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool elms_changed = false;
8496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (item_count < actual_delete_count) {
850402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // Shrink the array.
85144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    const bool trim_array = !heap->lo_space()->Contains(elms) &&
8526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      ((actual_start + item_count) <
8536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          (len - actual_delete_count - actual_start));
8546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (trim_array) {
8556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      const int delta = actual_delete_count - item_count;
8566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      {
858053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block        AssertNoAllocation no_gc;
859053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block        MoveElements(heap, &no_gc, elms, delta, elms, 0, actual_start);
8606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
861402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
86244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      elms = LeftTrimFixedArray(heap, elms, delta);
8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      elms_changed = true;
8656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    } else {
8666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      AssertNoAllocation no_gc;
86744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      MoveElements(heap, &no_gc,
8686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   elms, actual_start + item_count,
8696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   elms, actual_start + actual_delete_count,
8706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   (len - actual_delete_count - actual_start));
87144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      FillWithHoles(heap, elms, new_length, len);
872402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
8736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else if (item_count > actual_delete_count) {
874402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // Currently fixed arrays cannot grow too big, so
875402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // we should never hit this case.
8766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
877402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
878402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // Check if array need to grow.
879402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    if (new_length > elms->length()) {
880402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      // New backing storage is needed.
881402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      int capacity = new_length + (new_length >> 1) + 16;
8825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* obj;
8835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      { MaybeObject* maybe_obj =
88444f0eee88ff00398ff7f715fab053374d808c90dSteve Block            heap->AllocateUninitializedFixedArray(capacity);
8855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      }
887402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      FixedArray* new_elms = FixedArray::cast(obj);
888402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      {
8903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // Copy the part before actual_start as is.
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   new_elms, FAST_ELEMENTS, 0, actual_start);
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        const int to_copy = len - actual_delete_count - actual_start;
8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CopyObjectToObjectElements(elms, FAST_ELEMENTS,
8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   actual_start + actual_delete_count,
8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   new_elms, FAST_ELEMENTS,
8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   actual_start + item_count, to_copy);
8986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
90044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      FillWithHoles(heap, new_elms, new_length, capacity);
901402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
902402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      elms = new_elms;
9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      elms_changed = true;
9046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    } else {
9056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      AssertNoAllocation no_gc;
90644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      MoveElements(heap, &no_gc,
9076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   elms, actual_start + item_count,
9086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   elms, actual_start + actual_delete_count,
9096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   (len - actual_delete_count - actual_start));
910402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
911402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
912402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
9136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  AssertNoAllocation no_gc;
9146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
9156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int k = actual_start; k < actual_start + item_count; k++) {
9166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    elms->set(k, args[3 + k - actual_start], mode);
917402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
918402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
9193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (elms_changed) {
9203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    array->set_elements(elms);
9213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
9223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
923402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Set the length.
924402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  array->set_length(Smi::FromInt(new_length));
925402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
926402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return result_array;
927402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
928402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
929402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
9306ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockBUILTIN(ArrayConcat) {
93144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
93244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Context* global_context = isolate->context()->global_context();
93325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  JSObject* array_proto =
93425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      JSObject::cast(global_context->array_function()->prototype());
93544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!ArrayPrototypeHasNoElements(heap, global_context, array_proto)) {
93644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return CallJsBuiltin(isolate, "ArrayConcat", args);
9376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
9386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Iterate through all the arguments performing checks
9406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and calculating total length.
9416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int n_arguments = args.length();
9426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int result_len = 0;
9433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS;
9446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int i = 0; i < n_arguments; i++) {
9456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Object* arg = args[i];
9463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastTypeElements()
94725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen        || JSArray::cast(arg)->GetPrototype() != array_proto) {
94844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArrayConcat", args);
9496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
9506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int len = Smi::cast(JSArray::cast(arg)->length())->value();
9526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // We shouldn't overflow when adding another len.
9546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
9556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
9566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    USE(kHalfOfMaxInt);
9576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result_len += len;
9586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(result_len >= 0);
9596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (result_len > FixedArray::kMaxLength) {
96144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArrayConcat", args);
9626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
9636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!JSArray::cast(arg)->HasFastSmiOnlyElements()) {
9653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      elements_kind = FAST_ELEMENTS;
9663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
9676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
9686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Allocate result.
9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JSArray* result_array;
9713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  MaybeObject* maybe_array =
9723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      heap->AllocateJSArrayAndStorage(elements_kind,
9733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      result_len,
9743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      result_len);
9753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!maybe_array->To(&result_array)) return maybe_array;
9763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (result_len == 0) return result_array;
977592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
9786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Copy data.
9796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int start_pos = 0;
9803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FixedArray* result_elms(FixedArray::cast(result_array->elements()));
9816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int i = 0; i < n_arguments; i++) {
9826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    JSArray* array = JSArray::cast(args[i]);
9836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int len = Smi::cast(array->length())->value();
9843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FixedArray* elms = FixedArray::cast(array->elements());
9853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CopyObjectToObjectElements(elms, FAST_ELEMENTS, 0,
9863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               result_elms, FAST_ELEMENTS,
9873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               start_pos, len);
9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    start_pos += len;
9896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
9906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(start_pos == result_len);
9916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return result_array;
9936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
9946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
99744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Strict mode poison pills
99844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
99944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochBUILTIN(StrictModePoisonPill) {
100144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope;
100244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->Throw(*isolate->factory()->NewTypeError(
1003257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "strict_poison_pill", HandleVector<Object>(NULL, 0)));
100444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
100544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
100644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// -----------------------------------------------------------------------------
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the holder JSObject if the function can legally be called
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with this receiver.  Returns Heap::null_value() if the call is
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// illegal.  Any arguments that don't fit the expected type is
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// overwritten with undefined.  Arguments that do fit the expected
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// type is overwritten with the object in the prototype chain that
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// actually has that type.
101644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic inline Object* TypeCheck(Heap* heap,
101744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                int argc,
1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                Object** argv,
1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                FunctionTemplateInfo* info) {
1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* recv = argv[0];
1021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // API calls are only supported with JSObject receivers.
1022257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!recv->IsJSObject()) return heap->null_value();
1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* sig_obj = info->signature();
1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (sig_obj->IsUndefined()) return recv;
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SignatureInfo* sig = SignatureInfo::cast(sig_obj);
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If necessary, check the receiver
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* recv_type = sig->receiver();
1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* holder = recv;
1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!recv_type->IsUndefined()) {
103144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    for (; holder != heap->null_value(); holder = holder->GetPrototype()) {
1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (holder->IsInstanceOf(FunctionTemplateInfo::cast(recv_type))) {
1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
103644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (holder == heap->null_value()) return holder;
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* args_obj = sig->args();
1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If there is no argument signature we're done
1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (args_obj->IsUndefined()) return holder;
1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FixedArray* args = FixedArray::cast(args_obj);
1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int length = args->length();
1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (argc <= length) length = argc - 1;
1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < length; i++) {
1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* argtype = args->get(i);
1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (argtype->IsUndefined()) continue;
1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object** arg = &argv[-1 - i];
1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* current = *arg;
104944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    for (; current != heap->null_value(); current = current->GetPrototype()) {
1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (current->IsInstanceOf(FunctionTemplateInfo::cast(argtype))) {
1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        *arg = current;
1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
105544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (current == heap->null_value()) *arg = heap->undefined_value();
1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return holder;
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1061e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketemplate <bool is_construct>
10625913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
106344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) {
106444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(is_construct == CalledAsConstructor(isolate));
106544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
1068e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Handle<JSFunction> function = args.called_function();
10696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(function->shared()->IsApiFunction());
1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data();
1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_construct) {
107344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FunctionTemplateInfo> desc(fun_data, isolate);
1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool pending_exception = false;
107544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->factory()->ConfigureInstance(
107644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc, Handle<JSObject>::cast(args.receiver()), &pending_exception);
107744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(isolate->has_pending_exception() == pending_exception);
1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (pending_exception) return Failure::Exception();
10796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    fun_data = *desc;
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* raw_holder = TypeCheck(heap, args.length(), &args[0], fun_data);
1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (raw_holder->IsNull()) {
1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // This function cannot be called with the given receiver.  Abort!
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Object> obj =
108744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate->factory()->NewTypeError(
108844f0eee88ff00398ff7f715fab053374d808c90dSteve Block            "illegal_invocation", HandleVector(&function, 1));
108944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate->Throw(*obj);
1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* raw_call_data = fun_data->call_code();
1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!raw_call_data->IsUndefined()) {
1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* callback_obj = call_data->callback();
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::InvocationCallback callback =
1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        v8::ToCData<v8::InvocationCallback>(callback_obj);
1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* data_obj = call_data->data();
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* result;
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
110144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
11023e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    ASSERT(raw_holder->IsJSObject());
11033e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
110444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CustomArguments custom(isolate);
11053e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
11063e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        data_obj, *function, raw_holder);
11073e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
11093e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        custom.end(),
11103e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        &args[0] - 1,
11113e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        args.length() - 1,
11123e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        is_construct);
1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<v8::Value> value;
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
111744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      VMState state(isolate, EXTERNAL);
111844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ExternalCallbackScope call_scope(isolate,
111944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                       v8::ToCData<Address>(callback_obj));
1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value = callback(new_args);
1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (value.IsEmpty()) {
112344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      result = heap->undefined_value();
1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = *reinterpret_cast<Object**>(*value);
1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!is_construct || result->IsJSObject()) return result;
1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1132e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return *args.receiver();
1133e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1134e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1136e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBUILTIN(HandleApiCall) {
113744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HandleApiCallHelper<false>(args, isolate);
1138e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1140e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBUILTIN(HandleApiCallConstruct) {
114244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HandleApiCallHelper<true>(args, isolate);
1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1146402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#ifdef DEBUG
1147402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1148402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescustatic void VerifyTypeCheck(Handle<JSObject> object,
1149402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                            Handle<JSFunction> function) {
11506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(function->shared()->IsApiFunction());
11516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  FunctionTemplateInfo* info = function->shared()->get_api_func_data();
1152402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (info->signature()->IsUndefined()) return;
1153402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  SignatureInfo* signature = SignatureInfo::cast(info->signature());
1154402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Object* receiver_type = signature->receiver();
1155402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (receiver_type->IsUndefined()) return;
1156402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  FunctionTemplateInfo* type = FunctionTemplateInfo::cast(receiver_type);
1157402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(object->IsInstanceOf(type));
1158402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
1159402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1160402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#endif
1161402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1162402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1163402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(FastHandleApiCall) {
116444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!CalledAsConstructor(isolate));
116544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
1166402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  const bool is_construct = false;
1167402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
11688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // We expect four more arguments: callback, function, call data, and holder.
1169402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  const int args_length = args.length() - 4;
1170402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(args_length >= 0);
1171402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
11728a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Object* callback_obj = args[args_length];
1173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1174402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
11758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      &args[args_length + 1],
11763e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      &args[0] - 1,
11773e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      args_length - 1,
11783e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      is_construct);
1179402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
11808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#ifdef DEBUG
11818a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  VerifyTypeCheck(Utils::OpenHandle(*new_args.Holder()),
11828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                  Utils::OpenHandle(*new_args.Callee()));
11838a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#endif
118444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
1185402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Object* result;
1186402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  v8::Handle<v8::Value> value;
1187402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  {
1188402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // Leaving JavaScript.
118944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    VMState state(isolate, EXTERNAL);
119044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExternalCallbackScope call_scope(isolate,
119144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                     v8::ToCData<Address>(callback_obj));
11923e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    v8::InvocationCallback callback =
11933e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        v8::ToCData<v8::InvocationCallback>(callback_obj);
11943e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
1195402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    value = callback(new_args);
1196402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
1197402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (value.IsEmpty()) {
119844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    result = heap->undefined_value();
1199402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  } else {
1200402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    result = *reinterpret_cast<Object**>(*value);
1201402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
1202402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
120344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1204402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return result;
1205402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
1206402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1207402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function to handle calls to non-function objects created through the
1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// API. The object can be called as either a constructor (using new) or just as
1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a function (without new).
12115913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
121244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate,
1213e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    bool is_construct_call,
1214e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Non-functions are never called as constructors. Even if this is an object
1216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // called as a constructor the delegate call is not a construct call.
121744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!CalledAsConstructor(isolate));
121844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Handle<Object> receiver = args.receiver();
1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the object called.
12233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  JSObject* obj = JSObject::cast(*receiver);
1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the invocation callback from the function descriptor that was
1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // used to create the called object.
1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(obj->map()->has_instance_call_handler());
1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSFunction* constructor = JSFunction::cast(obj->map()->constructor());
12296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(constructor->shared()->IsApiFunction());
1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* handler =
12316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      constructor->shared()->get_api_func_data()->instance_call_handler();
1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!handler->IsUndefined());
1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* callback_obj = call_data->callback();
1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::InvocationCallback callback =
1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::ToCData<v8::InvocationCallback>(callback_obj);
1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the data for the call and perform the callback.
1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result;
12403e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  {
124144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    HandleScope scope(isolate);
124244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG(isolate, ApiObjectAccess("call non-function", obj));
12433e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
124444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CustomArguments custom(isolate);
12453e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
12463e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        call_data->data(), constructor, obj);
1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
12483e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        custom.end(),
12493e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        &args[0] - 1,
12503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        args.length() - 1,
12513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        is_construct_call);
1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<v8::Value> value;
1253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
125544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      VMState state(isolate, EXTERNAL);
125644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ExternalCallbackScope call_scope(isolate,
125744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                       v8::ToCData<Address>(callback_obj));
1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value = callback(new_args);
1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (value.IsEmpty()) {
126144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      result = heap->undefined_value();
1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = *reinterpret_cast<Object**>(*value);
1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for exceptions and return result.
126744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Handle calls to non-function objects created through the API. This delegate
1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function is used when the call is a normal function call.
1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(HandleApiCallAsFunction) {
127544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HandleApiCallAsFunctionOrConstructor(isolate, false, args);
1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Handle calls to non-function objects created through the API. This delegate
1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function is used when the call is a construct call.
1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(HandleApiCallAsConstructor) {
128244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HandleApiCallAsFunctionOrConstructor(isolate, true, args);
1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_ArrayLength(MacroAssembler* masm) {
1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateArrayLength(masm);
1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_StringLength(MacroAssembler* masm) {
12921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LoadIC::GenerateStringLength(masm, false);
12931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
12941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
12951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
12961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_LoadIC_StringWrapperLength(MacroAssembler* masm) {
12971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LoadIC::GenerateStringLength(masm, true);
1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) {
1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateFunctionPrototype(masm);
1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_Initialize(MacroAssembler* masm) {
1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateInitialize(masm);
1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_PreMonomorphic(MacroAssembler* masm) {
1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GeneratePreMonomorphic(masm);
1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_Miss(MacroAssembler* masm) {
1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateMiss(masm);
1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_Megamorphic(MacroAssembler* masm) {
1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateMegamorphic(masm);
1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_Normal(MacroAssembler* masm) {
1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateNormal(masm);
1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedLoadIC::GenerateInitialize(masm);
1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic void Generate_KeyedLoadIC_Slow(MacroAssembler* masm) {
1337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  KeyedLoadIC::GenerateRuntimeGetProperty(masm);
1338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1340257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) {
1342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  KeyedLoadIC::GenerateMiss(masm, false);
1343257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1345257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1346257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic void Generate_KeyedLoadIC_MissForceGeneric(MacroAssembler* masm) {
1347257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  KeyedLoadIC::GenerateMiss(masm, true);
1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) {
1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedLoadIC::GenerateGeneric(masm);
1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1356e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic void Generate_KeyedLoadIC_String(MacroAssembler* masm) {
1357e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  KeyedLoadIC::GenerateString(masm);
1358e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1359e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1360e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedLoadIC::GeneratePreMonomorphic(masm);
1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1365402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescustatic void Generate_KeyedLoadIC_IndexedInterceptor(MacroAssembler* masm) {
1366402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  KeyedLoadIC::GenerateIndexedInterceptor(masm);
1367402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
1368402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
13693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochstatic void Generate_KeyedLoadIC_NonStrictArguments(MacroAssembler* masm) {
13703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  KeyedLoadIC::GenerateNonStrictArguments(masm);
13713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_StoreIC_Initialize(MacroAssembler* masm) {
1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StoreIC::GenerateInitialize(masm);
1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_Initialize_Strict(MacroAssembler* masm) {
13791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StoreIC::GenerateInitialize(masm);
13801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
13811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
13821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_StoreIC_Miss(MacroAssembler* masm) {
1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StoreIC::GenerateMiss(masm);
1385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13888defd9ff6930b4e24729971a61cf7469daf119beSteve Blockstatic void Generate_StoreIC_Normal(MacroAssembler* masm) {
13898defd9ff6930b4e24729971a61cf7469daf119beSteve Block  StoreIC::GenerateNormal(masm);
13908defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
13918defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13928defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_Normal_Strict(MacroAssembler* masm) {
13941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StoreIC::GenerateNormal(masm);
1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
1399e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StoreIC::GenerateMegamorphic(masm, kNonStrictMode);
14003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_Megamorphic_Strict(MacroAssembler* masm) {
1404e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StoreIC::GenerateMegamorphic(masm, kStrictMode);
14053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_ArrayLength(MacroAssembler* masm) {
14091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StoreIC::GenerateArrayLength(masm);
14103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_ArrayLength_Strict(MacroAssembler* masm) {
14141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StoreIC::GenerateArrayLength(masm);
14153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) {
1419e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StoreIC::GenerateGlobalProxy(masm, kNonStrictMode);
14203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) {
1424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StoreIC::GenerateGlobalProxy(masm, kStrictMode);
14253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
1429e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  KeyedStoreIC::GenerateGeneric(masm, kNonStrictMode);
1430e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
1431e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1432e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1433e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic void Generate_KeyedStoreIC_Generic_Strict(MacroAssembler* masm) {
1434e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  KeyedStoreIC::GenerateGeneric(masm, kStrictMode);
14353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
1439257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  KeyedStoreIC::GenerateMiss(masm, false);
1440257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1441257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1442257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1443257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic void Generate_KeyedStoreIC_MissForceGeneric(MacroAssembler* masm) {
1444257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  KeyedStoreIC::GenerateMiss(masm, true);
1445257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1446257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1447257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1448257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) {
1449257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  KeyedStoreIC::GenerateSlow(masm);
1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) {
1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedStoreIC::GenerateInitialize(masm);
1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1458e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic void Generate_KeyedStoreIC_Initialize_Strict(MacroAssembler* masm) {
1459e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  KeyedStoreIC::GenerateInitialize(masm);
1460e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
1461e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
14623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochstatic void Generate_KeyedStoreIC_NonStrictArguments(MacroAssembler* masm) {
14633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  KeyedStoreIC::GenerateNonStrictArguments(masm);
14643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
1465e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
14663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void Generate_TransitionElementsSmiToDouble(MacroAssembler* masm) {
14673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedStoreIC::GenerateTransitionElementsSmiToDouble(masm);
14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
14693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void Generate_TransitionElementsDoubleToObject(MacroAssembler* masm) {
14713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KeyedStoreIC::GenerateTransitionElementsDoubleToObject(masm);
14723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
14733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateLoadICDebugBreak(masm);
1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_StoreIC_DebugBreak(MacroAssembler* masm) {
1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateStoreICDebugBreak(masm);
1482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) {
1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateKeyedLoadICDebugBreak(masm);
1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {
1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateKeyedStoreICDebugBreak(masm);
1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void Generate_Return_DebugBreak(MacroAssembler* masm) {
14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Debug::GenerateReturnDebugBreak(masm);
14975d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
14985d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
14995d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
15003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void Generate_CallFunctionStub_DebugBreak(MacroAssembler* masm) {
15013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Debug::GenerateCallFunctionStubDebugBreak(masm);
15023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
15033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void Generate_CallFunctionStub_Recording_DebugBreak(
15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MacroAssembler* masm) {
15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Debug::GenerateCallFunctionStubRecordDebugBreak(masm);
15083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
15093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
15113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void Generate_CallConstructStub_DebugBreak(MacroAssembler* masm) {
15123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Debug::GenerateCallConstructStubDebugBreak(masm);
15135d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
15145d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
15155d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
15163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void Generate_CallConstructStub_Recording_DebugBreak(
15173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    MacroAssembler* masm) {
15183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Debug::GenerateCallConstructStubRecordDebugBreak(masm);
15195d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
15205d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
15215d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
15227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochstatic void Generate_Slot_DebugBreak(MacroAssembler* masm) {
15237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Debug::GenerateSlotDebugBreak(masm);
15247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
15257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
15267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
15276ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) {
15286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Debug::GeneratePlainReturnLiveEdit(masm);
15296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
15306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
15317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
15326ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) {
15336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Debug::GenerateFrameDropperLiveEdit(masm);
15346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
153844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBuiltins::Builtins() : initialized_(false) {
153944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
154044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memset(names_, 0, sizeof(names_[0]) * builtin_count);
154144f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
154244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
154344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
154444f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBuiltins::~Builtins() {
154544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
154644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1548e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name),
154944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockAddress const Builtins::c_functions_[cfunction_count] = {
155044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BUILTIN_LIST_C(DEF_ENUM_C)
155144f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_ENUM_C
1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DEF_JS_NAME(name, ignore) #name,
1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DEF_JS_ARGC(ignore, argc) argc,
155644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockconst char* const Builtins::javascript_names_[id_count] = {
1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  BUILTINS_LIST_JS(DEF_JS_NAME)
1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
156044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint const Builtins::javascript_argc_[id_count] = {
1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  BUILTINS_LIST_JS(DEF_JS_ARGC)
1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_JS_NAME
1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_JS_ARGC
1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
156644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstruct BuiltinDesc {
156744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  byte* generator;
156844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  byte* c_code;
156944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  const char* s_name;  // name is only used for generating log information.
157044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int name;
157144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Code::Flags flags;
157244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BuiltinExtraArguments extra_args;
157344f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
15753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define BUILTIN_FUNCTION_TABLE_INIT { V8_ONCE_INIT, {} }
15763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
157744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass BuiltinFunctionTable {
157844f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
15793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  BuiltinDesc* functions() {
15803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CallOnce(&once_, &Builtins::InitBuiltinFunctionTable);
15813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return functions_;
158244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
158344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
15843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  OnceType once_;
15853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  BuiltinDesc functions_[Builtins::builtin_count + 1];
1586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
158744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class Builtins;
158844f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
158944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
15903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic BuiltinFunctionTable builtin_function_table =
15913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    BUILTIN_FUNCTION_TABLE_INIT;
159244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
159344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Define array of pointers to generators and C builtin functions.
159444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// We do this in a sort of roundabout way so that we can do the initialization
159544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// within the lexical scope of Builtins:: and within a context where
159644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Code::Flags names a non-abstract type.
159744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Builtins::InitBuiltinFunctionTable() {
15983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  BuiltinDesc* functions = builtin_function_table.functions_;
159944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].generator = NULL;
160044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].c_code = NULL;
160144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].s_name = NULL;
160244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].name = builtin_count;
160344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].flags = static_cast<Code::Flags>(0);
160444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS;
160544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
160644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define DEF_FUNCTION_PTR_C(aname, aextra_args)                         \
160744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->generator = FUNCTION_ADDR(Generate_Adaptor);            \
160844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->c_code = FUNCTION_ADDR(Builtin_##aname);                \
160944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->s_name = #aname;                                        \
161044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->name = c_##aname;                                       \
161144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->flags = Code::ComputeFlags(Code::BUILTIN);              \
161244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->extra_args = aextra_args;                               \
161344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ++functions;
161444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
161544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define DEF_FUNCTION_PTR_A(aname, kind, state, extra)                       \
161644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->generator = FUNCTION_ADDR(Generate_##aname);                 \
161744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->c_code = NULL;                                               \
161844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->s_name = #aname;                                             \
161944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->name = k##aname;                                             \
162044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->flags = Code::ComputeFlags(Code::kind,                       \
162144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                          state,                            \
162244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                          extra);                           \
162344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->extra_args = NO_EXTRA_ARGUMENTS;                             \
162444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ++functions;
162544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
162644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
162744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
162844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
1629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_FUNCTION_PTR_C
1631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_FUNCTION_PTR_A
163244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
163344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
16343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Builtins::SetUp(bool create_heap_objects) {
163544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!initialized_);
16368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = Isolate::Current();
16378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Heap* heap = isolate->heap();
163844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
163944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Create a scope for the handles in the builtins.
16408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  HandleScope scope(isolate);
164144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
16423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const BuiltinDesc* functions = builtin_function_table.functions();
1643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For now we generate builtin adaptor code into a stack-allocated
16453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // buffer, before copying it into individual code objects. Be careful
16463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // with alignment, some platforms don't like unaligned code.
16473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  union { int force_alignment; byte buffer[4*KB]; } u;
1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Traverse the list of builtins and generate an adaptor in a
1650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // separate code object for each one.
1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < builtin_count; i++) {
1652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (create_heap_objects) {
16533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      MacroAssembler masm(isolate, u.buffer, sizeof u.buffer);
1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Generate the code/adaptor.
1655e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments);
1656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Generator g = FUNCTION_CAST<Generator>(functions[i].generator);
1657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // We pass all arguments to the generator, but it may not use all of
1658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // them.  This works because the first arguments are on top of the
1659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // stack.
16603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ASSERT(!masm.has_frame());
1661e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      g(&masm, functions[i].name, functions[i].extra_args);
1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Move the code into the object heap.
1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      CodeDesc desc;
1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      masm.GetCode(&desc);
1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::Flags flags =  functions[i].flags;
1666b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      Object* code = NULL;
1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      {
1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // During startup it's OK to always allocate and defer GC to later.
1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // This simplifies things because we don't need to retry.
1670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        AlwaysAllocateScope __scope__;
16715913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        { MaybeObject* maybe_code =
167244f0eee88ff00398ff7f715fab053374d808c90dSteve Block              heap->CreateCode(desc, flags, masm.CodeObject());
16735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck          if (!maybe_code->ToObject(&code)) {
16745913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck            v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
16755913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck          }
1676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Log the event and add the code to the builtins array.
16798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      PROFILE(isolate,
168044f0eee88ff00398ff7f715fab053374d808c90dSteve Block              CodeCreateEvent(Logger::BUILTIN_TAG,
1681b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                              Code::cast(code),
1682b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                              functions[i].s_name));
1683b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      GDBJIT(AddCode(GDBJITInterface::BUILTIN,
1684b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                     functions[i].s_name,
1685b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                     Code::cast(code)));
1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      builtins_[i] = code;
1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DISASSEMBLER
1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (FLAG_print_builtin_code) {
1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        PrintF("Builtin: %s\n", functions[i].s_name);
1690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Code::cast(code)->Disassemble(functions[i].s_name);
1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        PrintF("\n");
1692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Deserializing. The values will be filled in during IterateBuiltins.
1696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      builtins_[i] = NULL;
1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    names_[i] = functions[i].s_name;
1699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Mark as initialized.
170244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  initialized_ = true;
1703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Builtins::TearDown() {
170744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  initialized_ = false;
1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Builtins::IterateBuiltins(ObjectVisitor* v) {
1712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count);
1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* Builtins::Lookup(byte* pc) {
171744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // may be called during initialization (disassembler!)
171844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (initialized_) {
1719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < builtin_count; i++) {
1720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code* entry = Code::cast(builtins_[i]);
1721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (entry->contains(pc)) {
1722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return names_[i];
1723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
1727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1729b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
173044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define DEFINE_BUILTIN_ACCESSOR_C(name, ignore)               \
173144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<Code> Builtins::name() {                               \
173244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Code** code_address =                                       \
173344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reinterpret_cast<Code**>(builtin_address(k##name));     \
173444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Handle<Code>(code_address);                          \
173544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
173644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
173744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<Code> Builtins::name() {                             \
173844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Code** code_address =                                     \
173944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reinterpret_cast<Code**>(builtin_address(k##name));   \
174044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Handle<Code>(code_address);                        \
174144f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
174244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
174344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
174444f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
174544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef DEFINE_BUILTIN_ACCESSOR_C
174644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef DEFINE_BUILTIN_ACCESSOR_A
174744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
174844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1750