Bug 1051109 - Define non-static method to jsonify interface attributes r=smaug
authorValentin Gosu <valentin.gosu@gmail.com>
Mon, 11 Aug 2014 01:17:50 +0300
changeset 198807 71a1dcb2697de1356e0f78d71dfe573e60fecaef
parent 198806 5709d54523ef034d4e1e8466ad4e451dcb6116bf
child 198808 c8657abef1d770f95c85e554d470fc908a3d4e3e
push id27286
push usernigelbabu@gmail.com
push dateMon, 11 Aug 2014 06:26:45 +0000
treeherdermozilla-central@8c4a1b3a2a8b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1051109
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 1051109 - Define non-static method to jsonify interface attributes r=smaug
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -2440,16 +2440,47 @@ class CGNativeProperties(CGList):
         CGList.__init__(self, nativeProperties, "\n")
 
     def declare(self):
         return ""
 
     def define(self):
         return CGList.define(self)
 
+class CGJsonifyAttributesMethod(CGAbstractMethod):
+    """
+    Generate the JsonifyAttributes method for an interface descriptor
+    """
+    def __init__(self, descriptor):
+        args = [Argument('JSContext*', 'aCx'),
+                Argument('JS::Handle<JSObject*>', 'obj'),
+                Argument('%s*' % descriptor.nativeType, 'self'),
+                Argument('JS::Rooted<JSObject*>&', 'aResult')]
+        CGAbstractMethod.__init__(self, descriptor, 'JsonifyAttributes', 'bool', args)
+
+    def definition_body(self):
+        ret = ''
+        interface = self.descriptor.interface
+        for m in interface.members:
+            if m.isAttr() and not m.isStatic() and m.type.isSerializable():
+                ret += fill(
+                    """
+                    { // scope for "temp"
+                      JS::Rooted<JS::Value> temp(aCx);
+                      if (!get_${name}(aCx, obj, self, JSJitGetterCallArgs(&temp))) {
+                        return false;
+                      }
+                      if (!JS_DefineProperty(aCx, aResult, "${name}", temp, JSPROP_ENUMERATE)) {
+                        return false;
+                      }
+                    }
+                    """,
+                    name=m.identifier.name)
+        ret += 'return true;\n'
+        return ret
 
 class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
     """
     Generate the CreateInterfaceObjects method for an interface descriptor.
 
     properties should be a PropertyArrays instance.
     """
     def __init__(self, descriptor, properties):
@@ -7239,38 +7270,34 @@ class CGJsonifierMethod(CGSpecializedMet
     def definition_body(self):
         ret = dedent("""
             JS::Rooted<JSObject*> result(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
             if (!result) {
               return false;
             }
             """)
 
+        jsonInterfaces = []
         interface = self.descriptor.interface
         while interface:
             descriptor = self.descriptor.getDescriptor(interface.identifier.name)
             if descriptor.operations['Jsonifier']:
-                for m in interface.members:
-                    if m.isAttr() and not m.isStatic() and m.type.isSerializable():
-                        ret += fill(
-                            """
-                            { // scope for "temp"
-                              JS::Rooted<JS::Value> temp(cx);
-                              if (!${parentclass}::get_${name}(cx, obj, self, JSJitGetterCallArgs(&temp))) {
-                                return false;
-                              }
-                              if (!JS_DefineProperty(cx, result, "${name}", temp, JSPROP_ENUMERATE)) {
-                                return false;
-                              }
-                            }
-                            """,
-                            parentclass=toBindingNamespace(interface.identifier.name),
-                            name=m.identifier.name)
+                jsonInterfaces.append(interface)
             interface = interface.parent
 
+        # Iterate the array in reverse: oldest ancestor first
+        for interface in jsonInterfaces[::-1]:
+            ret += fill(
+                """
+                if (!${parentclass}::JsonifyAttributes(cx, obj, self, result)) {
+                  return false;
+                }
+                """,
+                parentclass=toBindingNamespace(interface.identifier.name)
+                )
         ret += ('args.rval().setObject(*result);\n'
                 'return true;\n')
         return ret
 
 
 class CGLegacyCallHook(CGAbstractBindingMethod):
     """
     Call hook for our object
@@ -10599,16 +10626,17 @@ class CGDescriptor(CGThing):
             hasPromiseReturningMethod = (hasPromiseReturningMethod or
                                          props.isPromiseReturningMethod)
             hasGetter = hasGetter or props.isGenericGetter
             hasLenientGetter = hasLenientGetter or props.isLenientGetter
             hasSetter = hasSetter or props.isGenericSetter
             hasLenientSetter = hasLenientSetter or props.isLenientSetter
 
         if jsonifierMethod:
+            cgThings.append(CGJsonifyAttributesMethod(descriptor))
             cgThings.append(CGJsonifierMethod(descriptor, jsonifierMethod))
             cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod))
         if hasMethod:
             cgThings.append(CGGenericMethod(descriptor))
         if hasPromiseReturningMethod:
             cgThings.append(CGGenericPromiseReturningMethod(descriptor))
         if len(crossOriginMethods):
             cgThings.append(CGGenericMethod(descriptor,