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

Unified Diff: src/runtime.cc

Issue 18658: Added handling of hidden prototype objects when collecting local properties f... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 11 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/runtime.h ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 1116)
+++ src/runtime.cc (working copy)
@@ -4536,6 +4536,21 @@
}
+// Find the length of the prototype chain that is to to handled as one. If a
+// prototype object is hidden it is to be viewed as part of the the object it
+// is prototype for.
+static int LocalPrototypeChainLength(JSObject* obj) {
+ int count = 1;
+ Object* proto = obj->GetPrototype();
+ while (proto->IsJSObject() &&
+ JSObject::cast(proto)->map()->is_hidden_prototype()) {
+ count++;
+ proto = JSObject::cast(proto)->GetPrototype();
+ }
+ return count;
+}
+
+
static Object* DebugLookupResultValue(Object* receiver, LookupResult* result,
bool* caught_exception) {
Object* value;
@@ -4611,6 +4626,13 @@
CONVERT_ARG_CHECKED(JSObject, obj, 0);
CONVERT_ARG_CHECKED(String, name, 1);
+ // Skip the global proxy as it has no properties and always delegates to the
+ // real global object.
+ if (obj->IsJSGlobalProxy()) {
+ obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
+ }
+
+
// Check if the name is trivially convertible to an index and get the element
// if so.
uint32_t index;
@@ -4621,9 +4643,22 @@
return *Factory::NewJSArrayWithElements(details);
}
- // Perform standard local lookup on the object.
+ // Find the number of objects making up this.
+ int length = LocalPrototypeChainLength(*obj);
+
+ // Try local lookup on each of the objects.
LookupResult result;
- obj->LocalLookup(*name, &result);
+ Handle<JSObject> jsproto = obj;
+ for (int i = 0; i < length; i++) {
+ jsproto->LocalLookup(*name, &result);
+ if (result.IsProperty()) {
+ break;
+ }
+ if (i < length - 1) {
+ jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ }
+ }
+
if (result.IsProperty()) {
bool caught_exception = false;
Handle<Object> value(DebugLookupResultValue(*obj, &result,
@@ -4676,12 +4711,43 @@
}
CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ // Skip the global proxy as it has no properties and always delegates to the
+ // real global object.
if (obj->IsJSGlobalProxy()) {
obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
}
- int n = obj->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
- Handle<FixedArray> names = Factory::NewFixedArray(n);
- obj->GetLocalPropertyNames(*names);
+
+ // Find the number of objects making up this.
+ int length = LocalPrototypeChainLength(*obj);
+
+ // Find the number of local properties for each of the objects.
+ int* local_property_count = NewArray<int>(length);
+ int total_property_count = 0;
+ Handle<JSObject> jsproto = obj;
+ for (int i = 0; i < length; i++) {
+ int n;
+ n = jsproto->NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE));
+ local_property_count[i] = n;
+ total_property_count += n;
+ if (i < length - 1) {
+ jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ }
+ }
+
+ // Allocate an array with storage for all the property names.
+ Handle<FixedArray> names = Factory::NewFixedArray(total_property_count);
+
+ // Get the property names.
+ jsproto = obj;
+ for (int i = 0; i < length; i++) {
+ jsproto->GetLocalPropertyNames(*names,
+ i == 0 ? 0 : local_property_count[i - 1]);
+ if (i < length - 1) {
+ jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ }
+ }
+
+ DeleteArray(local_property_count);
return *Factory::NewJSArrayWithElements(names);
}
@@ -5809,12 +5875,15 @@
}
-static Object* Runtime_GetPrototype(Arguments args) {
+// Find the effective prototype object as returned by __proto__.
+// args[0]: the object to find the prototype for.
+static Object* Runtime_DebugGetPrototype(Arguments args) {
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSObject, obj, args[0]);
- return obj->GetPrototype();
+ // Use the __proto__ accessor.
+ return Accessors::ObjectPrototype.getter(obj, NULL);
}
« no previous file with comments | « src/runtime.h ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698