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