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

Unified Diff: src/objects.cc

Issue 11275292: Object.observe: Move notification of JSArray length changes to JSArray::SetElementsLength (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add test Created 8 years, 1 month 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.h ('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/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index a03054653aa16cf014d8ffd83783a7ccd4d7c223..23ff2e274ae5e9abd9e3c721e1065d45006632c0 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -9378,7 +9378,51 @@ void JSArray::Expand(int required_size) {
MaybeObject* JSArray::SetElementsLength(Object* len) {
// We should never end in here with a pixel or external array.
ASSERT(AllowsSetElementsLength());
- return GetElementsAccessor()->SetLength(this, len);
+ if (!(FLAG_harmony_observation && map()->is_observed()))
+ return GetElementsAccessor()->SetLength(this, len);
+
+ Isolate* isolate = GetIsolate();
+ HandleScope scope(isolate);
+ Handle<JSArray> self(this);
+ List<Handle<String> > indices;
+ List<Handle<Object> > old_values;
+ Handle<Object> old_length_handle(self->length());
+ Handle<Object> new_length_handle(len);
+ uint32_t old_length = 0;
+ CHECK(old_length_handle->ToArrayIndex(&old_length));
+ uint32_t new_length = 0;
+ if (!new_length_handle->ToArrayIndex(&new_length))
+ return Failure::InternalError();
+
+ // TODO(adamk): This loop can be very slow for arrays in dictionary mode.
+ // Find another way to iterate over arrays with dictionary elements.
+ for (uint32_t i = old_length - 1; i + 1 > new_length; --i) {
+ PropertyAttributes attributes = self->GetLocalElementAttribute(i);
+ if (attributes == ABSENT) continue;
+ // A non-configurable property will cause the truncation operation to
+ // stop at this index.
+ if (attributes == DONT_DELETE) break;
+ // TODO(adamk): Don't fetch the old value if it's an accessor.
+ old_values.Add(Object::GetElement(self, i));
+ indices.Add(isolate->factory()->Uint32ToString(i));
+ }
+
+ MaybeObject* result =
+ self->GetElementsAccessor()->SetLength(*self, *new_length_handle);
+ Handle<Object> hresult;
+ if (!result->ToHandle(&hresult)) return result;
+
+ CHECK(self->length()->ToArrayIndex(&new_length));
+ if (old_length != new_length) {
+ for (int i = 0; i < indices.length(); ++i) {
+ JSObject::EnqueueChangeRecord(
+ self, "deleted", indices[i], old_values[i]);
+ }
+ JSObject::EnqueueChangeRecord(
+ self, "updated", isolate->factory()->length_symbol(),
+ old_length_handle);
+ }
+ return *hresult;
}
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/harmony/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698