Bug 1050340 - Handle object and array. r=luke
authorBobby Holley <bobbyholley@gmail.com>
Mon, 18 Aug 2014 14:18:39 -0700
changeset 200211 12fd4b703210702c464939284a3bdc71b4408ff3
parent 200210 2491548a1dccee0cbc145b0f9b386662f0b784b4
child 200212 33e14266964977ec23a64b4fab708897bf443f1e
push id27337
push useremorley@mozilla.com
push dateTue, 19 Aug 2014 12:40:34 +0000
treeherdermozilla-central@a38daccaa557 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1050340
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1050340 - Handle object and array. r=luke
js/public/Class.h
js/src/jsobjinlines.h
js/src/vm/StructuredClone.cpp
--- a/js/public/Class.h
+++ b/js/public/Class.h
@@ -513,19 +513,19 @@ Valueify(const JSClass *c)
     return (const Class *)c;
 }
 
 /*
  * Enumeration describing possible values of the [[Class]] internal property
  * value of objects.
  */
 enum ESClassValue {
-    ESClass_Array, ESClass_Number, ESClass_String, ESClass_Boolean,
-    ESClass_RegExp, ESClass_ArrayBuffer, ESClass_Date, ESClass_Set,
-    ESClass_Map
+    ESClass_Object, ESClass_Array, ESClass_Number, ESClass_String,
+    ESClass_Boolean, ESClass_RegExp, ESClass_ArrayBuffer, ESClass_Date,
+    ESClass_Set, ESClass_Map
 };
 
 /*
  * Return whether the given object has the given [[Class]] internal property
  * value. Beware, this query says nothing about the js::Class of the JSObject
  * so the caller must not assume anything about obj's representation (e.g., obj
  * may be a proxy).
  */
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1021,16 +1021,17 @@ GuessArrayGCKind(size_t numSlots)
 
 inline bool
 ObjectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx)
 {
     if (MOZ_UNLIKELY(obj->is<ProxyObject>()))
         return Proxy::objectClassIs(obj, classValue, cx);
 
     switch (classValue) {
+      case ESClass_Object: return obj->is<JSObject>();
       case ESClass_Array: return obj->is<ArrayObject>();
       case ESClass_Number: return obj->is<NumberObject>();
       case ESClass_String: return obj->is<StringObject>();
       case ESClass_Boolean: return obj->is<BooleanObject>();
       case ESClass_RegExp: return obj->is<RegExpObject>();
       case ESClass_ArrayBuffer:
         return obj->is<ArrayBufferObject>() || obj->is<SharedArrayBufferObject>();
       case ESClass_Date: return obj->is<DateObject>();
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -925,17 +925,17 @@ JSStructuredCloneWriter::traverseObject(
 
     /* Push obj and count to the stack. */
     if (!objs.append(ObjectValue(*obj)) || !counts.append(properties.length()))
         return false;
 
     checkStack();
 
     /* Write the header for obj. */
-    return out.writePair(obj->is<ArrayObject>() ? SCTAG_ARRAY_OBJECT : SCTAG_OBJECT_OBJECT, 0);
+    return out.writePair(ObjectClassIs(obj, ESClass_Array, context()) ? SCTAG_ARRAY_OBJECT : SCTAG_OBJECT_OBJECT, 0);
 }
 
 bool
 JSStructuredCloneWriter::traverseMap(HandleObject obj)
 {
     AutoValueVector newEntries(context());
     {
         // If there is no wrapper, the compartment munging is a no-op.
@@ -1037,17 +1037,19 @@ JSStructuredCloneWriter::startWrite(Hand
                    writeString(SCTAG_STRING, re->getSource());
         } else if (ObjectClassIs(obj, ESClass_Date, context())) {
             double d = js_DateGetMsecSinceEpoch(obj);
             return out.writePair(SCTAG_DATE_OBJECT, 0) && out.writeDouble(d);
         } else if (JS_IsTypedArrayObject(obj)) {
             return writeTypedArray(obj);
         } else if (JS_IsArrayBufferObject(obj) && JS_ArrayBufferHasData(obj)) {
             return writeArrayBuffer(obj);
-        } else if (obj->is<JSObject>() || obj->is<ArrayObject>()) {
+        } else if (ObjectClassIs(obj, ESClass_Object, context())) {
+            return traverseObject(obj);
+        } else if (ObjectClassIs(obj, ESClass_Array, context())) {
             return traverseObject(obj);
         } else if (ObjectClassIs(obj, ESClass_Boolean, context())) {
             RootedValue unboxed(context());
             if (!Unbox(context(), obj, &unboxed))
                 return false;
             return out.writePair(SCTAG_BOOLEAN_OBJECT, unboxed.toBoolean());
         } else if (ObjectClassIs(obj, ESClass_Number, context())) {
             RootedValue unboxed(context());