Bug 918351 - Support Replaceable WebIDL properties. r=bz.
authorPeter Van der Beken <peterv@propagandism.org>
Sun, 15 Sep 2013 23:04:08 +0200
changeset 165814 01b3315d12f5b94133f304b88c5bcb669e9c2944
parent 165813 1b2970c8d6dd62bfca17c47d250e09cd05eafba0
child 165815 2c1f60140a95a92baff1471350c952824460b2b8
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs918351
milestone27.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 918351 - Support Replaceable WebIDL properties. r=bz.
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1636,17 +1636,19 @@ class AttrDefiner(PropertyDefiner):
             else:
                 accessor = ("genericLenientGetter" if attr.hasLenientThis()
                             else "genericGetter")
                 jitinfo = "&%s_getterinfo" % attr.identifier.name
             return "{ JS_CAST_NATIVE_TO(%s, JSPropertyOp), %s }" % \
                    (accessor, jitinfo)
 
         def setter(attr):
-            if attr.readonly and attr.getExtendedAttribute("PutForwards") is None:
+            if (attr.readonly and
+                attr.getExtendedAttribute("PutForwards") is None and
+                attr.getExtendedAttribute("Replaceable") is None):
                 return "JSOP_NULLWRAPPER"
             if self.static:
                 accessor = 'set_' + attr.identifier.name
                 jitinfo = "nullptr"
             else:
                 accessor = ("genericLenientSetter" if attr.hasLenientThis()
                             else "genericSetter")
                 jitinfo = "&%s_setterinfo" % attr.identifier.name
@@ -5790,16 +5792,39 @@ if (!JS_GetProperty(cx, obj, "%s", &v)) 
 }
 
 if (!v.isObject()) {
   return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "%s.%s");
 }
 
 return JS_SetProperty(cx, &v.toObject(), "%s", args[0]);""" % (attrName, self.descriptor.interface.identifier.name, attrName, forwardToAttrName))).define()
 
+class CGSpecializedReplaceableSetter(CGSpecializedSetter):
+    """
+    A class for generating the code for a specialized attribute setter with
+    Replaceable that the JIT can call with lower overhead.
+    """
+    def __init__(self, descriptor, attr):
+        CGSpecializedSetter.__init__(self, descriptor, attr)
+
+    def definition_body(self):
+        attrName = self.attr.identifier.name
+        return CGIndenter(CGGeneric("""JS::Rooted<JSPropertyDescriptor> desc(cx);
+desc.object().set(obj);
+desc.setEnumerable();
+desc.value().set(args[0]);
+
+JS::Rooted<jsid> id(cx);
+if (!InternJSString(cx, id.get(), "%s")) {
+  return false;
+}
+
+bool b;
+return js_DefineOwnProperty(cx, obj, id, desc, &b);""" % attrName)).define()
+
 def memberReturnsNewObject(member):
     return member.getExtendedAttribute("NewObject") is not None
 
 class CGMemberJITInfo(CGThing):
     """
     A class for generating the JITInfo for a property that points to
     our specialized getter and setter.
     """
@@ -5844,17 +5869,19 @@ class CGMemberJITInfo(CGThing):
                            self.member.getExtendedAttribute("Constant"))
             getterpure = getterconst or self.member.getExtendedAttribute("Pure")
             assert (getterinfal or (not getterconst and not getterpure))
 
             getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
             result = self.defineJitInfo(getterinfo, getter, "Getter",
                                         getterinfal, getterconst, getterpure,
                                         [self.member.type])
-            if not self.member.readonly or self.member.getExtendedAttribute("PutForwards") is not None:
+            if (not self.member.readonly or
+                self.member.getExtendedAttribute("PutForwards") is not None or
+                self.member.getExtendedAttribute("Replaceable") is not None):
                 setterinfo = ("%s_setterinfo" % self.member.identifier.name)
                 # Actually a JSJitSetterOp, but JSJitGetterOp is first in the
                 # union.
                 setter = ("(JSJitGetterOp)set_%s" % self.member.identifier.name)
                 # Setters are always fallible, since they have to do a typed unwrap.
                 result += self.defineJitInfo(setterinfo, setter, "Setter",
                                              False, False, False,
                                              [BuiltinTypes[IDLBuiltinType.Types.void]])
@@ -7966,16 +7993,19 @@ class CGDescriptor(CGThing):
                         cgThings.append(CGSpecializedSetter(descriptor, m))
                         if m.hasLenientThis():
                             hasLenientSetter = True
                         else:
                             hasSetter = True
                 elif m.getExtendedAttribute("PutForwards"):
                     cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
                     hasSetter = True
+                elif m.getExtendedAttribute("Replaceable"):
+                    cgThings.append(CGSpecializedReplaceableSetter(descriptor, m))
+                    hasSetter = True
                 if (not m.isStatic() and
                     descriptor.interface.hasInterfacePrototypeObject()):
                     cgThings.append(CGMemberJITInfo(descriptor, m))
         if hasJsonifier:
             cgThings.append(CGJsonifierMethod(descriptor, jsonifierMethod))
             cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod))
         if hasMethod: cgThings.append(CGGenericMethod(descriptor))
         if hasGetter: cgThings.append(CGGenericGetter(descriptor))