Chromium Code Reviews| Index: src/v8natives.js |
| diff --git a/src/v8natives.js b/src/v8natives.js |
| index f5ab122ff0aa8d2a1604f640ca97de7cb2499d1e..d444613f3a8ad0422aeae6d84c0f7cf7636bc2e8 100644 |
| --- a/src/v8natives.js |
| +++ b/src/v8natives.js |
| @@ -873,6 +873,7 @@ function DefineArrayProperty(obj, p, desc, should_throw) { |
| // Step 3 - Special handling for length property. |
| if (p === "length") { |
| var length = obj.length; |
| + var old_length = length; |
| if (!desc.hasValue()) { |
| return DefineObjectProperty(obj, "length", desc, should_throw); |
| } |
| @@ -889,8 +890,24 @@ function DefineArrayProperty(obj, p, desc, should_throw) { |
| } |
| } |
| var threw = false; |
| + |
| + var emit_splice = %IsObserved(obj) && new_length !== old_length; |
| + var removed; |
| + if (emit_splice) { |
| + BeginPerformSplice(obj); |
| + removed = []; |
| + if (new_length < old_length) |
| + removed.length = old_length - new_length; |
| + } |
| + |
| while (new_length < length--) { |
| - if (!Delete(obj, ToString(length), false)) { |
| + var index = ToString(length); |
| + if (emit_splice) { |
| + var deletedDesc = GetOwnProperty(obj, index); |
| + if (deletedDesc && deletedDesc.hasValue()) |
| + removed[length - new_length] = deletedDesc.getValue(); |
| + } |
| + if (!Delete(obj, index, false)) { |
| new_length = length + 1; |
| threw = true; |
| break; |
| @@ -902,13 +919,18 @@ function DefineArrayProperty(obj, p, desc, should_throw) { |
| // respective TODO in Runtime_DefineOrRedefineDataProperty. |
| // For the time being, we need a hack to prevent Object.observe from |
| // generating two change records. |
| - var isObserved = %IsObserved(obj); |
| - if (isObserved) %SetIsObserved(obj, false); |
| obj.length = new_length; |
| desc.value_ = void 0; |
| desc.hasValue_ = false; |
| threw = !DefineObjectProperty(obj, "length", desc, should_throw) || threw; |
| - if (isObserved) %SetIsObserved(obj, true); |
| + if (emit_splice) { |
| + EndPerformSplice(obj); |
| + EnqueueSpliceRecord(obj, |
| + new_length < old_length ? new_length : old_length, |
|
rossberg
2013/05/27 14:48:41
Perhaps use Math.min
rafaelw
2013/05/28 11:38:53
Math. doesn't seem to be available from here. If t
rossberg
2013/06/04 10:56:58
You're right, Math is defined later in the bootstr
|
| + removed, |
| + removed.length, |
| + new_length > old_length ? new_length - old_length : 0); |
|
rossberg
2013/05/27 14:48:41
Perhaps use Math.max
rafaelw
2013/05/28 11:38:53
Ditto.
On 2013/05/27 14:48:41, rossberg wrote:
|
| + } |
| if (threw) { |
| if (should_throw) { |
| throw MakeTypeError("redefine_disallowed", [p]); |
| @@ -916,27 +938,24 @@ function DefineArrayProperty(obj, p, desc, should_throw) { |
| return false; |
| } |
| } |
| - if (isObserved) { |
| - var new_desc = GetOwnProperty(obj, "length"); |
| - var updated = length_desc.value_ !== new_desc.value_; |
| - var reconfigured = length_desc.writable_ !== new_desc.writable_ || |
| - length_desc.configurable_ !== new_desc.configurable_ || |
| - length_desc.enumerable_ !== new_desc.configurable_; |
| - if (updated || reconfigured) { |
| - NotifyChange(reconfigured ? "reconfigured" : "updated", |
| - obj, "length", length_desc.value_); |
| - } |
| - } |
| return true; |
| } |
| // Step 4 - Special handling for array index. |
| var index = ToUint32(p); |
| + var emit_splice = false; |
| if (ToString(index) == p && index != 4294967295) { |
| var length = obj.length; |
| + if (index >= length && %IsObserved(obj)) { |
| + emit_splice = true; |
| + BeginPerformSplice(obj); |
| + } |
| + |
| var length_desc = GetOwnProperty(obj, "length"); |
| if ((index >= length && !length_desc.isWritable()) || |
| !DefineObjectProperty(obj, p, desc, true)) { |
| + if (emit_splice) |
| + EndPerformSplice(obj); |
| if (should_throw) { |
| throw MakeTypeError("define_disallowed", [p]); |
| } else { |
| @@ -946,6 +965,10 @@ function DefineArrayProperty(obj, p, desc, should_throw) { |
| if (index >= length) { |
| obj.length = index + 1; |
| } |
| + if (emit_splice) { |
| + EndPerformSplice(obj); |
| + EnqueueSpliceRecord(obj, length, [], 0, index + 1 - length); |
| + } |
| return true; |
| } |