Commit 94c4c596 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Array "splice" changeRecords should be emitted after the performChange has completed (per spec)

R=rossberg@chromium.org
BUG=

Review URL: https://codereview.chromium.org/23434008

Patch from Rafael Weinstein <rafaelw@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16704 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f99298bf
...@@ -399,14 +399,13 @@ function ObservedArrayPop(n) { ...@@ -399,14 +399,13 @@ function ObservedArrayPop(n) {
n--; n--;
var value = this[n]; var value = this[n];
EnqueueSpliceRecord(this, n, [value], 0);
try { try {
BeginPerformSplice(this); BeginPerformSplice(this);
delete this[n]; delete this[n];
this.length = n; this.length = n;
} finally { } finally {
EndPerformSplice(this); EndPerformSplice(this);
EnqueueSpliceRecord(this, n, [value], 0);
} }
return value; return value;
...@@ -441,8 +440,6 @@ function ObservedArrayPush() { ...@@ -441,8 +440,6 @@ function ObservedArrayPush() {
var n = TO_UINT32(this.length); var n = TO_UINT32(this.length);
var m = %_ArgumentsLength(); var m = %_ArgumentsLength();
EnqueueSpliceRecord(this, n, [], m);
try { try {
BeginPerformSplice(this); BeginPerformSplice(this);
for (var i = 0; i < m; i++) { for (var i = 0; i < m; i++) {
...@@ -451,6 +448,7 @@ function ObservedArrayPush() { ...@@ -451,6 +448,7 @@ function ObservedArrayPush() {
this.length = n + m; this.length = n + m;
} finally { } finally {
EndPerformSplice(this); EndPerformSplice(this);
EnqueueSpliceRecord(this, n, [], m);
} }
return this.length; return this.length;
...@@ -581,14 +579,13 @@ function ArrayReverse() { ...@@ -581,14 +579,13 @@ function ArrayReverse() {
function ObservedArrayShift(len) { function ObservedArrayShift(len) {
var first = this[0]; var first = this[0];
EnqueueSpliceRecord(this, 0, [first], 0);
try { try {
BeginPerformSplice(this); BeginPerformSplice(this);
SimpleMove(this, 0, 1, len, 0); SimpleMove(this, 0, 1, len, 0);
this.length = len - 1; this.length = len - 1;
} finally { } finally {
EndPerformSplice(this); EndPerformSplice(this);
EnqueueSpliceRecord(this, 0, [first], 0);
} }
return first; return first;
...@@ -627,8 +624,6 @@ function ObservedArrayUnshift() { ...@@ -627,8 +624,6 @@ function ObservedArrayUnshift() {
var len = TO_UINT32(this.length); var len = TO_UINT32(this.length);
var num_arguments = %_ArgumentsLength(); var num_arguments = %_ArgumentsLength();
EnqueueSpliceRecord(this, 0, [], num_arguments);
try { try {
BeginPerformSplice(this); BeginPerformSplice(this);
SimpleMove(this, 0, 0, len, num_arguments); SimpleMove(this, 0, 0, len, num_arguments);
...@@ -638,6 +633,7 @@ function ObservedArrayUnshift() { ...@@ -638,6 +633,7 @@ function ObservedArrayUnshift() {
this.length = len + num_arguments; this.length = len + num_arguments;
} finally { } finally {
EndPerformSplice(this); EndPerformSplice(this);
EnqueueSpliceRecord(this, 0, [], num_arguments);
} }
return len + num_arguments; return len + num_arguments;
......
...@@ -1254,6 +1254,75 @@ observer.assertCallbackRecords([ ...@@ -1254,6 +1254,75 @@ observer.assertCallbackRecords([
{ object: array, name: '0', type: 'updated', oldValue: 2 }, { object: array, name: '0', type: 'updated', oldValue: 2 },
]); ]);
// Splice emitted after Array mutation methods
function MockArray(initial, observer) {
for (var i = 0; i < initial.length; i++)
this[i] = initial[i];
this.length_ = initial.length;
this.observer = observer;
}
MockArray.prototype = {
set length(length) {
Object.getNotifier(this).notify({ type: 'lengthChange' });
this.length_ = length;
Object.observe(this, this.observer.callback, ['splice']);
},
get length() {
return this.length_;
}
}
reset();
var array = new MockArray([], observer);
Object.observe(array, observer.callback, ['lengthChange']);
Array.prototype.push.call(array, 1);
Object.deliverChangeRecords(observer.callback);
observer.assertCallbackRecords([
{ object: array, type: 'lengthChange' },
{ object: array, type: 'splice', index: 0, removed: [], addedCount: 1 },
]);
reset();
var array = new MockArray([1], observer);
Object.observe(array, observer.callback, ['lengthChange']);
Array.prototype.pop.call(array);
Object.deliverChangeRecords(observer.callback);
observer.assertCallbackRecords([
{ object: array, type: 'lengthChange' },
{ object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 },
]);
reset();
var array = new MockArray([1], observer);
Object.observe(array, observer.callback, ['lengthChange']);
Array.prototype.shift.call(array);
Object.deliverChangeRecords(observer.callback);
observer.assertCallbackRecords([
{ object: array, type: 'lengthChange' },
{ object: array, type: 'splice', index: 0, removed: [1], addedCount: 0 },
]);
reset();
var array = new MockArray([], observer);
Object.observe(array, observer.callback, ['lengthChange']);
Array.prototype.unshift.call(array, 1);
Object.deliverChangeRecords(observer.callback);
observer.assertCallbackRecords([
{ object: array, type: 'lengthChange' },
{ object: array, type: 'splice', index: 0, removed: [], addedCount: 1 },
]);
reset();
var array = new MockArray([0, 1, 2], observer);
Object.observe(array, observer.callback, ['lengthChange']);
Array.prototype.splice.call(array, 1, 1);
Object.deliverChangeRecords(observer.callback);
observer.assertCallbackRecords([
{ object: array, type: 'lengthChange' },
{ object: array, type: 'splice', index: 1, removed: [1], addedCount: 0 },
]);
// //
// === PLAIN OBJECTS === // === PLAIN OBJECTS ===
// //
......
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