1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h" 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arguments.h" 91e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/once.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/builtins.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/gdb-jit.h" 143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/mark-compact.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/heap-profiler.h" 166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/handler-compiler.h" 17a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/ic.h" 189bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#include "src/prototype.h" 19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/vm-state-inl.h" 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 2271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgnamespace { 25b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 26b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Arguments object passed to C++ builtins. 27b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgtemplate <BuiltinExtraArguments extra_args> 28b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass BuiltinArguments : public Arguments { 29b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public: 30b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BuiltinArguments(int length, Object** arguments) 31b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org : Arguments(length, arguments) { } 32b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 33b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Object*& operator[] (int index) { 34e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index < length()); 35b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return Arguments::operator[](index); 36b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 37b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 38b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org template <class S> Handle<S> at(int index) { 39e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index < length()); 40b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return Arguments::at<S>(index); 41b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 42b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 43b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Handle<Object> receiver() { 44b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return Arguments::at<Object>(0); 45b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 46b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 47b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Handle<JSFunction> called_function() { 48b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION); 49b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return Arguments::at<JSFunction>(Arguments::length() - 1); 50b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 51b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 52b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Gets the total number of arguments including the receiver (but 53b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // excluding extra arguments). 54b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int length() const { 55b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS); 56b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return Arguments::length(); 57b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 58b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 59b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef DEBUG 60b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void Verify() { 61b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Check we have at least the receiver. 62e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Arguments::length() >= 1); 63b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 64b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif 65b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}; 66b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 67b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 68b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Specialize BuiltinArguments for the called function extra argument. 69b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 70b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgtemplate <> 71b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgint BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const { 72b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return Arguments::length() - 1; 73b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 74b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 75b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef DEBUG 76b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgtemplate <> 77b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() { 78b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Check we have at least the receiver and the called function. 79e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Arguments::length() >= 2); 80b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Make sure cast to JSFunction succeeds. 81b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org called_function(); 82b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 83b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif 84b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 85b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 86b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#define DEF_ARG_TYPE(name, spec) \ 87b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org typedef BuiltinArguments<spec> name##ArgumentsType; 88b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgBUILTIN_LIST_C(DEF_ARG_TYPE) 89b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#undef DEF_ARG_TYPE 90b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 91b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} // namespace 92b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 94b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Support macro for defining builtins in C++. 9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A builtin function is defined by writing: 9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 99b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org// BUILTIN(name) { 10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ... 10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// } 10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 103b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// In the body of the builtin function the arguments can be accessed 104b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// through the BuiltinArguments object args. 10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 106b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef DEBUG 10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 108f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org#define BUILTIN(name) \ 109a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org MUST_USE_RESULT static Object* Builtin_Impl_##name( \ 110f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name##ArgumentsType args, Isolate* isolate); \ 111a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org MUST_USE_RESULT static Object* Builtin_##name( \ 112f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int args_length, Object** args_object, Isolate* isolate) { \ 113f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name##ArgumentsType args(args_length, args_object); \ 114f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org args.Verify(); \ 115f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org return Builtin_Impl_##name(args, isolate); \ 116f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } \ 117a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org MUST_USE_RESULT static Object* Builtin_Impl_##name( \ 118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org name##ArgumentsType args, Isolate* isolate) 11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#else // For release mode. 12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 122f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org#define BUILTIN(name) \ 123a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org static Object* Builtin_impl##name( \ 124f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name##ArgumentsType args, Isolate* isolate); \ 125a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org static Object* Builtin_##name( \ 126f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int args_length, Object** args_object, Isolate* isolate) { \ 127f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name##ArgumentsType args(args_length, args_object); \ 128f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org return Builtin_impl##name(args, isolate); \ 129f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } \ 130a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org static Object* Builtin_impl##name( \ 131f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name##ArgumentsType args, Isolate* isolate) 132b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif 13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1350b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org#ifdef DEBUG 136afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.orgstatic inline bool CalledAsConstructor(Isolate* isolate) { 1370b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Calculate the result using a full stack frame iterator and check 1380b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // that the state of the stack is as we assume it to be in the 1390b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // code below. 140c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org StackFrameIterator it(isolate); 141e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(it.frame()->is_exit()); 142b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org it.Advance(); 143b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org StackFrame* frame = it.frame(); 1440b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org bool reference_result = frame->is_construct(); 145ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Address fp = Isolate::c_entry_fp(isolate->thread_local_top()); 1460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Because we know fp points to an exit frame we can use the relevant 1470b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // part of ExitFrame::ComputeCallerState directly. 1480b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org const int kCallerOffset = ExitFrameConstants::kCallerFPOffset; 1490b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Address caller_fp = Memory::Address_at(fp + kCallerOffset); 1500b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // This inlines the part of StackFrame::ComputeType that grabs the 1510b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // type of the current frame. Note that StackFrame::ComputeType 1520b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // has been specialized for each architecture so if any one of them 1530b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // changes this code has to be changed as well. 1540b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org const int kMarkerOffset = StandardFrameConstants::kMarkerOffset; 1550b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT); 1560b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Object* marker = Memory::Object_at(caller_fp + kMarkerOffset); 1570b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org bool result = (marker == kConstructMarker); 158e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(result, reference_result); 1590b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org return result; 160b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org} 161afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#endif 162b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 163e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 16443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 16543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 166b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgBUILTIN(Illegal) { 16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 168ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return isolate->heap()->undefined_value(); // Make compiler happy. 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 172b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgBUILTIN(EmptyFunction) { 173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return isolate->heap()->undefined_value(); 17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 177d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgstatic void MoveDoubleElements(FixedDoubleArray* dst, int dst_index, 178d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org FixedDoubleArray* src, int src_index, int len) { 179fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (len == 0) return; 180d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org MemMove(dst->data_start() + dst_index, src->data_start() + src_index, 181d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org len * kDoubleSize); 182fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 183fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 184fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 185ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic bool ArrayPrototypeHasNoElements(Heap* heap, 18646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context* native_context, 187dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org JSObject* array_proto) { 188255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org DisallowHeapAllocation no_gc; 189ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // This method depends on non writability of Object and Array prototype 190ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // fields. 191ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (array_proto->elements() != heap->empty_fixed_array()) return false; 192ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Object.prototype 19393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org PrototypeIterator iter(heap->isolate(), array_proto); 19493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org if (iter.IsAtEnd()) { 19593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org return false; 19693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org } 19793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org array_proto = JSObject::cast(iter.GetCurrent()); 19846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (array_proto != native_context->initial_object_prototype()) return false; 199ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (array_proto->elements() != heap->empty_fixed_array()) return false; 20093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org iter.Advance(); 20193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org return iter.IsAtEnd(); 202ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 203ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 204ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 205a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org// Returns empty handle if not applicable. 206303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMUST_USE_RESULT 2078f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgstatic inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements( 208a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Isolate* isolate, 209a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Handle<Object> receiver, 210a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Arguments* args, 211a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org int first_added_arg) { 2128f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>(); 213a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Handle<JSArray> array = Handle<JSArray>::cast(receiver); 214202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org // If there may be elements accessors in the prototype chain, the fast path 2153484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org // cannot be used if there arguments to add to the array. 2163484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org if (args != NULL && array->map()->DictionaryElementsInPrototypeChainOnly()) { 217202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org return MaybeHandle<FixedArrayBase>(); 218202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org } 2198f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>(); 2208f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>(); 221255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<FixedArrayBase> elms(array->elements(), isolate); 222a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Heap* heap = isolate->heap(); 223a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Map* map = elms->map(); 224a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org if (map == heap->fixed_array_map()) { 225830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (args == NULL || array->HasFastObjectElements()) return elms; 226a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org } else if (map == heap->fixed_cow_array_map()) { 227a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org elms = JSObject::EnsureWritableFastElements(array); 228a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if (args == NULL || array->HasFastObjectElements()) return elms; 229fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else if (map == heap->fixed_double_array_map()) { 230fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (args == NULL) return elms; 231a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org } else { 2328f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org return MaybeHandle<FixedArrayBase>(); 233f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org } 234a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org 235a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org // Need to ensure that the arguments passed in args can be contained in 236a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org // the array. 237a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org int args_length = args->length(); 238255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (first_added_arg >= args_length) return handle(array->elements(), isolate); 239a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org 240fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsKind origin_kind = array->map()->elements_kind(); 241e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!IsFastObjectElementsKind(origin_kind)); 242fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsKind target_kind = origin_kind; 243255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org { 244255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org DisallowHeapAllocation no_gc; 245255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org int arg_count = args->length() - first_added_arg; 246255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Object** arguments = args->arguments() - first_added_arg - (arg_count - 1); 247255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org for (int i = 0; i < arg_count; i++) { 248255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Object* arg = arguments[i]; 249255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (arg->IsHeapObject()) { 250255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (arg->IsHeapNumber()) { 251255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org target_kind = FAST_DOUBLE_ELEMENTS; 252255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } else { 253255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org target_kind = FAST_ELEMENTS; 254255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org break; 255255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 256fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 257fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 258fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 259fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (target_kind != origin_kind) { 260a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org JSObject::TransitionElementsKind(array, target_kind); 261255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return handle(array->elements(), isolate); 262fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 263fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return elms; 264f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org} 265f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 266f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org 267ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic inline bool IsJSArrayFastElementMovingAllowed(Heap* heap, 268ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org JSArray* receiver) { 269b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (!FLAG_clever_optimizations) return false; 270255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org DisallowHeapAllocation no_gc; 27146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context* native_context = heap->isolate()->context()->native_context(); 272dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org JSObject* array_proto = 27346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org JSObject::cast(native_context->array_function()->prototype()); 27493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org PrototypeIterator iter(heap->isolate(), receiver); 27593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org return iter.GetCurrent() == array_proto && 27646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ArrayPrototypeHasNoElements(heap, native_context, array_proto); 277dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org} 278dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org 279dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org 280a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* CallJsBuiltin( 281ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate, 282303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org const char* name, 283303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { 284ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope handleScope(isolate); 285ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Object> js_builtin = Object::GetProperty( 2879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org isolate, 2889fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org handle(isolate->native_context()->builtins(), isolate), 2899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org name).ToHandleChecked(); 290a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin); 291a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org int argc = args.length() - 1; 292a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org ScopedVector<Handle<Object> > argv(argc); 293a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org for (int i = 0; i < argc; ++i) { 294a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org argv[i] = args.at<Object>(i + 1); 295ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 2962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Handle<Object> result; 2972ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2982ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org isolate, result, 2992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Execution::Call(isolate, 3002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org function, 3012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org args.receiver(), 3022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org argc, 3032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org argv.start())); 304ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org return *result; 305ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 306ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 307ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 308b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgBUILTIN(ArrayPush) { 3097010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org HandleScope scope(isolate); 3107010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<Object> receiver = args.receiver(); 3118f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org MaybeHandle<FixedArrayBase> maybe_elms_obj = 312a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1); 3138f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<FixedArrayBase> elms_obj; 3148f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (!maybe_elms_obj.ToHandle(&elms_obj)) { 3158f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org return CallJsBuiltin(isolate, "ArrayPush", args); 3168f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org } 31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3187010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<JSArray> array = Handle<JSArray>::cast(receiver); 319fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org int len = Smi::cast(array->length())->value(); 320fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org int to_add = args.length() - 1; 321fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { 322fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org return CallJsBuiltin(isolate, "ArrayPush", args); 323fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org } 324e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!array->map()->is_observed()); 3257c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org 326fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsKind kind = array->GetElementsKind(); 32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 328fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (IsFastSmiOrObjectElementsKind(kind)) { 3297010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 330fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (to_add == 0) { 331fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return Smi::FromInt(len); 332303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 333fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Currently fixed arrays cannot grow too big, so 334fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // we should never hit this case. 335e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(to_add <= (Smi::kMaxValue - len)); 336b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 337fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int new_length = len + to_add; 338ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 339fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (new_length > elms->length()) { 340fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // New backing storage is needed. 341fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int capacity = new_length + (new_length >> 1) + 16; 3427010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<FixedArray> new_elms = 3437010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org isolate->factory()->NewUninitializedFixedArray(capacity); 344fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 34583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ElementsAccessor* accessor = array->GetElementsAccessor(); 3467010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org accessor->CopyElements( 347255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org elms_obj, 0, kind, new_elms, 0, 348255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org ElementsAccessor::kCopyToEndAndInitializeToHole); 3495c838251403b0be9a882540f1922577abba4c872ager@chromium.org 350fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms = new_elms; 351fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 3525c838251403b0be9a882540f1922577abba4c872ager@chromium.org 353fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Add the provided values. 35479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 355fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 356fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org for (int index = 0; index < to_add; index++) { 357fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms->set(index + len, args[index + 1], mode); 358fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3607010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if (*elms != array->elements()) { 3617010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org array->set_elements(*elms); 362fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 363fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 364fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Set the length. 365fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org array->set_length(Smi::FromInt(new_length)); 366fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return Smi::FromInt(new_length); 367fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 368fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int elms_len = elms_obj->length(); 369fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (to_add == 0) { 370fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return Smi::FromInt(len); 371fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 372fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Currently fixed arrays cannot grow too big, so 373fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // we should never hit this case. 374e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(to_add <= (Smi::kMaxValue - len)); 375fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 376fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int new_length = len + to_add; 377fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 3787010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<FixedDoubleArray> new_elms; 379fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 380fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (new_length > elms_len) { 381fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // New backing storage is needed. 382fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int capacity = new_length + (new_length >> 1) + 16; 383f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org // Create new backing store; since capacity > 0, we can 384f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org // safely cast to FixedDoubleArray. 385f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org new_elms = Handle<FixedDoubleArray>::cast( 386f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org isolate->factory()->NewFixedDoubleArray(capacity)); 387fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 38883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ElementsAccessor* accessor = array->GetElementsAccessor(); 3897010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org accessor->CopyElements( 390255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org elms_obj, 0, kind, new_elms, 0, 391255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org ElementsAccessor::kCopyToEndAndInitializeToHole); 3927010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org 393fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 394fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the 395fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // empty_fixed_array. 3967010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org new_elms = Handle<FixedDoubleArray>::cast(elms_obj); 397fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 398fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 399fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Add the provided values. 40079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 401fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int index; 402fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org for (index = 0; index < to_add; index++) { 403fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Object* arg = args[index + 1]; 404fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org new_elms->set(index + len, arg->Number()); 405fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 406fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 4077010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if (*new_elms != array->elements()) { 4087010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org array->set_elements(*new_elms); 409fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 410fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 411fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Set the length. 412fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org array->set_length(Smi::FromInt(new_length)); 413fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return Smi::FromInt(new_length); 414fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 418b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgBUILTIN(ArrayPop) { 41969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org HandleScope scope(isolate); 42069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Handle<Object> receiver = args.receiver(); 4218f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org MaybeHandle<FixedArrayBase> maybe_elms_obj = 422a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); 4238f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<FixedArrayBase> elms_obj; 4248f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (!maybe_elms_obj.ToHandle(&elms_obj)) { 4258f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org return CallJsBuiltin(isolate, "ArrayPop", args); 4268f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org } 42769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 42869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Handle<JSArray> array = Handle<JSArray>::cast(receiver); 429e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!array->map()->is_observed()); 430e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int len = Smi::cast(array->length())->value(); 43269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (len == 0) return isolate->heap()->undefined_value(); 43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 434fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsAccessor* accessor = array->GetElementsAccessor(); 435fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int new_length = len - 1; 4363484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org Handle<Object> element = 4373484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org accessor->Get(array, array, new_length, elms_obj).ToHandleChecked(); 4383484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org if (element->IsTheHole()) { 4393484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org return CallJsBuiltin(isolate, "ArrayPop", args); 44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 4418496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org RETURN_FAILURE_ON_EXCEPTION( 442202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org isolate, 443202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org accessor->SetLength(array, handle(Smi::FromInt(new_length), isolate))); 44469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org return *element; 44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 448ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgBUILTIN(ArrayShift) { 4497010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org HandleScope scope(isolate); 450ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap = isolate->heap(); 4517010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<Object> receiver = args.receiver(); 4528f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org MaybeHandle<FixedArrayBase> maybe_elms_obj = 453a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); 4548f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<FixedArrayBase> elms_obj; 4558f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (!maybe_elms_obj.ToHandle(&elms_obj) || 4567010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org !IsJSArrayFastElementMovingAllowed(heap, 4577010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org *Handle<JSArray>::cast(receiver))) { 458ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return CallJsBuiltin(isolate, "ArrayShift", args); 4595c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 4607010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<JSArray> array = Handle<JSArray>::cast(receiver); 461e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!array->map()->is_observed()); 462e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 4635c838251403b0be9a882540f1922577abba4c872ager@chromium.org int len = Smi::cast(array->length())->value(); 464ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (len == 0) return heap->undefined_value(); 4655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4665c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Get first element 467fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsAccessor* accessor = array->GetElementsAccessor(); 4683484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org Handle<Object> first = 4693484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org accessor->Get(array, array, 0, elms_obj).ToHandleChecked(); 4705c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (first->IsTheHole()) { 4713484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org return CallJsBuiltin(isolate, "ArrayShift", args); 4725c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 4735c838251403b0be9a882540f1922577abba4c872ager@chromium.org 47463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org if (heap->CanMoveObjectStart(*elms_obj)) { 4753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org array->set_elements(heap->LeftTrimFixedArray(*elms_obj, 1)); 4765d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org } else { 4775d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org // Shift the elements. 478fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (elms_obj->IsFixedArray()) { 4797010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 48079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 4817010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org heap->MoveElements(*elms, 0, 1, len - 1); 482fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms->set(len - 1, heap->the_hole_value()); 483fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 4847010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj); 4857010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org MoveDoubleElements(*elms, 0, *elms, 1, len - 1); 486fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms->set_the_hole(len - 1); 487fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 4885d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org } 4895c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4905c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Set the length. 4915c838251403b0be9a882540f1922577abba4c872ager@chromium.org array->set_length(Smi::FromInt(len - 1)); 4925c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4937010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org return *first; 4945c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 4955c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4965c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4975c838251403b0be9a882540f1922577abba4c872ager@chromium.orgBUILTIN(ArrayUnshift) { 498fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org HandleScope scope(isolate); 499ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap = isolate->heap(); 500fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<Object> receiver = args.receiver(); 5018f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org MaybeHandle<FixedArrayBase> maybe_elms_obj = 502a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); 5038f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<FixedArrayBase> elms_obj; 5048f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (!maybe_elms_obj.ToHandle(&elms_obj) || 505fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org !IsJSArrayFastElementMovingAllowed(heap, 506fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org *Handle<JSArray>::cast(receiver))) { 507ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return CallJsBuiltin(isolate, "ArrayUnshift", args); 508ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 509fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<JSArray> array = Handle<JSArray>::cast(receiver); 510e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!array->map()->is_observed()); 511fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (!array->HasFastSmiOrObjectElements()) { 512fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return CallJsBuiltin(isolate, "ArrayUnshift", args); 513fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 5145c838251403b0be9a882540f1922577abba4c872ager@chromium.org int len = Smi::cast(array->length())->value(); 5155c838251403b0be9a882540f1922577abba4c872ager@chromium.org int to_add = args.length() - 1; 5165c838251403b0be9a882540f1922577abba4c872ager@chromium.org int new_length = len + to_add; 5175c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Currently fixed arrays cannot grow too big, so 5185c838251403b0be9a882540f1922577abba4c872ager@chromium.org // we should never hit this case. 519e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(to_add <= (Smi::kMaxValue - len)); 5205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 521fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { 522fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org return CallJsBuiltin(isolate, "ArrayUnshift", args); 523fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org } 524fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org 525fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 526fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org 527fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org JSObject::EnsureCanContainElements(array, &args, 1, to_add, 528fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org DONT_ALLOW_DOUBLE_ELEMENTS); 529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5305c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (new_length > elms->length()) { 5315c838251403b0be9a882540f1922577abba4c872ager@chromium.org // New backing storage is needed. 5325c838251403b0be9a882540f1922577abba4c872ager@chromium.org int capacity = new_length + (new_length >> 1) + 16; 533fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedArray> new_elms = 534fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org isolate->factory()->NewUninitializedFixedArray(capacity); 535fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 53683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ElementsKind kind = array->GetElementsKind(); 53783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ElementsAccessor* accessor = array->GetElementsAccessor(); 538fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org accessor->CopyElements( 539255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org elms, 0, kind, new_elms, to_add, 540255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org ElementsAccessor::kCopyToEndAndInitializeToHole); 541fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 5425c838251403b0be9a882540f1922577abba4c872ager@chromium.org elms = new_elms; 543fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org array->set_elements(*elms); 5445c838251403b0be9a882540f1922577abba4c872ager@chromium.org } else { 54579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 546fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org heap->MoveElements(*elms, to_add, 0, len); 5475c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 5485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5495c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Add the provided values. 55079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 5515c838251403b0be9a882540f1922577abba4c872ager@chromium.org WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 5525c838251403b0be9a882540f1922577abba4c872ager@chromium.org for (int i = 0; i < to_add; i++) { 5535c838251403b0be9a882540f1922577abba4c872ager@chromium.org elms->set(i, args[i + 1], mode); 5545c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 5555c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5565c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Set the length. 5575c838251403b0be9a882540f1922577abba4c872ager@chromium.org array->set_length(Smi::FromInt(new_length)); 5585c838251403b0be9a882540f1922577abba4c872ager@chromium.org return Smi::FromInt(new_length); 5595c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 5605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 562ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgBUILTIN(ArraySlice) { 563c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org HandleScope scope(isolate); 564ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap = isolate->heap(); 565c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org Handle<Object> receiver = args.receiver(); 566023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org int len = -1; 567255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org int relative_start = 0; 568255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org int relative_end = 0; 569255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org { 570255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org DisallowHeapAllocation no_gc; 571255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (receiver->IsJSArray()) { 572255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org JSArray* array = JSArray::cast(*receiver); 573255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (!IsJSArrayFastElementMovingAllowed(heap, array)) { 574255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 575255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 576255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 5779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org 578255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (!array->HasFastElements()) { 579255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 580255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 581255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 582fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 583255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org len = Smi::cast(array->length())->value(); 584fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 585255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // Array.slice(arguments, ...) is quite a common idiom (notably more 586255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // than 50% of invocations in Web apps). Treat it in C++ as well. 587f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org Map* arguments_map = 588f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org isolate->context()->native_context()->sloppy_arguments_map(); 589255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org 590255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org bool is_arguments_object_with_fast_elements = 591255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org receiver->IsJSObject() && 592255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org JSObject::cast(*receiver)->map() == arguments_map; 593255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (!is_arguments_object_with_fast_elements) { 594255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 595255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 596255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 597255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org JSObject* object = JSObject::cast(*receiver); 598fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 599255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (!object->HasFastElements()) { 600255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 601255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 602255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 6035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 604255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex); 605255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (!len_obj->IsSmi()) { 606255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 607255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 608255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 609255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org len = Smi::cast(len_obj)->value(); 610255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (len > object->elements()->length()) { 611255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 612fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 613fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 6145c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 615255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org 616e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(len >= 0); 617255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org int n_arguments = args.length() - 1; 618255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org 619255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // Note carefully choosen defaults---if argument is missing, 620255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // it's undefined which gets converted to 0 for relative_start 621255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // and to len for relative_end. 622255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org relative_start = 0; 623255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org relative_end = len; 624255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (n_arguments > 0) { 625255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Object* arg1 = args[1]; 626255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (arg1->IsSmi()) { 627255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org relative_start = Smi::cast(arg1)->value(); 628255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } else if (arg1->IsHeapNumber()) { 629255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org double start = HeapNumber::cast(arg1)->value(); 630255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (start < kMinInt || start > kMaxInt) { 631255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 632fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 633fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 634255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org relative_start = std::isnan(start) ? 0 : static_cast<int>(start); 635255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } else if (!arg1->IsUndefined()) { 636255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 6385c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 639255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (n_arguments > 1) { 640255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Object* arg2 = args[2]; 641255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (arg2->IsSmi()) { 642255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org relative_end = Smi::cast(arg2)->value(); 643255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } else if (arg2->IsHeapNumber()) { 644255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org double end = HeapNumber::cast(arg2)->value(); 645255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (end < kMinInt || end > kMaxInt) { 646255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 647255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 648255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 649255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org relative_end = std::isnan(end) ? 0 : static_cast<int>(end); 650255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } else if (!arg2->IsUndefined()) { 651255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 652255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 653255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 654255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 6555c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 6565c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 6575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6585c838251403b0be9a882540f1922577abba4c872ager@chromium.org // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6. 659ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int k = (relative_start < 0) ? Max(len + relative_start, 0) 660ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org : Min(relative_start, len); 6615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6625c838251403b0be9a882540f1922577abba4c872ager@chromium.org // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8. 663ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int final = (relative_end < 0) ? Max(len + relative_end, 0) 664ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org : Min(relative_end, len); 6655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 666fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Calculate the length of result array. 667fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org int result_len = Max(final - k, 0); 6685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 669255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<JSObject> object = Handle<JSObject>::cast(receiver); 670255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<FixedArrayBase> elms(object->elements(), isolate); 671255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org 672a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ElementsKind kind = object->GetElementsKind(); 673a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (IsHoleyElementsKind(kind)) { 674255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org DisallowHeapAllocation no_gc; 675a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org bool packed = true; 676a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org ElementsAccessor* accessor = ElementsAccessor::ForKind(kind); 677a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = k; i < final; i++) { 6788f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (!accessor->HasElement(object, object, i, elms)) { 679a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org packed = false; 680a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org break; 681a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 682a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 683a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (packed) { 684a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org kind = GetPackedElementsKind(kind); 685a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else if (!receiver->IsJSArray()) { 686255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 687a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org return CallJsBuiltin(isolate, "ArraySlice", args); 688a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 689a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 690a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 691c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org Handle<JSArray> result_array = 692c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org isolate->factory()->NewJSArray(kind, result_len, result_len); 6938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 69479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 695c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org if (result_len == 0) return *result_array; 696c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 697fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsAccessor* accessor = object->GetElementsAccessor(); 698255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org accessor->CopyElements( 699255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org elms, k, kind, handle(result_array->elements(), isolate), 0, result_len); 700c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org return *result_array; 7015c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7025c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7045c838251403b0be9a882540f1922577abba4c872ager@chromium.orgBUILTIN(ArraySplice) { 705fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org HandleScope scope(isolate); 706ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap = isolate->heap(); 707fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<Object> receiver = args.receiver(); 7088f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org MaybeHandle<FixedArrayBase> maybe_elms_obj = 709a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3); 7108f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<FixedArrayBase> elms_obj; 7118f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org if (!maybe_elms_obj.ToHandle(&elms_obj) || 712fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org !IsJSArrayFastElementMovingAllowed(heap, 713fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org *Handle<JSArray>::cast(receiver))) { 714ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return CallJsBuiltin(isolate, "ArraySplice", args); 715ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 716fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<JSArray> array = Handle<JSArray>::cast(receiver); 717e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!array->map()->is_observed()); 718e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 7195c838251403b0be9a882540f1922577abba4c872ager@chromium.org int len = Smi::cast(array->length())->value(); 7205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7215c838251403b0be9a882540f1922577abba4c872ager@chromium.org int n_arguments = args.length() - 1; 7225c838251403b0be9a882540f1922577abba4c872ager@chromium.org 723ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int relative_start = 0; 72431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (n_arguments > 0) { 725255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org DisallowHeapAllocation no_gc; 726255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Object* arg1 = args[1]; 72731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (arg1->IsSmi()) { 728255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org relative_start = Smi::cast(arg1)->value(); 729fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else if (arg1->IsHeapNumber()) { 730255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org double start = HeapNumber::cast(arg1)->value(); 731fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (start < kMinInt || start > kMaxInt) { 732255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 733fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return CallJsBuiltin(isolate, "ArraySplice", args); 734fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 735ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org relative_start = std::isnan(start) ? 0 : static_cast<int>(start); 73631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } else if (!arg1->IsUndefined()) { 737255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 738ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return CallJsBuiltin(isolate, "ArraySplice", args); 73931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 7405c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 741ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) 742ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org : Min(relative_start, len); 7435c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7445c838251403b0be9a882540f1922577abba4c872ager@chromium.org // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is 74531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // given as a request to delete all the elements from the start. 74631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org // And it differs from the case of undefined delete count. 7475c838251403b0be9a882540f1922577abba4c872ager@chromium.org // This does not follow ECMA-262, but we do the same for 7485c838251403b0be9a882540f1922577abba4c872ager@chromium.org // compatibility. 74931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org int actual_delete_count; 75031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (n_arguments == 1) { 751e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(len - actual_start >= 0); 75231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org actual_delete_count = len - actual_start; 75331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } else { 75431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org int value = 0; // ToInteger(undefined) == 0 75531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (n_arguments > 1) { 756255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org DisallowHeapAllocation no_gc; 75731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org Object* arg2 = args[2]; 75831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org if (arg2->IsSmi()) { 75931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org value = Smi::cast(arg2)->value(); 76031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } else { 761255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 762ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return CallJsBuiltin(isolate, "ArraySplice", args); 76331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org } 7645c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 76531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org actual_delete_count = Min(Max(value, 0), len - actual_start); 7665c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 7675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 768fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsKind elements_kind = array->GetElementsKind(); 769fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 770fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; 771fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int new_length = len - actual_delete_count + item_count; 772fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 773fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // For double mode we do not support changing the length. 774fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (new_length > len && IsFastDoubleElementsKind(elements_kind)) { 775fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return CallJsBuiltin(isolate, "ArraySplice", args); 776fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 777fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 778fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (new_length == 0) { 779fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements( 780fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms_obj, elements_kind, actual_delete_count); 781fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org array->set_elements(heap->empty_fixed_array()); 782fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org array->set_length(Smi::FromInt(0)); 783fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org return *result; 784fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 785fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 786fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<JSArray> result_array = 787fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org isolate->factory()->NewJSArray(elements_kind, 788fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org actual_delete_count, 789fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org actual_delete_count); 7905c838251403b0be9a882540f1922577abba4c872ager@chromium.org 791fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (actual_delete_count > 0) { 79279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 793fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsAccessor* accessor = array->GetElementsAccessor(); 794fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org accessor->CopyElements( 795255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org elms_obj, actual_start, elements_kind, 796255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org handle(result_array->elements(), isolate), 0, actual_delete_count); 797ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 7985c838251403b0be9a882540f1922577abba4c872ager@chromium.org 799c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool elms_changed = false; 800ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org if (item_count < actual_delete_count) { 8015c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Shrink the array. 802fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org const bool trim_array = !heap->lo_space()->Contains(*elms_obj) && 80325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org ((actual_start + item_count) < 80425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org (len - actual_delete_count - actual_start)); 80525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org if (trim_array) { 80625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org const int delta = actual_delete_count - item_count; 80725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org 808fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (elms_obj->IsFixedDoubleArray()) { 809fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedDoubleArray> elms = 810fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedDoubleArray>::cast(elms_obj); 811fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org MoveDoubleElements(*elms, delta, *elms, 0, actual_start); 812fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 813fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 81479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 815fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org heap->MoveElements(*elms, delta, 0, actual_start); 81625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org } 81725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org 818b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org if (heap->CanMoveObjectStart(*elms_obj)) { 819b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org // On the fast path we move the start of the object in memory. 8203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org elms_obj = handle(heap->LeftTrimFixedArray(*elms_obj, delta)); 821b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org } else { 822b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org // This is the slow path. We are going to move the elements to the left 823b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org // by copying them. For trimmed values we store the hole. 824b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org if (elms_obj->IsFixedDoubleArray()) { 825b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org Handle<FixedDoubleArray> elms = 826b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org Handle<FixedDoubleArray>::cast(elms_obj); 827b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org MoveDoubleElements(*elms, 0, *elms, delta, len - delta); 8282f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org elms->FillWithHoles(len - delta, len); 829b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org } else { 830b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 831b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org DisallowHeapAllocation no_gc; 832b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org heap->MoveElements(*elms, 0, delta, len - delta); 8332f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org elms->FillWithHoles(len - delta, len); 834b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org } 835b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org } 836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com elms_changed = true; 83725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org } else { 838fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (elms_obj->IsFixedDoubleArray()) { 839fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedDoubleArray> elms = 840fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedDoubleArray>::cast(elms_obj); 841fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org MoveDoubleElements(*elms, actual_start + item_count, 842fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org *elms, actual_start + actual_delete_count, 843fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org (len - actual_delete_count - actual_start)); 8442f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org elms->FillWithHoles(new_length, len); 845fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 846fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 84779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 848fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org heap->MoveElements(*elms, actual_start + item_count, 84959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org actual_start + actual_delete_count, 85059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org (len - actual_delete_count - actual_start)); 8512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org elms->FillWithHoles(new_length, len); 852fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 85325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org } 854ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else if (item_count > actual_delete_count) { 855fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 8565c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Currently fixed arrays cannot grow too big, so 8575c838251403b0be9a882540f1922577abba4c872ager@chromium.org // we should never hit this case. 858e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((item_count - actual_delete_count) <= (Smi::kMaxValue - len)); 8595c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8605c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Check if array need to grow. 8615c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (new_length > elms->length()) { 8625c838251403b0be9a882540f1922577abba4c872ager@chromium.org // New backing storage is needed. 8635c838251403b0be9a882540f1922577abba4c872ager@chromium.org int capacity = new_length + (new_length >> 1) + 16; 864fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedArray> new_elms = 865fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org isolate->factory()->NewUninitializedFixedArray(capacity); 866fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 86779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 8688e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 869fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsKind kind = array->GetElementsKind(); 870fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ElementsAccessor* accessor = array->GetElementsAccessor(); 8718e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org if (actual_start > 0) { 8728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Copy the part before actual_start as is. 873fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org accessor->CopyElements( 874255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org elms, 0, kind, new_elms, 0, actual_start); 8758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org } 876fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org accessor->CopyElements( 877255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org elms, actual_start + actual_delete_count, kind, 878fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org new_elms, actual_start + item_count, 879255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org ElementsAccessor::kCopyToEndAndInitializeToHole); 8805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 881fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms_obj = new_elms; 882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com elms_changed = true; 883ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } else { 88479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 885fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org heap->MoveElements(*elms, actual_start + item_count, 88659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org actual_start + actual_delete_count, 88759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org (len - actual_delete_count - actual_start)); 8885c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 8895c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 8905c838251403b0be9a882540f1922577abba4c872ager@chromium.org 891fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (IsFastDoubleElementsKind(elements_kind)) { 892fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj); 893fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org for (int k = actual_start; k < actual_start + item_count; k++) { 894fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Object* arg = args[3 + k - actual_start]; 895fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (arg->IsSmi()) { 896fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms->set(k, Smi::cast(arg)->value()); 897fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 898fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms->set(k, HeapNumber::cast(arg)->value()); 899fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 900fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 901fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 902fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); 90379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_gc; 904fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 905fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org for (int k = actual_start; k < actual_start + item_count; k++) { 906fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org elms->set(k, args[3 + k - actual_start], mode); 907fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 9085c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 9095c838251403b0be9a882540f1922577abba4c872ager@chromium.org 910c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (elms_changed) { 911fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org array->set_elements(*elms_obj); 912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 9135c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Set the length. 9145c838251403b0be9a882540f1922577abba4c872ager@chromium.org array->set_length(Smi::FromInt(new_length)); 9155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 916fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org return *result_array; 9175c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 9185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9195c838251403b0be9a882540f1922577abba4c872ager@chromium.org 920086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.orgBUILTIN(ArrayConcat) { 921c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org HandleScope scope(isolate); 922086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org 923086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org int n_arguments = args.length(); 924086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org int result_len = 0; 925830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org ElementsKind elements_kind = GetInitialFastElementsKind(); 9268e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org bool has_double = false; 927255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org { 928255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org DisallowHeapAllocation no_gc; 929255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Heap* heap = isolate->heap(); 930255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Context* native_context = isolate->context()->native_context(); 931255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org JSObject* array_proto = 932255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org JSObject::cast(native_context->array_function()->prototype()); 933255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) { 934255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 935aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org return CallJsBuiltin(isolate, "ArrayConcatJS", args); 936086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org } 937086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org 938255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // Iterate through all the arguments performing checks 939255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // and calculating total length. 940255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org bool is_holey = false; 941255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org for (int i = 0; i < n_arguments; i++) { 942255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Object* arg = args[i]; 94393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org PrototypeIterator iter(isolate, arg); 94493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements() || 94593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org iter.GetCurrent() != array_proto) { 946255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 947aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org return CallJsBuiltin(isolate, "ArrayConcatJS", args); 948255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 949255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org int len = Smi::cast(JSArray::cast(arg)->length())->value(); 950255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org 951255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // We shouldn't overflow when adding another len. 952255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); 953255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); 954255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org USE(kHalfOfMaxInt); 955255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org result_len += len; 956e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result_len >= 0); 957255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org 958255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (result_len > FixedDoubleArray::kMaxLength) { 959255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org AllowHeapAllocation allow_allocation; 960aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org return CallJsBuiltin(isolate, "ArrayConcatJS", args); 961255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 962086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org 963255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind(); 964255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org has_double = has_double || IsFastDoubleElementsKind(arg_kind); 965255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); 966255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) { 967255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org elements_kind = arg_kind; 968255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org } 969830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 970255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org if (is_holey) elements_kind = GetHoleyElementsKind(elements_kind); 971086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org } 972086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org 9738e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // If a double array is concatted into a fast elements array, the fast 9748e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // elements array needs to be initialized to contain proper holes, since 9758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // boxing doubles may cause incremental marking. 9768e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org ArrayStorageAllocationMode mode = 9778e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org has_double && IsFastObjectElementsKind(elements_kind) 9788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS; 979c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org Handle<JSArray> result_array = 980c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org isolate->factory()->NewJSArray(elements_kind, 981c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org result_len, 982c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org result_len, 983c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org mode); 984c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org if (result_len == 0) return *result_array; 985c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 986fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int j = 0; 987255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org Handle<FixedArrayBase> storage(result_array->elements(), isolate); 9884cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); 989086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org for (int i = 0; i < n_arguments; i++) { 990255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // TODO(ishell): It is crucial to keep |array| as a raw pointer to avoid 991255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org // performance degradation. Revisit this later. 992255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org JSArray* array = JSArray::cast(args[i]); 993086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org int len = Smi::cast(array->length())->value(); 9944cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ElementsKind from_kind = array->GetElementsKind(); 9958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org if (len > 0) { 996c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org accessor->CopyElements(array, 0, from_kind, storage, j, len); 9978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org j += len; 9988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org } 999086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org } 1000fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 1001e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(j == result_len); 1002086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org 1003c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org return *result_array; 1004086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org} 1005086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org 1006086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org 100743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------- 100854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org// Generator and strict mode poison pills 1009ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1010ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 101140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgBUILTIN(StrictModePoisonPill) { 1012c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org HandleScope scope(isolate); 1013ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org THROW_NEW_ERROR_RETURN_FAILURE( 1014ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org isolate, 1015ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org NewTypeError("strict_poison_pill", HandleVector<Object>(NULL, 0))); 1016ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 1017ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1018e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 101954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.orgBUILTIN(GeneratorPoisonPill) { 102054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org HandleScope scope(isolate); 1021ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org THROW_NEW_ERROR_RETURN_FAILURE( 1022ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org isolate, 1023ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org NewTypeError("generator_poison_pill", HandleVector<Object>(NULL, 0))); 102454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org} 102554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org 102654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org 1027ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// ----------------------------------------------------------------------------- 102843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 102943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 103043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 103149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// Searches the hidden prototype chain of the given object for the first 103249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// object that is an instance of the given type. If no such object can 103349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// be found then Heap::null_value() is returned. 103449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgstatic inline Object* FindHidden(Heap* heap, 103549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org Object* object, 103649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org FunctionTemplateInfo* type) { 10379bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org for (PrototypeIterator iter(heap->isolate(), object, 10389bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org PrototypeIterator::START_AT_RECEIVER); 10399bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { 10409bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org if (type->IsTemplateFor(iter.GetCurrent())) { 10419bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org return iter.GetCurrent(); 10429bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org } 104349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org } 104449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org return heap->null_value(); 104549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org} 104649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org 104749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org 104843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the holder JSObject if the function can legally be called 104943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with this receiver. Returns Heap::null_value() if the call is 105043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// illegal. Any arguments that don't fit the expected type is 105149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// overwritten with undefined. Note that holder and the arguments are 105249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// implicitly rewritten with the first object in the hidden prototype 105349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// chain that actually has the expected type. 1054ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic inline Object* TypeCheck(Heap* heap, 1055ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int argc, 105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object** argv, 105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FunctionTemplateInfo* info) { 105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* recv = argv[0]; 10591c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org // API calls are only supported with JSObject receivers. 10601c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (!recv->IsJSObject()) return heap->null_value(); 106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* sig_obj = info->signature(); 106243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (sig_obj->IsUndefined()) return recv; 106343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SignatureInfo* sig = SignatureInfo::cast(sig_obj); 106443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If necessary, check the receiver 106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* recv_type = sig->receiver(); 106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* holder = recv; 106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!recv_type->IsUndefined()) { 106849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org holder = FindHidden(heap, holder, FunctionTemplateInfo::cast(recv_type)); 106949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org if (holder == heap->null_value()) return heap->null_value(); 107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* args_obj = sig->args(); 107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there is no argument signature we're done 107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (args_obj->IsUndefined()) return holder; 107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FixedArray* args = FixedArray::cast(args_obj); 107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int length = args->length(); 107631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager if (argc <= length) length = argc - 1; 107743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < length; i++) { 107843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* argtype = args->get(i); 107943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (argtype->IsUndefined()) continue; 108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object** arg = &argv[-1 - i]; 108143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* current = *arg; 108249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org current = FindHidden(heap, current, FunctionTemplateInfo::cast(argtype)); 108349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org if (current == heap->null_value()) current = heap->undefined_value(); 108449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org *arg = current; 108543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return holder; 108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1090b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgtemplate <bool is_construct> 1091a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* HandleApiCallHelper( 1092ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { 1093e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_construct == CalledAsConstructor(isolate)); 1094ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap = isolate->heap(); 109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1096ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope scope(isolate); 1097b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Handle<JSFunction> function = args.called_function(); 1098e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(function->shared()->IsApiFunction()); 109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Handle<FunctionTemplateInfo> fun_data( 11012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org function->shared()->get_api_func_data(), isolate); 110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (is_construct) { 11032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 11042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org isolate, fun_data, 11052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org isolate->factory()->ConfigureInstance( 11062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org fun_data, Handle<JSObject>::cast(args.receiver()))); 110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1109e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org SharedFunctionInfo* shared = function->shared(); 1110486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if (shared->strict_mode() == SLOPPY && !shared->native()) { 1111e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org Object* recv = args[0]; 1112e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!recv->IsNull()); 111358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org if (recv->IsUndefined()) args[0] = function->global_proxy(); 1114e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org } 1115e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org 11162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Object* raw_holder = TypeCheck(heap, args.length(), &args[0], *fun_data); 111743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 111843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (raw_holder->IsNull()) { 111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // This function cannot be called with the given receiver. Abort! 1120ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org THROW_NEW_ERROR_RETURN_FAILURE( 1121ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org isolate, 1122ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org NewTypeError("illegal_invocation", HandleVector(&function, 1))); 112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 112443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* raw_call_data = fun_data->call_code(); 112643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!raw_call_data->IsUndefined()) { 112743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); 112843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* callback_obj = call_data->callback(); 1129662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org v8::FunctionCallback callback = 1130662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org v8::ToCData<v8::FunctionCallback>(callback_obj); 113143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* data_obj = call_data->data(); 113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* result; 113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); 1135e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(raw_holder->IsJSObject()); 1136e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org 1137bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org FunctionCallbackArguments custom(isolate, 1138bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org data_obj, 1139bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org *function, 1140bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org raw_holder, 1141bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org &args[0] - 1, 1142bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org args.length() - 1, 1143bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org is_construct); 114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org v8::Handle<v8::Value> value = custom.Call(callback); 114643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value.IsEmpty()) { 1147ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org result = heap->undefined_value(); 114843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 114943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = *reinterpret_cast<Object**>(*value); 1150de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org result->VerifyApiCallResultType(); 115143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!is_construct || result->IsJSObject()) return result; 115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1157b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return *args.receiver(); 1158b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1159b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1160b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1161b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgBUILTIN(HandleApiCall) { 1162ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return HandleApiCallHelper<false>(args, isolate); 1163b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1164b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1165b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1166b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgBUILTIN(HandleApiCallConstruct) { 1167ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return HandleApiCallHelper<true>(args, isolate); 116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117105521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// Helper function to handle calls to non-function objects created through the 117205521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// API. The object can be called as either a constructor (using new) or just as 117305521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// a function (without new). 1174a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( 1175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate, 1176b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org bool is_construct_call, 1177b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { 117805521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org // Non-functions are never called as constructors. Even if this is an object 117905521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org // called as a constructor the delegate call is not a construct call. 1180e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!CalledAsConstructor(isolate)); 1181ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap = isolate->heap(); 118243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1183717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org Handle<Object> receiver = args.receiver(); 118405521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org 118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the object called. 1186717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org JSObject* obj = JSObject::cast(*receiver); 118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the invocation callback from the function descriptor that was 118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // used to create the called object. 1190e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(obj->map()->has_instance_call_handler()); 119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); 1192e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(constructor->shared()->IsApiFunction()); 119343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* handler = 1194f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org constructor->shared()->get_api_func_data()->instance_call_handler(); 1195e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!handler->IsUndefined()); 119643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); 119743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* callback_obj = call_data->callback(); 1198662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org v8::FunctionCallback callback = 1199662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org v8::ToCData<v8::FunctionCallback>(callback_obj); 120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the data for the call and perform the callback. 120243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Object* result; 1203e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org { 1204ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope scope(isolate); 1205ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LOG(isolate, ApiObjectAccess("call non-function", obj)); 1206e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org 1207bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org FunctionCallbackArguments custom(isolate, 1208bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org call_data->data(), 1209bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org constructor, 1210bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org obj, 1211bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org &args[0] - 1, 1212bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org args.length() - 1, 1213bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org is_construct_call); 12141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org v8::Handle<v8::Value> value = custom.Call(callback); 121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (value.IsEmpty()) { 1216ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org result = heap->undefined_value(); 121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen result = *reinterpret_cast<Object**>(*value); 1219de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org result->VerifyApiCallResultType(); 122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check for exceptions and return result. 12238496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 122605521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org 122705521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org 122805521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// Handle calls to non-function objects created through the API. This delegate 122905521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// function is used when the call is a normal function call. 123005521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.orgBUILTIN(HandleApiCallAsFunction) { 1231ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return HandleApiCallAsFunctionOrConstructor(isolate, false, args); 123205521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org} 123305521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org 123405521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org 123505521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// Handle calls to non-function objects created through the API. This delegate 123605521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// function is used when the call is a construct call. 123705521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.orgBUILTIN(HandleApiCallAsConstructor) { 1238ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return HandleApiCallAsFunctionOrConstructor(isolate, true, args); 123905521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org} 124043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_LoadIC_Miss(MacroAssembler* masm) { 124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LoadIC::GenerateMiss(masm); 124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_LoadIC_Normal(MacroAssembler* masm) { 124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LoadIC::GenerateNormal(masm); 124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 125143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1252de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgstatic void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) { 1253eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org NamedLoadHandlerCompiler::GenerateLoadViaGetterForDeopt(masm); 1254de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org} 1255de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1256de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1257d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgstatic void Generate_LoadIC_Slow(MacroAssembler* masm) { 1258d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org LoadIC::GenerateRuntimeGetProperty(masm); 1259d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org} 1260d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 1261d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 126243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) { 126343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen KeyedLoadIC::GenerateInitialize(masm); 126443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 126543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 126643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1267ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgstatic void Generate_KeyedLoadIC_Slow(MacroAssembler* masm) { 1268ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org KeyedLoadIC::GenerateRuntimeGetProperty(masm); 1269ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 1270ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1271ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 127243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) { 1273af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org KeyedLoadIC::GenerateMiss(masm); 127443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 127543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 127643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 127743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) { 127843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen KeyedLoadIC::GenerateGeneric(masm); 127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 128043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 128143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgstatic void Generate_KeyedLoadIC_String(MacroAssembler* masm) { 12830c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org KeyedLoadIC::GenerateString(masm); 12840c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org} 12850c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 12860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 128743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) { 128843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen KeyedLoadIC::GeneratePreMonomorphic(masm); 128943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 129043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1291e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 129243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_StoreIC_Miss(MacroAssembler* masm) { 129343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen StoreIC::GenerateMiss(masm); 129443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 129543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 129643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 129769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgstatic void Generate_StoreIC_Normal(MacroAssembler* masm) { 129869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org StoreIC::GenerateNormal(masm); 129969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org} 130069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 130169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 13026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void Generate_StoreIC_Slow(MacroAssembler* masm) { 13036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org NamedStoreHandlerCompiler::GenerateSlow(masm); 13046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 13056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 13066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 13076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) { 13086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org ElementHandlerCompiler::GenerateStoreSlow(masm); 13096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org} 13106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 13116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 131246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgstatic void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { 1313eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm); 131446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 131546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 131646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 131743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) { 1318486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org KeyedStoreIC::GenerateGeneric(masm, SLOPPY); 13199ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org} 13209ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 13219ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 13229ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgstatic void Generate_KeyedStoreIC_Generic_Strict(MacroAssembler* masm) { 1323486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org KeyedStoreIC::GenerateGeneric(masm, STRICT); 132443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 132643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) { 1328af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org KeyedStoreIC::GenerateMiss(masm); 1329ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 1330ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1331ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 133243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) { 133343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen KeyedStoreIC::GenerateInitialize(masm); 133443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 133643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13379ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgstatic void Generate_KeyedStoreIC_Initialize_Strict(MacroAssembler* masm) { 13389ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org KeyedStoreIC::GenerateInitialize(masm); 13399ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org} 13409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 1341e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 13423d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgstatic void Generate_KeyedStoreIC_PreMonomorphic(MacroAssembler* masm) { 13433d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org KeyedStoreIC::GeneratePreMonomorphic(masm); 13443d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org} 13453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 13463d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 13473d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgstatic void Generate_KeyedStoreIC_PreMonomorphic_Strict(MacroAssembler* masm) { 13483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org KeyedStoreIC::GeneratePreMonomorphic(masm); 13493d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org} 13503d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 13513d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 1352486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgstatic void Generate_KeyedStoreIC_SloppyArguments(MacroAssembler* masm) { 1353486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org KeyedStoreIC::GenerateSloppyArguments(masm); 13547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org} 13559ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org 1356e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1357a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgstatic void Generate_CallICStub_DebugBreak(MacroAssembler* masm) { 1358d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateCallICStubDebugBreak(masm); 1359a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 1360a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1361a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 13628bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_LoadIC_DebugBreak(MacroAssembler* masm) { 1363d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateLoadICDebugBreak(masm); 13648bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 13658bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 13668bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 13678bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_StoreIC_DebugBreak(MacroAssembler* masm) { 1368d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateStoreICDebugBreak(masm); 13698bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 13708bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 13718bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 13728bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) { 1373d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateKeyedLoadICDebugBreak(masm); 13748bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 13758bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 13768bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 13778bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) { 1378d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateKeyedStoreICDebugBreak(masm); 13798bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 13808bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 13818bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1382f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgstatic void Generate_CompareNilIC_DebugBreak(MacroAssembler* masm) { 1383d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateCompareNilICDebugBreak(masm); 1384f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 1385f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 1386f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 13878bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_Return_DebugBreak(MacroAssembler* masm) { 1388d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateReturnDebugBreak(masm); 13898bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 13908bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 13918bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1392c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgstatic void Generate_CallFunctionStub_DebugBreak(MacroAssembler* masm) { 1393d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateCallFunctionStubDebugBreak(masm); 13948bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 1395357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 13962356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 1397fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgstatic void Generate_CallConstructStub_DebugBreak(MacroAssembler* masm) { 1398d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateCallConstructStubDebugBreak(masm); 1399fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 1400fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 1401fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 1402fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgstatic void Generate_CallConstructStub_Recording_DebugBreak( 1403fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org MacroAssembler* masm) { 1404d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateCallConstructStubRecordDebugBreak(masm); 1405fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 1406fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 1407fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 14082356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgstatic void Generate_Slot_DebugBreak(MacroAssembler* masm) { 1409d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateSlotDebugBreak(masm); 14102356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 14112356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 14122356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 1413357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.orgstatic void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) { 1414d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GeneratePlainReturnLiveEdit(masm); 1415357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 1416357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 14172356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 1418357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.orgstatic void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) { 1419d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DebugCodegen::GenerateFrameDropperLiveEdit(masm); 1420357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 14218bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgBuiltins::Builtins() : initialized_(false) { 1424ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count); 1425ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org memset(names_, 0, sizeof(names_[0]) * builtin_count); 1426ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 1427ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1428ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1429ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgBuiltins::~Builtins() { 1430ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 1431ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 143243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1433b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name), 1434ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgAddress const Builtins::c_functions_[cfunction_count] = { 1435ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org BUILTIN_LIST_C(DEF_ENUM_C) 1436ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}; 143743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_ENUM_C 143843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DEF_JS_NAME(name, ignore) #name, 144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DEF_JS_ARGC(ignore, argc) argc, 1441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgconst char* const Builtins::javascript_names_[id_count] = { 144243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BUILTINS_LIST_JS(DEF_JS_NAME) 144343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1445ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint const Builtins::javascript_argc_[id_count] = { 144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BUILTINS_LIST_JS(DEF_JS_ARGC) 144743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 144843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_JS_NAME 144943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_JS_ARGC 145043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1451ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstruct BuiltinDesc { 1452ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org byte* generator; 1453ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org byte* c_code; 1454ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const char* s_name; // name is only used for generating log information. 1455ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int name; 1456ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Code::Flags flags; 1457ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org BuiltinExtraArguments extra_args; 1458ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}; 145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#define BUILTIN_FUNCTION_TABLE_INIT { V8_ONCE_INIT, {} } 14611456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 1462ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass BuiltinFunctionTable { 1463ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org public: 14641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BuiltinDesc* functions() { 14651e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::CallOnce(&once_, &Builtins::InitBuiltinFunctionTable); 14661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return functions_; 1467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 1468ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 14691e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::OnceType once_; 14701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BuiltinDesc functions_[Builtins::builtin_count + 1]; 147143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1472ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org friend class Builtins; 1473ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}; 1474ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 14751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstatic BuiltinFunctionTable builtin_function_table = 14761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BUILTIN_FUNCTION_TABLE_INIT; 1477ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1478ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// Define array of pointers to generators and C builtin functions. 1479ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// We do this in a sort of roundabout way so that we can do the initialization 1480ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// within the lexical scope of Builtins:: and within a context where 1481ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// Code::Flags names a non-abstract type. 1482ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid Builtins::InitBuiltinFunctionTable() { 14831456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BuiltinDesc* functions = builtin_function_table.functions_; 1484ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions[builtin_count].generator = NULL; 1485ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions[builtin_count].c_code = NULL; 1486ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions[builtin_count].s_name = NULL; 1487ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions[builtin_count].name = builtin_count; 1488ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions[builtin_count].flags = static_cast<Code::Flags>(0); 1489ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS; 1490ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1491ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#define DEF_FUNCTION_PTR_C(aname, aextra_args) \ 1492ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->generator = FUNCTION_ADDR(Generate_Adaptor); \ 1493ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->c_code = FUNCTION_ADDR(Builtin_##aname); \ 1494ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->s_name = #aname; \ 1495ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->name = c_##aname; \ 1496ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->flags = Code::ComputeFlags(Code::BUILTIN); \ 1497ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->extra_args = aextra_args; \ 1498ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ++functions; 1499ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1500ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#define DEF_FUNCTION_PTR_A(aname, kind, state, extra) \ 1501ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->generator = FUNCTION_ADDR(Generate_##aname); \ 1502ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->c_code = NULL; \ 1503ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->s_name = #aname; \ 15047979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org functions->name = k##aname; \ 1505ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->flags = Code::ComputeFlags(Code::kind, \ 1506ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org state, \ 1507ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org extra); \ 1508ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org functions->extra_args = NO_EXTRA_ARGUMENTS; \ 1509ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ++functions; 1510ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1511c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org#define DEF_FUNCTION_PTR_H(aname, kind) \ 151232aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org functions->generator = FUNCTION_ADDR(Generate_##aname); \ 151332aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org functions->c_code = NULL; \ 151432aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org functions->s_name = #aname; \ 151532aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org functions->name = k##aname; \ 1516f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org functions->flags = Code::ComputeHandlerFlags(Code::kind); \ 151732aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org functions->extra_args = NO_EXTRA_ARGUMENTS; \ 151832aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org ++functions; 151932aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org 1520ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) 1521ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) 152232aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org BUILTIN_LIST_H(DEF_FUNCTION_PTR_H) 1523ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) 152443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 152543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_FUNCTION_PTR_C 152643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_FUNCTION_PTR_A 1527ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 1528ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1529e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1530e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgvoid Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { 1531e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!initialized_); 1532ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1533ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Create a scope for the handles in the builtins. 1534c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org HandleScope scope(isolate); 1535ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 15361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org const BuiltinDesc* functions = builtin_function_table.functions(); 153743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 153843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // For now we generate builtin adaptor code into a stack-allocated 1539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // buffer, before copying it into individual code objects. Be careful 1540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // with alignment, some platforms don't like unaligned code. 15413c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org#ifdef DEBUG 15423c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org // We can generate a lot of debug code on Arm64. 15433c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org const size_t buffer_size = 32*KB; 15443c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org#else 15453c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org const size_t buffer_size = 8*KB; 15463c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org#endif 15473c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org union { int force_alignment; byte buffer[buffer_size]; } u; 154843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 154943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Traverse the list of builtins and generate an adaptor in a 155043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // separate code object for each one. 155143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < builtin_count; i++) { 155243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (create_heap_objects) { 1553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MacroAssembler masm(isolate, u.buffer, sizeof u.buffer); 155443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Generate the code/adaptor. 1555b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); 155643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Generator g = FUNCTION_CAST<Generator>(functions[i].generator); 155743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We pass all arguments to the generator, but it may not use all of 155843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // them. This works because the first arguments are on top of the 155943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // stack. 1560e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!masm.has_frame()); 1561b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org g(&masm, functions[i].name, functions[i].extra_args); 156243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Move the code into the object heap. 156343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CodeDesc desc; 156443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen masm.GetCode(&desc); 156543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code::Flags flags = functions[i].flags; 15669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<Code> code = 15679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org isolate->factory()->NewCode(desc, flags, masm.CodeObject()); 156843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Log the event and add the code to the builtins array. 1569c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org PROFILE(isolate, 15709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org CodeCreateEvent(Logger::BUILTIN_TAG, *code, functions[i].s_name)); 15719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org builtins_[i] = *code; 15724c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org if (code->kind() == Code::BUILTIN) code->set_builtin_index(i); 15737be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org#ifdef ENABLE_DISASSEMBLER 157431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager if (FLAG_print_builtin_code) { 1575e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org CodeTracer::Scope trace_scope(isolate->GetCodeTracer()); 1576f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org OFStream os(trace_scope.file()); 1577f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org os << "Builtin: " << functions[i].s_name << "\n"; 1578f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org code->Disassemble(functions[i].s_name, os); 1579f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org os << "\n"; 158031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager } 158131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager#endif 158243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 158343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Deserializing. The values will be filled in during IterateBuiltins. 158443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen builtins_[i] = NULL; 158543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen names_[i] = functions[i].s_name; 158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Mark as initialized. 1590ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org initialized_ = true; 159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Builtins::TearDown() { 1595ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org initialized_ = false; 159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Builtins::IterateBuiltins(ObjectVisitor* v) { 160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count); 160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 160243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* Builtins::Lookup(byte* pc) { 1605ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // may be called during initialization (disassembler!) 1606ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (initialized_) { 160743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < builtin_count; i++) { 160843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code* entry = Code::cast(builtins_[i]); 160943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (entry->contains(pc)) { 161043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return names_[i]; 161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 161343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 161443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 161543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 161643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1617a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1618dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid Builtins::Generate_InterruptCheck(MacroAssembler* masm) { 161947390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org masm->TailCallRuntime(Runtime::kInterrupt, 0, 1); 1620dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 1621dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 1622dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 1623dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid Builtins::Generate_StackCheck(MacroAssembler* masm) { 162447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org masm->TailCallRuntime(Runtime::kStackGuard, 0, 1); 1625dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 1626dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 1627dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 16287979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#define DEFINE_BUILTIN_ACCESSOR_C(name, ignore) \ 16297979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgHandle<Code> Builtins::name() { \ 16307979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Code** code_address = \ 16317979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org reinterpret_cast<Code**>(builtin_address(k##name)); \ 16327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org return Handle<Code>(code_address); \ 16337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org} 16347979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \ 16357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgHandle<Code> Builtins::name() { \ 16367979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Code** code_address = \ 16377979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org reinterpret_cast<Code**>(builtin_address(k##name)); \ 16387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org return Handle<Code>(code_address); \ 16397979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org} 1640c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org#define DEFINE_BUILTIN_ACCESSOR_H(name, kind) \ 164132aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.orgHandle<Code> Builtins::name() { \ 164232aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org Code** code_address = \ 164332aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org reinterpret_cast<Code**>(builtin_address(k##name)); \ 164432aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org return Handle<Code>(code_address); \ 164532aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org} 16467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgBUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 16477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgBUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 164832aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.orgBUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 16497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgBUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 16507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#undef DEFINE_BUILTIN_ACCESSOR_C 16517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#undef DEFINE_BUILTIN_ACCESSOR_A 16527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 16537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 1655