Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: src/v8natives.js

Issue 15504002: Array.observe emit splices for array length change and update index >= length (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: cr comments Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.cc ('k') | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « src/objects.cc ('k') | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698