1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 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"
36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h"
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkenamespace {
42e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
43e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Arguments object passed to C++ builtins.
44e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketemplate <BuiltinExtraArguments extra_args>
45e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeclass BuiltinArguments : public Arguments {
46e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke public:
47e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  BuiltinArguments(int length, Object** arguments)
48e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      : Arguments(length, arguments) { }
49e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
50e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Object*& operator[] (int index) {
51e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    ASSERT(index < length());
52e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::operator[](index);
53e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
54e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
55e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  template <class S> Handle<S> at(int index) {
56e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    ASSERT(index < length());
57e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::at<S>(index);
58e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
59e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
60e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Handle<Object> receiver() {
61e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::at<Object>(0);
62e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
63e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
64e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Handle<JSFunction> called_function() {
65e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION);
66e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::at<JSFunction>(Arguments::length() - 1);
67e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
68e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
69e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Gets the total number of arguments including the receiver (but
70e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // excluding extra arguments).
71e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  int length() const {
72e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS);
73e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return Arguments::length();
74e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
75e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
76e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG
77e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Verify() {
78e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    // Check we have at least the receiver.
79e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    ASSERT(Arguments::length() >= 1);
80e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
81e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif
82e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke};
83e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
84e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
85e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Specialize BuiltinArguments for the called function extra argument.
86e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
87e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketemplate <>
88e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkeint BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const {
89e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return Arguments::length() - 1;
90e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
91e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
92e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG
93e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketemplate <>
94e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() {
95e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Check we have at least the receiver and the called function.
96e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  ASSERT(Arguments::length() >= 2);
97e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Make sure cast to JSFunction succeeds.
98e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  called_function();
99e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
100e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif
101e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
102e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
103e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#define DEF_ARG_TYPE(name, spec)                      \
104e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  typedef BuiltinArguments<spec> name##ArgumentsType;
105e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBUILTIN_LIST_C(DEF_ARG_TYPE)
106e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#undef DEF_ARG_TYPE
107e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
108e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}  // namespace
109e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
111e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Support macro for defining builtins in C++.
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A builtin function is defined by writing:
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   BUILTIN(name) {
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     ...
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//   }
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
120e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// In the body of the builtin function the arguments can be accessed
121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// through the BuiltinArguments object args.
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#ifdef DEBUG
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define BUILTIN(name)                                      \
12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      name##ArgumentsType args, Isolate* isolate);         \
12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MUST_USE_RESULT static MaybeObject* Builtin_##name(      \
12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      name##ArgumentsType args, Isolate* isolate) {        \
13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(isolate == Isolate::Current());                 \
13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    args.Verify();                                         \
13244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return Builtin_Impl_##name(args, isolate);             \
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }                                                        \
13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      name##ArgumentsType args, Isolate* isolate)
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#else  // For release mode.
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define BUILTIN(name)                                      \
14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static MaybeObject* Builtin_##name(name##ArgumentsType args, Isolate* isolate)
141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
142e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#endif
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic inline bool CalledAsConstructor(Isolate* isolate) {
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calculate the result using a full stack frame iterator and check
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // that the state of the stack is as we assume it to be in the
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // code below.
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrameIterator it;
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(it.frame()->is_exit());
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  it.Advance();
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StackFrame* frame = it.frame();
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool reference_result = frame->is_construct();
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
15644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address fp = Isolate::c_entry_fp(isolate->thread_local_top());
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Because we know fp points to an exit frame we can use the relevant
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // part of ExitFrame::ComputeCallerState directly.
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const int kCallerOffset = ExitFrameConstants::kCallerFPOffset;
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Address caller_fp = Memory::Address_at(fp + kCallerOffset);
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This inlines the part of StackFrame::ComputeType that grabs the
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // type of the current frame.  Note that StackFrame::ComputeType
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // has been specialized for each architecture so if any one of them
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // changes this code has to be changed as well.
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const int kMarkerOffset = StandardFrameConstants::kMarkerOffset;
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT);
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* marker = Memory::Object_at(caller_fp + kMarkerOffset);
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result = (marker == kConstructMarker);
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT_EQ(result, reference_result);
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(Illegal) {
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
17744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->undefined_value();  // Make compiler happy.
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(EmptyFunction) {
18244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->undefined_value();
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(ArrayCodeGeneric) {
18744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
18844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->counters()->array_function_runtime()->Increment();
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSArray* array;
19144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (CalledAsConstructor(isolate)) {
192e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    array = JSArray::cast(*args.receiver());
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Allocate the JS Array
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    JSFunction* constructor =
19644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate->context()->global_context()->array_function();
1975913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* obj;
19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    { MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
1995913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2005913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    array = JSArray::cast(obj);
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 'array' now contains the JSArray we should initialize.
2058defd9ff6930b4e24729971a61cf7469daf119beSteve Block  ASSERT(array->HasFastElements());
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optimize the case where there is one argument and the argument is a
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // small smi.
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (args.length() == 2) {
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* obj = args[1];
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (obj->IsSmi()) {
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int len = Smi::cast(obj)->value();
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
2145913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        Object* obj;
21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len);
2165913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck          if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        }
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        array->SetContent(FixedArray::cast(obj));
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return array;
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Take the argument as the length.
2235913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    { MaybeObject* maybe_obj = array->Initialize(0);
2245913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2255913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return array->SetElementsLength(args[1]);
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optimize the case where there are no parameters passed.
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (args.length() == 1) {
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return array->Initialize(JSArray::kPreallocatedArrayElements);
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Take the arguments as elements.
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int number_of_elements = args.length() - 1;
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Smi* len = Smi::FromInt(number_of_elements);
2375913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* obj;
23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len->value());
2395913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
2414515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
2424515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  AssertNoAllocation no_gc;
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FixedArray* elms = FixedArray::cast(obj);
2444515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Fill in the content
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int index = 0; index < number_of_elements; index++) {
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    elms->set(index, args[index+1], mode);
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set length and elements on the array.
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  array->set_elements(FixedArray::cast(obj));
2524515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  array->set_length(len);
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return array;
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
25844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockMUST_USE_RESULT static MaybeObject* AllocateJSArray(Heap* heap) {
2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSFunction* array_function =
26044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      heap->isolate()->context()->global_context()->array_function();
2615913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* result;
26244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { MaybeObject* maybe_result = heap->AllocateJSObject(array_function);
2635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_result->ToObject(&result)) return maybe_result;
2645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
2656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return result;
2666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
2676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
26944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockMUST_USE_RESULT static MaybeObject* AllocateEmptyJSArray(Heap* heap) {
2705913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* result;
27144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { MaybeObject* maybe_result = AllocateJSArray(heap);
2725913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_result->ToObject(&result)) return maybe_result;
2735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* result_array = JSArray::cast(result);
2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  result_array->set_length(Smi::FromInt(0));
27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  result_array->set_elements(heap->empty_fixed_array());
2776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return result_array;
2786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
2796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
28144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic void CopyElements(Heap* heap,
28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                         AssertNoAllocation* no_gc,
2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         FixedArray* dst,
2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int dst_index,
2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         FixedArray* src,
2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int src_index,
2876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int len) {
2886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(dst != src);  // Use MoveElements instead.
28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(dst->map() != HEAP->fixed_cow_array_map());
2906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(len > 0);
2916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  CopyWords(dst->data_start() + dst_index,
2926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            src->data_start() + src_index,
2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            len);
2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
2956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (mode == UPDATE_WRITE_BARRIER) {
29644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
2976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic void MoveElements(Heap* heap,
30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                         AssertNoAllocation* no_gc,
3036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         FixedArray* dst,
3046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int dst_index,
3056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         FixedArray* src,
3066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int src_index,
3076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int len) {
30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(dst->map() != HEAP->fixed_cow_array_map());
3096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  memmove(dst->data_start() + dst_index,
3106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          src->data_start() + src_index,
3116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          len * kPointerSize);
3126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (mode == UPDATE_WRITE_BARRIER) {
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
31944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
32044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(dst->map() != heap->fixed_cow_array_map());
32144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
3226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
32544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic FixedArray* LeftTrimFixedArray(Heap* heap,
32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                      FixedArray* elms,
32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                      int to_trim) {
32844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(elms->map() != HEAP->fixed_cow_array_map());
329791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // For now this trick is only applied to fixed arrays in new and paged space.
3306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // In large object space the object's start must coincide with chunk
3316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and thus the trick is just not applicable.
33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!HEAP->lo_space()->Contains(elms));
3336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  STATIC_ASSERT(FixedArray::kMapOffset == 0);
3356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  STATIC_ASSERT(FixedArray::kLengthOffset == kPointerSize);
3366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  STATIC_ASSERT(FixedArray::kHeaderSize == 2 * kPointerSize);
3376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object** former_start = HeapObject::RawField(elms, 0);
3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const int len = elms->length();
3416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
342791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  if (to_trim > FixedArray::kHeaderSize / kPointerSize &&
34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      !heap->new_space()->Contains(elms)) {
344791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    // If we are doing a big trim in old space then we zap the space that was
345791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    // formerly part of the array so that the GC (aided by the card-based
346791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    // remembered set) won't find pointers to new-space there.
347791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    Object** zap = reinterpret_cast<Object**>(elms->address());
348791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    zap++;  // Header of filler must be at least one word so skip that.
349791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    for (int i = 1; i < to_trim; i++) {
350791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block      *zap++ = Smi::FromInt(0);
351791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    }
352791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  }
3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Technically in new space this write might be omitted (except for
3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // debug mode which iterates through the heap), but to play safer
3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // we still do it.
35644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  heap->CreateFillerObjectAt(elms->address(), to_trim * kPointerSize);
3576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  former_start[to_trim] = heap->fixed_array_map();
3597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  former_start[to_trim + 1] = Smi::FromInt(len - to_trim);
3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
361791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  return FixedArray::cast(HeapObject::FromAddress(
362791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block      elms->address() + to_trim * kPointerSize));
3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
36644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic bool ArrayPrototypeHasNoElements(Heap* heap,
36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                        Context* global_context,
36825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                                        JSObject* array_proto) {
3696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // This method depends on non writability of Object and Array prototype
3706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // fields.
37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (array_proto->elements() != heap->empty_fixed_array()) return false;
3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Hidden prototype
37325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  array_proto = JSObject::cast(array_proto->GetPrototype());
37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(array_proto->elements() == heap->empty_fixed_array());
3756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Object.prototype
3761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Object* proto = array_proto->GetPrototype();
37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (proto == heap->null_value()) return false;
3781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  array_proto = JSObject::cast(proto);
37925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  if (array_proto != global_context->initial_object_prototype()) return false;
38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (array_proto->elements() != heap->empty_fixed_array()) return false;
381053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  return array_proto->GetPrototype()->IsNull();
3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3855913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMUST_USE_RESULT
3865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckstatic inline MaybeObject* EnsureJSArrayWithWritableFastElements(
38744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Heap* heap, Object* receiver) {
388756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (!receiver->IsJSArray()) return NULL;
3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
3909fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  HeapObject* elms = array->elements();
39144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (elms->map() == heap->fixed_array_map()) return elms;
39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (elms->map() == heap->fixed_cow_array_map()) {
393756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    return array->EnsureWritableFastElements();
3946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
395756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return NULL;
3966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
40044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                                     JSArray* receiver) {
40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Context* global_context = heap->isolate()->context()->global_context();
40225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  JSObject* array_proto =
40325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      JSObject::cast(global_context->array_function()->prototype());
404756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return receiver->GetPrototype() == array_proto &&
40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block         ArrayPrototypeHasNoElements(heap, global_context, array_proto);
40625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
40725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
40825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
4095913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMUST_USE_RESULT static MaybeObject* CallJsBuiltin(
41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate,
4115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    const char* name,
4125913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope handleScope(isolate);
4146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<Object> js_builtin =
41644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      GetProperty(Handle<JSObject>(
41744f0eee88ff00398ff7f715fab053374d808c90dSteve Block          isolate->global_context()->builtins()),
41844f0eee88ff00398ff7f715fab053374d808c90dSteve Block          name);
4196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(js_builtin->IsJSFunction());
4206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<JSFunction> function(Handle<JSFunction>::cast(js_builtin));
42125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  ScopedVector<Object**> argv(args.length() - 1);
4226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int n_args = args.length() - 1;
4236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int i = 0; i < n_args; i++) {
4246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    argv[i] = args.at<Object>(i + 1).location();
4256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
4266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  bool pending_exception = false;
4276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<Object> result = Execution::Call(function,
4286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          args.receiver(),
4296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          n_args,
4306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          argv.start(),
4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          &pending_exception);
4326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (pending_exception) return Failure::Exception();
4336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return *result;
4346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(ArrayPush) {
43844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
4396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
4405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
4415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        EnsureJSArrayWithWritableFastElements(heap, receiver);
44344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL) {
44444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArrayPush", args);
44544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
4465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
4475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
448756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
4496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int len = Smi::cast(array->length())->value();
452402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int to_add = args.length() - 1;
453402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (to_add == 0) {
454402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    return Smi::FromInt(len);
455402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
456402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Currently fixed arrays cannot grow too big, so
457402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // we should never hit this case.
458402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(to_add <= (Smi::kMaxValue - len));
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
460402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int new_length = len + to_add;
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
462402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (new_length > elms->length()) {
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // New backing storage is needed.
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int capacity = new_length + (new_length >> 1) + 16;
4655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* obj;
46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
4675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4685913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
4696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    FixedArray* new_elms = FixedArray::cast(obj);
4704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
4714515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    AssertNoAllocation no_gc;
4726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (len > 0) {
47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len);
4746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    FillWithHoles(heap, new_elms, new_length, capacity);
4766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
477402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    elms = new_elms;
478402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    array->set_elements(elms);
479402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
480402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Add the provided values.
482402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  AssertNoAllocation no_gc;
483402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
484402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  for (int index = 0; index < to_add; index++) {
485402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    elms->set(index + len, args[index + 1], mode);
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
487402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the length.
4894515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  array->set_length(Smi::FromInt(new_length));
490402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return Smi::FromInt(new_length);
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(ArrayPop) {
49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
4966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
4975913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
4985913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
49944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        EnsureJSArrayWithWritableFastElements(heap, receiver);
50044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL) return CallJsBuiltin(isolate, "ArrayPop", args);
5015913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
5025913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
503756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
5046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int len = Smi::cast(array->length())->value();
50744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (len == 0) return heap->undefined_value();
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get top element
5105913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* top = elms->get(len - 1);
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the length.
5134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  array->set_length(Smi::FromInt(len - 1));
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!top->IsTheHole()) {
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Delete the top element.
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    elms->set_the_hole(len - 1);
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return top;
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
52125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  top = array->GetPrototype()->GetElement(len - 1);
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return top;
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
527402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(ArrayShift) {
52844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
5296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
5305913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
5315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
53244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        EnsureJSArrayWithWritableFastElements(heap, receiver);
53344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL)
53444f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArrayShift", args);
5355913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
5365913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
53744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
53844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return CallJsBuiltin(isolate, "ArrayShift", args);
5396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
540756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
5416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
542402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(array->HasFastElements());
543402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
544402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int len = Smi::cast(array->length())->value();
54544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (len == 0) return heap->undefined_value();
546402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
547402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Get first element
548402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Object* first = elms->get(0);
549402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (first->IsTheHole()) {
55044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    first = heap->undefined_value();
551402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
552402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
55344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!heap->lo_space()->Contains(elms)) {
554791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block    // As elms still in the same space they used to be,
5557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    // there is no need to update region dirty mark.
55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    array->set_elements(LeftTrimFixedArray(heap, elms, 1), SKIP_WRITE_BARRIER);
5576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
5586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Shift the elements.
5596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    AssertNoAllocation no_gc;
56044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    MoveElements(heap, &no_gc, elms, 0, elms, 1, len - 1);
56144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    elms->set(len - 1, heap->the_hole_value());
562402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
563402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
564402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Set the length.
565402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  array->set_length(Smi::FromInt(len - 1));
566402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
567402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return first;
568402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
569402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
570402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
571402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(ArrayUnshift) {
57244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
5736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
5745913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
5755913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
57644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        EnsureJSArrayWithWritableFastElements(heap, receiver);
57744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL)
57844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArrayUnshift", args);
5795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
5805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
58144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
58244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return CallJsBuiltin(isolate, "ArrayUnshift", args);
5836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
584756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
5856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
586402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(array->HasFastElements());
587402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
588402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int len = Smi::cast(array->length())->value();
589402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int to_add = args.length() - 1;
590402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int new_length = len + to_add;
591402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Currently fixed arrays cannot grow too big, so
592402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // we should never hit this case.
593402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(to_add <= (Smi::kMaxValue - len));
594402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
595402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (new_length > elms->length()) {
596402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // New backing storage is needed.
597402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    int capacity = new_length + (new_length >> 1) + 16;
5985913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* obj;
59944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
6005913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6015913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
6026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    FixedArray* new_elms = FixedArray::cast(obj);
603402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
604402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    AssertNoAllocation no_gc;
6056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (len > 0) {
60644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      CopyElements(heap, &no_gc, new_elms, to_add, elms, 0, len);
6076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    FillWithHoles(heap, new_elms, new_length, capacity);
609402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
610402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    elms = new_elms;
611402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    array->set_elements(elms);
612402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  } else {
613402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    AssertNoAllocation no_gc;
61444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    MoveElements(heap, &no_gc, elms, to_add, elms, 0, len);
615402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
616402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
617402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Add the provided values.
618402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  AssertNoAllocation no_gc;
619402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
620402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  for (int i = 0; i < to_add; i++) {
621402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    elms->set(i, args[i + 1], mode);
622402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
623402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
624402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Set the length.
625402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  array->set_length(Smi::FromInt(new_length));
626402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return Smi::FromInt(new_length);
627402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
628402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
629402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
630402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(ArraySlice) {
63144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
6326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  FixedArray* elms;
634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int len = -1;
6359fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  if (receiver->IsJSArray()) {
6369fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    JSArray* array = JSArray::cast(receiver);
6379fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    if (!array->HasFastElements() ||
63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        !IsJSArrayFastElementMovingAllowed(heap, array)) {
63944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
6409fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    }
6419fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
6429fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    elms = FixedArray::cast(array->elements());
6439fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    len = Smi::cast(array->length())->value();
6449fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  } else {
6459fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    // Array.slice(arguments, ...) is quite a common idiom (notably more
6469fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    // than 50% of invocations in Web apps).  Treat it in C++ as well.
6479fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    Map* arguments_map =
64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate->context()->global_context()->arguments_boilerplate()->map();
6499fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
6509fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    bool is_arguments_object_with_fast_elements =
6519fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block        receiver->IsJSObject()
6529fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block        && JSObject::cast(receiver)->map() == arguments_map
6539fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block        && JSObject::cast(receiver)->HasFastElements();
6549fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    if (!is_arguments_object_with_fast_elements) {
65544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
6569fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    }
6579fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    elms = FixedArray::cast(JSObject::cast(receiver)->elements());
658b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    Object* len_obj = JSObject::cast(receiver)
65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        ->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
660b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (!len_obj->IsSmi()) {
66144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
662b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
663b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    len = Smi::cast(len_obj)->value();
664b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    if (len > elms->length()) {
66544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
666b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    }
667b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch    for (int i = 0; i < len; i++) {
66844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      if (elms->get(i) == heap->the_hole_value()) {
66944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArraySlice", args);
670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(len >= 0);
674402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int n_arguments = args.length() - 1;
675402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
676402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Note carefully choosen defaults---if argument is missing,
6776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // it's undefined which gets converted to 0 for relative_start
6786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and to len for relative_end.
6796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int relative_start = 0;
6806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int relative_end = len;
681402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (n_arguments > 0) {
682402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    Object* arg1 = args[1];
683402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    if (arg1->IsSmi()) {
6846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      relative_start = Smi::cast(arg1)->value();
685402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    } else if (!arg1->IsUndefined()) {
68644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySlice", args);
687402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
688402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    if (n_arguments > 1) {
689402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      Object* arg2 = args[2];
690402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      if (arg2->IsSmi()) {
6916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        relative_end = Smi::cast(arg2)->value();
692402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      } else if (!arg2->IsUndefined()) {
69344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArraySlice", args);
694402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      }
695402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
696402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
697402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
698402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
6996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int k = (relative_start < 0) ? Max(len + relative_start, 0)
7006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               : Min(relative_start, len);
701402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
702402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
7036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int final = (relative_end < 0) ? Max(len + relative_end, 0)
7046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 : Min(relative_end, len);
705402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
706402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Calculate the length of result array.
707402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int result_len = final - k;
7086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (result_len <= 0) {
70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return AllocateEmptyJSArray(heap);
710402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
711402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
7125913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* result;
71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { MaybeObject* maybe_result = AllocateJSArray(heap);
7145913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_result->ToObject(&result)) return maybe_result;
7155913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
716402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  JSArray* result_array = JSArray::cast(result);
717402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
7185913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_result =
71944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        heap->AllocateUninitializedFixedArray(result_len);
7205913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_result->ToObject(&result)) return maybe_result;
7215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
722402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  FixedArray* result_elms = FixedArray::cast(result);
723402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
724402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  AssertNoAllocation no_gc;
72544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len);
726402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
727402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Set elements.
728402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  result_array->set_elements(result_elms);
729402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
730402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Set the length.
731402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  result_array->set_length(Smi::FromInt(result_len));
732402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return result_array;
733402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
734402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
735402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
736402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(ArraySplice) {
73744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
7386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Object* receiver = *args.receiver();
7395913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* elms_obj;
7405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_elms_obj =
74144f0eee88ff00398ff7f715fab053374d808c90dSteve Block        EnsureJSArrayWithWritableFastElements(heap, receiver);
74244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (maybe_elms_obj == NULL)
74344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArraySplice", args);
7445913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
7455913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
74644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
74744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return CallJsBuiltin(isolate, "ArraySplice", args);
7486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
749756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  FixedArray* elms = FixedArray::cast(elms_obj);
7506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* array = JSArray::cast(receiver);
751402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(array->HasFastElements());
752402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
753402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int len = Smi::cast(array->length())->value();
754402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
755402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int n_arguments = args.length() - 1;
756402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
7576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int relative_start = 0;
7581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (n_arguments > 0) {
7591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Object* arg1 = args[1];
7601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (arg1->IsSmi()) {
7611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      relative_start = Smi::cast(arg1)->value();
7621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    } else if (!arg1->IsUndefined()) {
76344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArraySplice", args);
7641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
765402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
7666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
7676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                          : Min(relative_start, len);
768402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
769402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
7701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // given as a request to delete all the elements from the start.
7711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // And it differs from the case of undefined delete count.
772402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // This does not follow ECMA-262, but we do the same for
773402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // compatibility.
7741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int actual_delete_count;
7751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (n_arguments == 1) {
7761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    ASSERT(len - actual_start >= 0);
7771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    actual_delete_count = len - actual_start;
7781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
7791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    int value = 0;  // ToInteger(undefined) == 0
7801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (n_arguments > 1) {
7811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      Object* arg2 = args[2];
7821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      if (arg2->IsSmi()) {
7831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        value = Smi::cast(arg2)->value();
7841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      } else {
78544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return CallJsBuiltin(isolate, "ArraySplice", args);
7861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      }
787402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
7881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    actual_delete_count = Min(Max(value, 0), len - actual_start);
789402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
790402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
7916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* result_array = NULL;
7926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (actual_delete_count == 0) {
7935913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* result;
79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    { MaybeObject* maybe_result = AllocateEmptyJSArray(heap);
7955913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_result->ToObject(&result)) return maybe_result;
7965913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
7976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result_array = JSArray::cast(result);
7986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
7996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Allocate result array.
8005913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* result;
80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    { MaybeObject* maybe_result = AllocateJSArray(heap);
8025913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_result->ToObject(&result)) return maybe_result;
8035913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
8046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result_array = JSArray::cast(result);
805402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8065913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    { MaybeObject* maybe_result =
80744f0eee88ff00398ff7f715fab053374d808c90dSteve Block          heap->AllocateUninitializedFixedArray(actual_delete_count);
8085913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_result->ToObject(&result)) return maybe_result;
8095913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
8106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    FixedArray* result_elms = FixedArray::cast(result);
811402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    AssertNoAllocation no_gc;
8136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Fill newly created array.
81444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CopyElements(heap,
81544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                 &no_gc,
8166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                 result_elms, 0,
8176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                 elms, actual_start,
8186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                 actual_delete_count);
819402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Set elements.
8216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result_array->set_elements(result_elms);
822402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Set the length.
8246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result_array->set_length(Smi::FromInt(actual_delete_count));
825402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
826402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
828402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int new_length = len - actual_delete_count + item_count;
830402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (item_count < actual_delete_count) {
832402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // Shrink the array.
83344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    const bool trim_array = !heap->lo_space()->Contains(elms) &&
8346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      ((actual_start + item_count) <
8356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          (len - actual_delete_count - actual_start));
8366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (trim_array) {
8376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      const int delta = actual_delete_count - item_count;
8386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
8396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (actual_start > 0) {
840053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block        AssertNoAllocation no_gc;
841053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block        MoveElements(heap, &no_gc, elms, delta, elms, 0, actual_start);
8426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
843402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
84444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      elms = LeftTrimFixedArray(heap, elms, delta);
8456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      array->set_elements(elms, SKIP_WRITE_BARRIER);
8466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    } else {
8476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      AssertNoAllocation no_gc;
84844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      MoveElements(heap, &no_gc,
8496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   elms, actual_start + item_count,
8506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   elms, actual_start + actual_delete_count,
8516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   (len - actual_delete_count - actual_start));
85244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      FillWithHoles(heap, elms, new_length, len);
853402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
8546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else if (item_count > actual_delete_count) {
855402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // Currently fixed arrays cannot grow too big, so
856402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // we should never hit this case.
8576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
858402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
859402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // Check if array need to grow.
860402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    if (new_length > elms->length()) {
861402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      // New backing storage is needed.
862402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      int capacity = new_length + (new_length >> 1) + 16;
8635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      Object* obj;
8645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      { MaybeObject* maybe_obj =
86544f0eee88ff00398ff7f715fab053374d808c90dSteve Block            heap->AllocateUninitializedFixedArray(capacity);
8665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      }
868402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      FixedArray* new_elms = FixedArray::cast(obj);
869402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      AssertNoAllocation no_gc;
8716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      // Copy the part before actual_start as is.
8726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (actual_start > 0) {
87344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        CopyElements(heap, &no_gc, new_elms, 0, elms, 0, actual_start);
874402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      }
8756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      const int to_copy = len - actual_delete_count - actual_start;
8766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (to_copy > 0) {
87744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        CopyElements(heap, &no_gc,
8786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     new_elms, actual_start + item_count,
8796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     elms, actual_start + actual_delete_count,
8806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     to_copy);
8816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
88244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      FillWithHoles(heap, new_elms, new_length, capacity);
883402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
884402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      elms = new_elms;
885402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      array->set_elements(elms);
8866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    } else {
8876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      AssertNoAllocation no_gc;
88844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      MoveElements(heap, &no_gc,
8896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   elms, actual_start + item_count,
8906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   elms, actual_start + actual_delete_count,
8916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                   (len - actual_delete_count - actual_start));
892402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
893402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
894402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
8956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  AssertNoAllocation no_gc;
8966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
8976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int k = actual_start; k < actual_start + item_count; k++) {
8986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    elms->set(k, args[3 + k - actual_start], mode);
899402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
900402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
901402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Set the length.
902402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  array->set_length(Smi::FromInt(new_length));
903402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
904402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return result_array;
905402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
906402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
907402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
9086ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockBUILTIN(ArrayConcat) {
90944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
91044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Context* global_context = isolate->context()->global_context();
91125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  JSObject* array_proto =
91225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      JSObject::cast(global_context->array_function()->prototype());
91344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!ArrayPrototypeHasNoElements(heap, global_context, array_proto)) {
91444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return CallJsBuiltin(isolate, "ArrayConcat", args);
9156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
9166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Iterate through all the arguments performing checks
9186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and calculating total length.
9196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int n_arguments = args.length();
9206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int result_len = 0;
9216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int i = 0; i < n_arguments; i++) {
9226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Object* arg = args[i];
92325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen    if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements()
92425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen        || JSArray::cast(arg)->GetPrototype() != array_proto) {
92544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArrayConcat", args);
9266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
9276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int len = Smi::cast(JSArray::cast(arg)->length())->value();
9296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // We shouldn't overflow when adding another len.
9316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
9326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
9336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    USE(kHalfOfMaxInt);
9346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result_len += len;
9356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(result_len >= 0);
9366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (result_len > FixedArray::kMaxLength) {
93844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return CallJsBuiltin(isolate, "ArrayConcat", args);
9396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
9406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
9416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (result_len == 0) {
94344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return AllocateEmptyJSArray(heap);
9446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
9456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Allocate result.
9475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* result;
94844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { MaybeObject* maybe_result = AllocateJSArray(heap);
9495913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_result->ToObject(&result)) return maybe_result;
9505913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
9516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  JSArray* result_array = JSArray::cast(result);
9526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9535913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_result =
95444f0eee88ff00398ff7f715fab053374d808c90dSteve Block        heap->AllocateUninitializedFixedArray(result_len);
9555913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_result->ToObject(&result)) return maybe_result;
9565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
9576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  FixedArray* result_elms = FixedArray::cast(result);
9586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Copy data.
9606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  AssertNoAllocation no_gc;
9616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int start_pos = 0;
9626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int i = 0; i < n_arguments; i++) {
9636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    JSArray* array = JSArray::cast(args[i]);
9646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int len = Smi::cast(array->length())->value();
9656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (len > 0) {
9666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      FixedArray* elms = FixedArray::cast(array->elements());
96744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      CopyElements(heap, &no_gc, result_elms, start_pos, elms, 0, len);
9686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      start_pos += len;
9696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
9706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
9716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(start_pos == result_len);
9726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Set the length and elements.
9746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  result_array->set_length(Smi::FromInt(result_len));
9756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  result_array->set_elements(result_elms);
9766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return result_array;
9786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
9796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
98244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Strict mode poison pills
98344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
98444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
98544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN(StrictArgumentsCallee) {
98644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope;
98744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->Throw(*isolate->factory()->NewTypeError(
98844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
98944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
99044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
99144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
99244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN(StrictArgumentsCaller) {
99344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope;
99444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->Throw(*isolate->factory()->NewTypeError(
99544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      "strict_arguments_caller", HandleVector<Object>(NULL, 0)));
99644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
99744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
99844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
99944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN(StrictFunctionCaller) {
100044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope;
100144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->Throw(*isolate->factory()->NewTypeError(
100244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      "strict_function_caller", HandleVector<Object>(NULL, 0)));
100344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
100444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
100544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
100644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN(StrictFunctionArguments) {
100744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope;
100844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->Throw(*isolate->factory()->NewTypeError(
100944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      "strict_function_arguments", HandleVector<Object>(NULL, 0)));
101044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
101144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
101244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
101344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// -----------------------------------------------------------------------------
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the holder JSObject if the function can legally be called
1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with this receiver.  Returns Heap::null_value() if the call is
1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// illegal.  Any arguments that don't fit the expected type is
1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// overwritten with undefined.  Arguments that do fit the expected
1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// type is overwritten with the object in the prototype chain that
1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// actually has that type.
102344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic inline Object* TypeCheck(Heap* heap,
102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                int argc,
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                Object** argv,
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                FunctionTemplateInfo* info) {
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* recv = argv[0];
1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* sig_obj = info->signature();
1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (sig_obj->IsUndefined()) return recv;
1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SignatureInfo* sig = SignatureInfo::cast(sig_obj);
1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If necessary, check the receiver
1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* recv_type = sig->receiver();
1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* holder = recv;
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!recv_type->IsUndefined()) {
103644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    for (; holder != heap->null_value(); holder = holder->GetPrototype()) {
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (holder->IsInstanceOf(FunctionTemplateInfo::cast(recv_type))) {
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
104144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (holder == heap->null_value()) return holder;
1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* args_obj = sig->args();
1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If there is no argument signature we're done
1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (args_obj->IsUndefined()) return holder;
1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FixedArray* args = FixedArray::cast(args_obj);
1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int length = args->length();
1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (argc <= length) length = argc - 1;
1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < length; i++) {
1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* argtype = args->get(i);
1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (argtype->IsUndefined()) continue;
1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object** arg = &argv[-1 - i];
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* current = *arg;
105444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    for (; current != heap->null_value(); current = current->GetPrototype()) {
1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (current->IsInstanceOf(FunctionTemplateInfo::cast(argtype))) {
1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        *arg = current;
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
106044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (current == heap->null_value()) *arg = heap->undefined_value();
1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return holder;
1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1066e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketemplate <bool is_construct>
10675913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
106844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) {
106944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(is_construct == CalledAsConstructor(isolate));
107044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
107244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
1073e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Handle<JSFunction> function = args.called_function();
10746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(function->shared()->IsApiFunction());
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data();
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_construct) {
107844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FunctionTemplateInfo> desc(fun_data, isolate);
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool pending_exception = false;
108044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->factory()->ConfigureInstance(
108144f0eee88ff00398ff7f715fab053374d808c90dSteve Block        desc, Handle<JSObject>::cast(args.receiver()), &pending_exception);
108244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(isolate->has_pending_exception() == pending_exception);
1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (pending_exception) return Failure::Exception();
10846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    fun_data = *desc;
1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* raw_holder = TypeCheck(heap, args.length(), &args[0], fun_data);
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (raw_holder->IsNull()) {
1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // This function cannot be called with the given receiver.  Abort!
1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Object> obj =
109244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate->factory()->NewTypeError(
109344f0eee88ff00398ff7f715fab053374d808c90dSteve Block            "illegal_invocation", HandleVector(&function, 1));
109444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate->Throw(*obj);
1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* raw_call_data = fun_data->call_code();
1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!raw_call_data->IsUndefined()) {
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* callback_obj = call_data->callback();
1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::InvocationCallback callback =
1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        v8::ToCData<v8::InvocationCallback>(callback_obj);
1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* data_obj = call_data->data();
1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* result;
1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
110644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
11073e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    ASSERT(raw_holder->IsJSObject());
11083e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
110944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CustomArguments custom(isolate);
11103e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
11113e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        data_obj, *function, raw_holder);
11123e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
11143e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        custom.end(),
11153e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        &args[0] - 1,
11163e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        args.length() - 1,
11173e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        is_construct);
1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<v8::Value> value;
1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
112244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      VMState state(isolate, EXTERNAL);
112344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ExternalCallbackScope call_scope(isolate,
112444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                       v8::ToCData<Address>(callback_obj));
1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value = callback(new_args);
1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (value.IsEmpty()) {
112844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      result = heap->undefined_value();
1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = *reinterpret_cast<Object**>(*value);
1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!is_construct || result->IsJSObject()) return result;
1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1137e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return *args.receiver();
1138e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1139e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1140e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1141e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBUILTIN(HandleApiCall) {
114244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HandleApiCallHelper<false>(args, isolate);
1143e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1144e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1145e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1146e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon ClarkeBUILTIN(HandleApiCallConstruct) {
114744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HandleApiCallHelper<true>(args, isolate);
1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1151402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#ifdef DEBUG
1152402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1153402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescustatic void VerifyTypeCheck(Handle<JSObject> object,
1154402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                            Handle<JSFunction> function) {
11556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(function->shared()->IsApiFunction());
11566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  FunctionTemplateInfo* info = function->shared()->get_api_func_data();
1157402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (info->signature()->IsUndefined()) return;
1158402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  SignatureInfo* signature = SignatureInfo::cast(info->signature());
1159402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Object* receiver_type = signature->receiver();
1160402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (receiver_type->IsUndefined()) return;
1161402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  FunctionTemplateInfo* type = FunctionTemplateInfo::cast(receiver_type);
1162402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(object->IsInstanceOf(type));
1163402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
1164402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1165402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu#endif
1166402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1167402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1168402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuBUILTIN(FastHandleApiCall) {
116944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!CalledAsConstructor(isolate));
117044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
1171402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  const bool is_construct = false;
1172402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
11738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // We expect four more arguments: callback, function, call data, and holder.
1174402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  const int args_length = args.length() - 4;
1175402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  ASSERT(args_length >= 0);
1176402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
11778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  Object* callback_obj = args[args_length];
1178402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1179402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
11808a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      &args[args_length + 1],
11813e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      &args[0] - 1,
11823e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      args_length - 1,
11833e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu      is_construct);
1184402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
11858a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#ifdef DEBUG
11868a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  VerifyTypeCheck(Utils::OpenHandle(*new_args.Holder()),
11878a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                  Utils::OpenHandle(*new_args.Callee()));
11888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#endif
118944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
1190402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Object* result;
1191402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  v8::Handle<v8::Value> value;
1192402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  {
1193402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    // Leaving JavaScript.
119444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    VMState state(isolate, EXTERNAL);
119544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExternalCallbackScope call_scope(isolate,
119644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                     v8::ToCData<Address>(callback_obj));
11973e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    v8::InvocationCallback callback =
11983e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        v8::ToCData<v8::InvocationCallback>(callback_obj);
11993e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
1200402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    value = callback(new_args);
1201402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
1202402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (value.IsEmpty()) {
120344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    result = heap->undefined_value();
1204402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  } else {
1205402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    result = *reinterpret_cast<Object**>(*value);
1206402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
1207402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
120844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1209402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return result;
1210402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
1211402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1212402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function to handle calls to non-function objects created through the
1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// API. The object can be called as either a constructor (using new) or just as
1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a function (without new).
12165913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
121744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate,
1218e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    bool is_construct_call,
1219e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Non-functions are never called as constructors. Even if this is an object
1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // called as a constructor the delegate call is not a construct call.
122244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!CalledAsConstructor(isolate));
122344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = isolate->heap();
1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> receiver = args.at<Object>(0);
1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the object called.
1228e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  JSObject* obj = JSObject::cast(*args.receiver());
1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the invocation callback from the function descriptor that was
1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // used to create the called object.
1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(obj->map()->has_instance_call_handler());
1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSFunction* constructor = JSFunction::cast(obj->map()->constructor());
12346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(constructor->shared()->IsApiFunction());
1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* handler =
12366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      constructor->shared()->get_api_func_data()->instance_call_handler();
1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!handler->IsUndefined());
1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* callback_obj = call_data->callback();
1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::InvocationCallback callback =
1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::ToCData<v8::InvocationCallback>(callback_obj);
1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the data for the call and perform the callback.
1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* result;
12453e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  {
124644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    HandleScope scope(isolate);
124744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG(isolate, ApiObjectAccess("call non-function", obj));
12483e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
124944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CustomArguments custom(isolate);
12503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
12513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        call_data->data(), constructor, obj);
1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
12533e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        custom.end(),
12543e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        &args[0] - 1,
12553e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        args.length() - 1,
12563e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        is_construct_call);
1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<v8::Value> value;
1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
126044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      VMState state(isolate, EXTERNAL);
126144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ExternalCallbackScope call_scope(isolate,
126244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                       v8::ToCData<Address>(callback_obj));
1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value = callback(new_args);
1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (value.IsEmpty()) {
126644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      result = heap->undefined_value();
1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = *reinterpret_cast<Object**>(*value);
1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for exceptions and return result.
127244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Handle calls to non-function objects created through the API. This delegate
1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function is used when the call is a normal function call.
1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(HandleApiCallAsFunction) {
128044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HandleApiCallAsFunctionOrConstructor(isolate, false, args);
1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Handle calls to non-function objects created through the API. This delegate
1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function is used when the call is a construct call.
1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockBUILTIN(HandleApiCallAsConstructor) {
128744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HandleApiCallAsFunctionOrConstructor(isolate, true, args);
1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_ArrayLength(MacroAssembler* masm) {
1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateArrayLength(masm);
1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_StringLength(MacroAssembler* masm) {
12971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LoadIC::GenerateStringLength(masm, false);
12981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
12991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
13001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
13011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_LoadIC_StringWrapperLength(MacroAssembler* masm) {
13021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  LoadIC::GenerateStringLength(masm, true);
1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_FunctionPrototype(MacroAssembler* masm) {
1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateFunctionPrototype(masm);
1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_Initialize(MacroAssembler* masm) {
1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateInitialize(masm);
1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_PreMonomorphic(MacroAssembler* masm) {
1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GeneratePreMonomorphic(masm);
1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_Miss(MacroAssembler* masm) {
1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateMiss(masm);
1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_Megamorphic(MacroAssembler* masm) {
1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateMegamorphic(masm);
1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_Normal(MacroAssembler* masm) {
1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadIC::GenerateNormal(masm);
1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedLoadIC::GenerateInitialize(masm);
1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) {
1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedLoadIC::GenerateMiss(masm);
1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) {
1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedLoadIC::GenerateGeneric(masm);
1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1351e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkestatic void Generate_KeyedLoadIC_String(MacroAssembler* masm) {
1352e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  KeyedLoadIC::GenerateString(masm);
1353e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1354e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1355e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedLoadIC::GeneratePreMonomorphic(masm);
1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1360402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescustatic void Generate_KeyedLoadIC_IndexedInterceptor(MacroAssembler* masm) {
1361402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  KeyedLoadIC::GenerateIndexedInterceptor(masm);
1362402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
1363402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_StoreIC_Initialize(MacroAssembler* masm) {
1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StoreIC::GenerateInitialize(masm);
1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_Initialize_Strict(MacroAssembler* masm) {
13711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StoreIC::GenerateInitialize(masm);
13721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
13731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
13741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_StoreIC_Miss(MacroAssembler* masm) {
1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StoreIC::GenerateMiss(masm);
1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13808defd9ff6930b4e24729971a61cf7469daf119beSteve Blockstatic void Generate_StoreIC_Normal(MacroAssembler* masm) {
13818defd9ff6930b4e24729971a61cf7469daf119beSteve Block  StoreIC::GenerateNormal(masm);
13828defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
13838defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13848defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_Normal_Strict(MacroAssembler* masm) {
13861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StoreIC::GenerateNormal(masm);
1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_Megamorphic(MacroAssembler* masm) {
1391e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StoreIC::GenerateMegamorphic(masm, kNonStrictMode);
13923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
13933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
13943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
13951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_Megamorphic_Strict(MacroAssembler* masm) {
1396e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StoreIC::GenerateMegamorphic(masm, kStrictMode);
13973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
13983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
13993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_ArrayLength(MacroAssembler* masm) {
14011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StoreIC::GenerateArrayLength(masm);
14023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_ArrayLength_Strict(MacroAssembler* masm) {
14061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StoreIC::GenerateArrayLength(masm);
14073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_GlobalProxy(MacroAssembler* masm) {
1411e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StoreIC::GenerateGlobalProxy(masm, kNonStrictMode);
14123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_StoreIC_GlobalProxy_Strict(MacroAssembler* masm) {
1416e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  StoreIC::GenerateGlobalProxy(masm, kStrictMode);
14173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockstatic void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
1421e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  KeyedStoreIC::GenerateGeneric(masm, kNonStrictMode);
1422e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
1423e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1425e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic void Generate_KeyedStoreIC_Generic_Strict(MacroAssembler* masm) {
1426e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  KeyedStoreIC::GenerateGeneric(masm, kStrictMode);
14273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
14283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
14293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedStoreIC::GenerateMiss(masm);
1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) {
1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  KeyedStoreIC::GenerateInitialize(masm);
1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1440e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic void Generate_KeyedStoreIC_Initialize_Strict(MacroAssembler* masm) {
1441e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  KeyedStoreIC::GenerateInitialize(masm);
1442e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
1443e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1444e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateLoadICDebugBreak(masm);
1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_StoreIC_DebugBreak(MacroAssembler* masm) {
1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateStoreICDebugBreak(masm);
1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) {
1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateKeyedLoadICDebugBreak(masm);
1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {
1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateKeyedStoreICDebugBreak(masm);
1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_ConstructCall_DebugBreak(MacroAssembler* masm) {
1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateConstructCallDebugBreak(masm);
1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_Return_DebugBreak(MacroAssembler* masm) {
1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateReturnDebugBreak(masm);
1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) {
1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debug::GenerateStubNoRegistersDebugBreak(masm);
1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
14796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
14807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
14817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochstatic void Generate_Slot_DebugBreak(MacroAssembler* masm) {
14827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Debug::GenerateSlotDebugBreak(masm);
14837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
14847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
14857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
14866ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) {
14876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Debug::GeneratePlainReturnLiveEdit(masm);
14886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
14896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
14907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
14916ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) {
14926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Debug::GenerateFrameDropperLiveEdit(masm);
14936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
149644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
149744f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBuiltins::Builtins() : initialized_(false) {
149844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
149944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  memset(names_, 0, sizeof(names_[0]) * builtin_count);
150044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
150144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
150244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
150344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBuiltins::~Builtins() {
150444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
150544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1507e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name),
150844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockAddress const Builtins::c_functions_[cfunction_count] = {
150944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BUILTIN_LIST_C(DEF_ENUM_C)
151044f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_ENUM_C
1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DEF_JS_NAME(name, ignore) #name,
1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DEF_JS_ARGC(ignore, argc) argc,
151544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockconst char* const Builtins::javascript_names_[id_count] = {
1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  BUILTINS_LIST_JS(DEF_JS_NAME)
1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
151944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint const Builtins::javascript_argc_[id_count] = {
1520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  BUILTINS_LIST_JS(DEF_JS_ARGC)
1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_JS_NAME
1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_JS_ARGC
1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
152544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstruct BuiltinDesc {
152644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  byte* generator;
152744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  byte* c_code;
152844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  const char* s_name;  // name is only used for generating log information.
152944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int name;
153044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Code::Flags flags;
153144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BuiltinExtraArguments extra_args;
153244f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
153444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass BuiltinFunctionTable {
153544f0eee88ff00398ff7f715fab053374d808c90dSteve Block public:
153644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BuiltinFunctionTable() {
153744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Builtins::InitBuiltinFunctionTable();
153844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
153944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
154044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static const BuiltinDesc* functions() { return functions_; }
154144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
154244f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
154344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  static BuiltinDesc functions_[Builtins::builtin_count + 1];
1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
154544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class Builtins;
154644f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
154744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
154844f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBuiltinDesc BuiltinFunctionTable::functions_[Builtins::builtin_count + 1];
154944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
155044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const BuiltinFunctionTable builtin_function_table_init;
155144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
155244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Define array of pointers to generators and C builtin functions.
155344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// We do this in a sort of roundabout way so that we can do the initialization
155444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// within the lexical scope of Builtins:: and within a context where
155544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Code::Flags names a non-abstract type.
155644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Builtins::InitBuiltinFunctionTable() {
155744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BuiltinDesc* functions = BuiltinFunctionTable::functions_;
155844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].generator = NULL;
155944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].c_code = NULL;
156044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].s_name = NULL;
156144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].name = builtin_count;
156244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].flags = static_cast<Code::Flags>(0);
156344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS;
156444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
156544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define DEF_FUNCTION_PTR_C(aname, aextra_args)                         \
156644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->generator = FUNCTION_ADDR(Generate_Adaptor);            \
156744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->c_code = FUNCTION_ADDR(Builtin_##aname);                \
156844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->s_name = #aname;                                        \
156944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->name = c_##aname;                                       \
157044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->flags = Code::ComputeFlags(Code::BUILTIN);              \
157144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->extra_args = aextra_args;                               \
157244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ++functions;
157344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
157444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define DEF_FUNCTION_PTR_A(aname, kind, state, extra)                       \
157544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->generator = FUNCTION_ADDR(Generate_##aname);                 \
157644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->c_code = NULL;                                               \
157744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->s_name = #aname;                                             \
157844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->name = k##aname;                                             \
157944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->flags = Code::ComputeFlags(Code::kind,                       \
158044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                          NOT_IN_LOOP,                      \
158144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                          state,                            \
158244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                          extra);                           \
158344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    functions->extra_args = NO_EXTRA_ARGUMENTS;                             \
158444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ++functions;
158544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
158644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
158744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
158844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
1589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_FUNCTION_PTR_C
1591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_FUNCTION_PTR_A
159244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
159344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
159444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Builtins::Setup(bool create_heap_objects) {
159544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!initialized_);
15968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = Isolate::Current();
15978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Heap* heap = isolate->heap();
159844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
159944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Create a scope for the handles in the builtins.
16008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  HandleScope scope(isolate);
160144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
160244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  const BuiltinDesc* functions = BuiltinFunctionTable::functions();
1603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // For now we generate builtin adaptor code into a stack-allocated
1605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // buffer, before copying it into individual code objects.
1606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte buffer[4*KB];
1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Traverse the list of builtins and generate an adaptor in a
1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // separate code object for each one.
1610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < builtin_count; i++) {
1611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (create_heap_objects) {
16128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      MacroAssembler masm(isolate, buffer, sizeof buffer);
1613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Generate the code/adaptor.
1614e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments);
1615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Generator g = FUNCTION_CAST<Generator>(functions[i].generator);
1616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // We pass all arguments to the generator, but it may not use all of
1617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // them.  This works because the first arguments are on top of the
1618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // stack.
1619e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      g(&masm, functions[i].name, functions[i].extra_args);
1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Move the code into the object heap.
1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      CodeDesc desc;
1622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      masm.GetCode(&desc);
1623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code::Flags flags =  functions[i].flags;
1624b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      Object* code = NULL;
1625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      {
1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // During startup it's OK to always allocate and defer GC to later.
1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // This simplifies things because we don't need to retry.
1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        AlwaysAllocateScope __scope__;
16295913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        { MaybeObject* maybe_code =
163044f0eee88ff00398ff7f715fab053374d808c90dSteve Block              heap->CreateCode(desc, flags, masm.CodeObject());
16315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck          if (!maybe_code->ToObject(&code)) {
16325913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck            v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
16335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck          }
1634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        }
1635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Log the event and add the code to the builtins array.
16378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      PROFILE(isolate,
163844f0eee88ff00398ff7f715fab053374d808c90dSteve Block              CodeCreateEvent(Logger::BUILTIN_TAG,
1639b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                              Code::cast(code),
1640b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                              functions[i].s_name));
1641b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch      GDBJIT(AddCode(GDBJITInterface::BUILTIN,
1642b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                     functions[i].s_name,
1643b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                     Code::cast(code)));
1644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      builtins_[i] = code;
1645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DISASSEMBLER
1646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (FLAG_print_builtin_code) {
1647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        PrintF("Builtin: %s\n", functions[i].s_name);
1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Code::cast(code)->Disassemble(functions[i].s_name);
1649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        PrintF("\n");
1650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Deserializing. The values will be filled in during IterateBuiltins.
1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      builtins_[i] = NULL;
1655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    names_[i] = functions[i].s_name;
1657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Mark as initialized.
166044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  initialized_ = true;
1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Builtins::TearDown() {
166544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  initialized_ = false;
1666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Builtins::IterateBuiltins(ObjectVisitor* v) {
1670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count);
1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* Builtins::Lookup(byte* pc) {
167544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // may be called during initialization (disassembler!)
167644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (initialized_) {
1677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < builtin_count; i++) {
1678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Code* entry = Code::cast(builtins_[i]);
1679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (entry->contains(pc)) {
1680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return names_[i];
1681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
1685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1687b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
168844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define DEFINE_BUILTIN_ACCESSOR_C(name, ignore)               \
168944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<Code> Builtins::name() {                               \
169044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Code** code_address =                                       \
169144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reinterpret_cast<Code**>(builtin_address(k##name));     \
169244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Handle<Code>(code_address);                          \
169344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
169444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
169544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<Code> Builtins::name() {                             \
169644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Code** code_address =                                     \
169744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      reinterpret_cast<Code**>(builtin_address(k##name));   \
169844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Handle<Code>(code_address);                        \
169944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
170044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
170144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
170244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockBUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
170344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef DEFINE_BUILTIN_ACCESSOR_C
170444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#undef DEFINE_BUILTIN_ACCESSOR_A
170544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
170644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1708