Revision: 4027
Author: [email protected]
Date: Thu Mar  4 14:16:58 2010
Log: Fix invalid fast return in splice when returned array is empty.

[email protected]

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

Modified:
 /branches/bleeding_edge/src/builtins.cc
 /branches/bleeding_edge/test/mjsunit/array-splice.js

=======================================
--- /branches/bleeding_edge/src/builtins.cc     Thu Mar  4 13:29:33 2010
+++ /branches/bleeding_edge/src/builtins.cc     Thu Mar  4 14:16:58 2010
@@ -616,30 +616,34 @@
     }
   }
   int actualDeleteCount = Min(Max(deleteCount, 0), len - actualStart);
-  if (actualDeleteCount == 0) {
-    return AllocateEmptyJSArray();
-  }
-
-  // Allocate result array.
-  Object* result = AllocateJSArray();
-  if (result->IsFailure()) return result;
-  JSArray* result_array = JSArray::cast(result);
-
-  result = Heap::AllocateUninitializedFixedArray(actualDeleteCount);
-  if (result->IsFailure()) return result;
-  FixedArray* result_elms = FixedArray::cast(result);
-
-  FixedArray* elms = FixedArray::cast(array->elements());
-
-  AssertNoAllocation no_gc;
-  // Fill newly created array.
- CopyElements(&no_gc, result_elms, 0, elms, actualStart, actualDeleteCount);
-
-  // Set elements.
-  result_array->set_elements(result_elms);
-
-  // Set the length.
-  result_array->set_length(Smi::FromInt(actualDeleteCount));
+
+  FixedArray* elms = FixedArray::cast(array->elements());
+
+  JSArray* result_array = NULL;
+  if (actualDeleteCount == 0) {
+    Object* result = AllocateEmptyJSArray();
+    if (result->IsFailure()) return result;
+    result_array = JSArray::cast(result);
+  } else {
+    // Allocate result array.
+    Object* result = AllocateJSArray();
+    if (result->IsFailure()) return result;
+    result_array = JSArray::cast(result);
+
+    result = Heap::AllocateUninitializedFixedArray(actualDeleteCount);
+    if (result->IsFailure()) return result;
+    FixedArray* result_elms = FixedArray::cast(result);
+
+    AssertNoAllocation no_gc;
+    // Fill newly created array.
+ CopyElements(&no_gc, result_elms, 0, elms, actualStart, actualDeleteCount);
+
+    // Set elements.
+    result_array->set_elements(result_elms);
+
+    // Set the length.
+    result_array->set_length(Smi::FromInt(actualDeleteCount));
+  }

   int itemCount = (n_arguments > 1) ? (n_arguments - 2) : 0;

@@ -647,6 +651,7 @@

   if (itemCount < actualDeleteCount) {
     // Shrink the array.
+    AssertNoAllocation no_gc;
     MoveElements(&no_gc,
                  elms, actualStart + itemCount,
                  elms, actualStart + actualDeleteCount,
@@ -667,6 +672,7 @@
       if (obj->IsFailure()) return obj;
       FixedArray* new_elms = FixedArray::cast(obj);

+      AssertNoAllocation no_gc;
       // Copy the part before actualStart as is.
       CopyElements(&no_gc, new_elms, 0, elms, 0, actualStart);
       FillWithHoles(new_elms, new_length, capacity);
@@ -676,12 +682,14 @@
       array->set_elements(elms);
     }

+    AssertNoAllocation no_gc;
     MoveElements(&no_gc,
                  elms, actualStart + itemCount,
                  source_elms, actualStart + actualDeleteCount,
                  (len - actualDeleteCount - actualStart));
   }

+  AssertNoAllocation no_gc;
   WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
   for (int k = actualStart; k < actualStart + itemCount; k++) {
     elms->set(k, args[3 + k - actualStart], mode);
=======================================
--- /branches/bleeding_edge/test/mjsunit/array-splice.js Thu Mar 4 13:29:33 2010 +++ /branches/bleeding_edge/test/mjsunit/array-splice.js Thu Mar 4 14:16:58 2010
@@ -53,6 +53,16 @@
 })();


+// Check that even if result array is empty, receiver gets sliced.
+(function() {
+  for (var i = 0; i < 7; i++) {
+    var a = [1, 2, 3];
+    assertEquals([], a.splice(1, 0, 'a', 'b', 'c'));
+    assertEquals([1, 'a', 'b', 'c', 2, 3], a);
+  }
+})();
+
+
 // Check various forms of arguments omission.
 (function() {
   var array;

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

Reply via email to