Bug 1299306 part 2. Call JS_SetImmutablePrototype on Location instances to make their prototype immutable in a more spec-compliant way. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 02 Sep 2016 17:55:38 -0400
changeset 312569 f3c975a2bc7eb37a566b3917a4502e12111160c6
parent 312568 2b20981109d68bfc483317bd531111aee171dd47
child 312570 7d6d85635ddb7c88a2ed5fb6dafc40f3096619ee
push id30646
push userryanvm@gmail.com
push dateSat, 03 Sep 2016 15:33:40 +0000
treeherdermozilla-central@1789229965bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1299306
milestone51.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 1299306 part 2. Call JS_SetImmutablePrototype on Location instances to make their prototype immutable in a more spec-compliant way. r=peterv
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3482,16 +3482,34 @@ def InitMemberSlots(descriptor, failureC
         """
         if (!UpdateMemberSlots(aCx, aReflector, aObject)) {
           $*{failureCode}
         }
         """,
         failureCode=failureCode)
 
 
+def SetImmutablePrototype(descriptor, failureCode):
+    if not descriptor.hasNonOrdinaryGetPrototypeOf():
+        return ""
+
+    return fill(
+        """
+        bool succeeded;
+        if (!JS_SetImmutablePrototype(aCx, aReflector, &succeeded)) {
+          ${failureCode}
+        }
+        MOZ_ASSERT(succeeded,
+                   "Making a fresh reflector instance have an immutable "
+                   "prototype can internally fail, but it should never be "
+                   "unsuccessful");
+        """,
+        failureCode=failureCode)
+
+
 def DeclareProto():
     """
     Declare the canonicalProto and proto we have for our wrapping operation.
     """
     return dedent(
         """
         JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
         if (!canonicalProto) {
@@ -3579,16 +3597,17 @@ class CGWrapWithCacheMethod(CGAbstractMe
             JSAutoCompartment ac(aCx, global);
             $*{declareProto}
 
             $*{createObject}
 
             aCache->SetWrapper(aReflector);
             $*{unforgeable}
             $*{slots}
+            $*{setImmutablePrototype}
             creator.InitializationSucceeded();
 
             MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
                        aCache->GetWrapperPreserveColor() == aReflector);
             // If proto != canonicalProto, we have to preserve our wrapper;
             // otherwise we won't be able to properly recreate it later, since
             // we won't know what proto to use.  Note that we don't check
             // aGivenProto here, since it's entirely possible (and even
@@ -3601,16 +3620,18 @@ class CGWrapWithCacheMethod(CGAbstractMe
             return true;
             """,
             assertInheritance=AssertInheritanceChain(self.descriptor),
             declareProto=DeclareProto(),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor,
                                                             failureCode),
             slots=InitMemberSlots(self.descriptor, failureCode),
+            setImmutablePrototype=SetImmutablePrototype(self.descriptor,
+                                                        failureCode),
             preserveWrapper=preserveWrapper)
 
 
 class CGWrapMethod(CGAbstractMethod):
     def __init__(self, descriptor):
         # XXX can we wrap if we don't have an interface prototype object?
         assert descriptor.interface.hasInterfacePrototypeObject()
         args = [Argument('JSContext*', 'aCx'),
@@ -3653,25 +3674,29 @@ class CGWrapNonWrapperCacheMethod(CGAbst
             JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
             $*{declareProto}
 
             $*{createObject}
 
             $*{unforgeable}
 
             $*{slots}
+
+            $*{setImmutablePrototype}
             creator.InitializationSucceeded();
             return true;
             """,
             assertions=AssertInheritanceChain(self.descriptor),
             declareProto=DeclareProto(),
             createObject=CreateBindingJSObject(self.descriptor, self.properties),
             unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor,
                                                             failureCode),
-            slots=InitMemberSlots(self.descriptor, failureCode))
+            slots=InitMemberSlots(self.descriptor, failureCode),
+            setImmutablePrototype=SetImmutablePrototype(self.descriptor,
+                                                        failureCode))
 
 
 class CGWrapGlobalMethod(CGAbstractMethod):
     """
     Create a wrapper JSObject for a global.  The global must implement
     nsWrapperCache.
 
     properties should be a PropertyArrays instance.