| 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, | 
| +          removed, | 
| +          removed.length, | 
| +          new_length > old_length ? new_length - old_length : 0); | 
| +    } | 
| 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; | 
| } | 
|  | 
|  |