Revision: 3853
Author: [email protected]
Date: Mon Feb 15 01:17:38 2010
Log: Introduce builtin for Array.shift function.

Review URL: http://codereview.chromium.org/606017
http://code.google.com/p/v8/source/detail?r=3853

Added:
 /branches/bleeding_edge/test/mjsunit/array-shift.js
Modified:
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/builtins.cc
 /branches/bleeding_edge/src/builtins.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/array-shift.js Mon Feb 15 01:17:38 2010
@@ -0,0 +1,46 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check that shifting array of holes keeps it as array of holes
+(function() {
+  var array = new Array(10);
+  array.shift();
+  assertFalse(0 in array);
+})();
+
+// Now check the case with array of holes and some elements on prototype.
+(function() {
+  var array = new Array(10);
+  Array.prototype[7] = "@7";
+  assertEquals(array[0], undefined);
+  assertEquals(array[7], Array.prototype[7]);
+
+  array.shift();
+
+  assertEquals(array[0], undefined);
+  assertEquals(array[7], Array.prototype[7]);
+})();
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Thu Feb 11 00:05:33 2010
+++ /branches/bleeding_edge/src/bootstrapper.cc Mon Feb 15 01:17:38 2010
@@ -1473,25 +1473,27 @@
 void Genesis::BuildSpecialFunctionTable() {
   HandleScope scope;
   Handle<JSObject> global = Handle<JSObject>(global_context()->global());
-  // Add special versions for Array.prototype.pop and push.
+  // Add special versions for some Array.prototype functions.
   Handle<JSFunction> function =
       Handle<JSFunction>(
           JSFunction::cast(global->GetProperty(Heap::Array_symbol())));
   Handle<JSObject> visible_prototype =
       Handle<JSObject>(JSObject::cast(function->prototype()));
-  // Remember to put push and pop on the hidden prototype if it's there.
-  Handle<JSObject> push_and_pop_prototype;
+ // Remember to put those specializations on the hidden prototype if present.
+  Handle<JSObject> special_prototype;
   Handle<Object> superproto(visible_prototype->GetPrototype());
   if (superproto->IsJSObject() &&
       JSObject::cast(*superproto)->map()->is_hidden_prototype()) {
-    push_and_pop_prototype = Handle<JSObject>::cast(superproto);
+    special_prototype = Handle<JSObject>::cast(superproto);
   } else {
-    push_and_pop_prototype = visible_prototype;
-  }
-  AddSpecialFunction(push_and_pop_prototype, "pop",
+    special_prototype = visible_prototype;
+  }
+  AddSpecialFunction(special_prototype, "pop",
                      Handle<Code>(Builtins::builtin(Builtins::ArrayPop)));
-  AddSpecialFunction(push_and_pop_prototype, "push",
+  AddSpecialFunction(special_prototype, "push",
                      Handle<Code>(Builtins::builtin(Builtins::ArrayPush)));
+  AddSpecialFunction(special_prototype, "shift",
+ Handle<Code>(Builtins::builtin(Builtins::ArrayShift)));
 }


=======================================
--- /branches/bleeding_edge/src/builtins.cc     Fri Feb 12 06:21:18 2010
+++ /branches/bleeding_edge/src/builtins.cc     Mon Feb 15 01:17:38 2010
@@ -311,6 +311,43 @@

   return top;
 }
+
+
+BUILTIN(ArrayShift) {
+  JSArray* array = JSArray::cast(*args.receiver());
+  ASSERT(array->HasFastElements());
+
+  int len = Smi::cast(array->length())->value();
+  if (len == 0) return Heap::undefined_value();
+
+  // Fetch the prototype.
+  JSFunction* array_function =
+      Top::context()->global_context()->array_function();
+  JSObject* prototype = JSObject::cast(array_function->prototype());
+
+  // Get first element
+  FixedArray* elms = FixedArray::cast(array->elements());
+  Object* first = elms->get(0);
+
+  if (first->IsTheHole()) {
+    first = prototype->GetElement(0);
+  }
+
+  // Shift the elements.
+  for (int i = 0; i < len - 1; i++) {
+    Object* e = elms->get(i + 1);
+    if (e->IsTheHole() && prototype->HasElement(i + 1)) {
+      e = prototype->GetElement(i + 1);
+    }
+    elms->set(i, e);
+  }
+  elms->set(len - 1, Heap::the_hole_value());
+
+  // Set the length.
+  array->set_length(Smi::FromInt(len - 1));
+
+  return first;
+}


// -----------------------------------------------------------------------------
=======================================
--- /branches/bleeding_edge/src/builtins.h      Fri Feb 12 06:21:18 2010
+++ /branches/bleeding_edge/src/builtins.h      Mon Feb 15 01:17:38 2010
@@ -48,6 +48,7 @@
                                                                     \
   V(ArrayPush, NO_EXTRA_ARGUMENTS)                                  \
   V(ArrayPop, NO_EXTRA_ARGUMENTS)                                   \
+  V(ArrayShift, NO_EXTRA_ARGUMENTS)                                 \
                                                                     \
   V(HandleApiCall, NEEDS_CALLED_FUNCTION)                           \
   V(FastHandleApiCall, NO_EXTRA_ARGUMENTS)                          \

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to