Commit 61d2ebde authored by antonm@chromium.org's avatar antonm@chromium.org

Fix invalid fast return in splice when returned array is empty.

TBR=vitalyr@chromium.org

Review URL: http://codereview.chromium.org/669101

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4027 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 56eb46e0
......@@ -616,30 +616,34 @@ BUILTIN(ArraySplice) {
}
}
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);
FixedArray* elms = FixedArray::cast(array->elements());
result = Heap::AllocateUninitializedFixedArray(actualDeleteCount);
if (result->IsFailure()) return result;
FixedArray* result_elms = FixedArray::cast(result);
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);
FixedArray* elms = FixedArray::cast(array->elements());
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);
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 elements.
result_array->set_elements(result_elms);
// Set the length.
result_array->set_length(Smi::FromInt(actualDeleteCount));
// Set the length.
result_array->set_length(Smi::FromInt(actualDeleteCount));
}
int itemCount = (n_arguments > 1) ? (n_arguments - 2) : 0;
......@@ -647,6 +651,7 @@ BUILTIN(ArraySplice) {
if (itemCount < actualDeleteCount) {
// Shrink the array.
AssertNoAllocation no_gc;
MoveElements(&no_gc,
elms, actualStart + itemCount,
elms, actualStart + actualDeleteCount,
......@@ -667,6 +672,7 @@ BUILTIN(ArraySplice) {
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 @@ BUILTIN(ArraySplice) {
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);
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment