Bug 458098 - js_DumpObject can't handle objects that share proto's scope (r=crowder)
authorJason Orendorff <jorendorff@mozilla.com>
Thu, 09 Oct 2008 07:30:21 -0500
changeset 20208 765855ec09b08c76075d130f8c72c5655aa42b9a
parent 20207 918a110a68e4f426b38bf510bac74ed51a85a9df
child 20209 068446ee54932617558b464072e00102c00f5686
push idunknown
push userunknown
push dateunknown
reviewerscrowder
bugs458098
milestone1.9.1b2pre
Bug 458098 - js_DumpObject can't handle objects that share proto's scope (r=crowder)
js/src/jsobj.cpp
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -5414,17 +5414,17 @@ js_DumpValue(jsval val)
 JS_FRIEND_API(void)
 js_DumpId(jsid id)
 {
     fprintf(stderr, "id %d (%p) = ", (int) id, (void *) id);
     dumpValue(ID_TO_VALUE(id));
     fputc('\n', stderr);
 }
 
-void
+static void
 dumpScopeProp(JSScopeProperty *sprop)
 {
     jsid id = sprop->id;
     uint8 attrs = sprop->attrs;
 
     fprintf(stderr, "    ");
     if (attrs & JSPROP_ENUMERATE) fprintf(stderr, "enumerate ");
     if (attrs & JSPROP_READONLY) fprintf(stderr, "readonly ");
@@ -5444,16 +5444,17 @@ dumpScopeProp(JSScopeProperty *sprop)
 }
 
 JS_FRIEND_API(void)
 js_DumpObject(JSObject *obj)
 {
     uint32 i, slots;
     JSClass *clasp;
     jsuint reservedEnd;
+    JSBool sharesScope = JS_FALSE;
 
     fprintf(stderr, "object %p\n", (void *) obj);
     clasp = STOBJ_GET_CLASS(obj);
     fprintf(stderr, "class %p %s\n", (void *)clasp, clasp->name);
 
     /* OBJ_IS_DENSE_ARRAY ignores the cx argument. */
     if (OBJ_IS_DENSE_ARRAY(BOGUS_CX, obj)) {
         slots = JS_MIN((jsuint) obj->fslots[JSSLOT_ARRAY_LENGTH],
@@ -5470,44 +5471,45 @@ js_DumpObject(JSObject *obj)
 
     if (OBJ_IS_NATIVE(obj)) {
         JSScope *scope = OBJ_SCOPE(obj);
         JSObject *proto = STOBJ_GET_PROTO(obj);
 
         if (SCOPE_IS_SEALED(scope))
             fprintf(stderr, "sealed\n");
 
-        if (proto && scope == OBJ_SCOPE(proto)) {
-            fprintf(stderr, "shares scope with proto (%s at %p)\n",
+        sharesScope = (scope->object != obj);
+        if (sharesScope) {
+            fprintf(stderr, "no own properties - see proto (%s at %p)\n",
                     STOBJ_GET_CLASS(proto)->name, proto);
-        }
-
-        fprintf(stderr, "properties:\n");
-        for (JSScopeProperty *sprop = SCOPE_LAST_PROP(scope); sprop;
-             sprop = sprop->parent) {
-            if (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
-                SCOPE_HAS_PROPERTY(scope, sprop)) {
-                dumpScopeProp(sprop);
+        } else {
+            fprintf(stderr, "properties:\n");
+            for (JSScopeProperty *sprop = SCOPE_LAST_PROP(scope); sprop;
+                 sprop = sprop->parent) {
+                if (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
+                    SCOPE_HAS_PROPERTY(scope, sprop)) {
+                    dumpScopeProp(sprop);
+                }
             }
         }
     } else {
         if (!OBJ_IS_NATIVE(obj))
             fprintf(stderr, "not native\n");
     }
 
     fprintf(stderr, "slots:\n");
-    slots = obj->map->freeslot;
     reservedEnd = JSSLOT_PRIVATE;
     if (clasp->flags & JSCLASS_HAS_PRIVATE)
         reservedEnd++;
     reservedEnd += JSCLASS_RESERVED_SLOTS(clasp);
+    slots = sharesScope ? reservedEnd : obj->map->freeslot;
     for (i = 0; i < slots; i++) {
         fprintf(stderr, " %3d ", i);
         if (i == JSSLOT_PRIVATE && (clasp->flags & JSCLASS_HAS_PRIVATE)) {
-            fprintf(stderr, "(private) = %p",
+            fprintf(stderr, "(private) = %p\n",
                     JSVAL_TO_PRIVATE(STOBJ_GET_SLOT(obj, i)));
             continue;
         }
         if (i == JSSLOT_PROTO)
             fprintf(stderr, "(proto) ");
         else if (i == JSSLOT_PARENT)
             fprintf(stderr, "(parent) ");
         else if (i < reservedEnd)