Bug 1082583 - Avoid shadowing iter variable in DOM bindings generated code. r=bz.
☠☠ backed out by 1caf249e58c3 ☠ ☠
authorPeter Van der Beken <peterv@propagandism.org>
Tue, 14 Oct 2014 16:12:36 +0200
changeset 210553 8d198ef0b5596bc4c6c1a72ef9ae3c981025ca65
parent 210552 49b06fb31f0b0ef0653fa11ffd5f98a7c603422e
child 210554 6f411275b7ec5dc953fdabdc198f9af5b8a35ca9
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbz
bugs1082583
milestone36.0a1
Bug 1082583 - Avoid shadowing iter variable in DOM bindings generated code. r=bz.
dom/bindings/Codegen.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3902,17 +3902,18 @@ def getJSToNativeConversionInfo(type, de
                                 treatNullAs="Default",
                                 isEnforceRange=False,
                                 isClamp=False,
                                 isNullOrUndefined=False,
                                 exceptionCode=None,
                                 lenientFloatCode=None,
                                 allowTreatNonCallableAsNull=False,
                                 isCallbackReturnValue=False,
-                                sourceDescription="value"):
+                                sourceDescription="value",
+                                nestingLevel=""):
     """
     Get a template for converting a JS value to a native object based on the
     given type and descriptor.  If failureCode is given, then we're actually
     testing whether we can convert the argument to the desired type.  That
     means that failures to convert due to the JS value being the wrong type of
     value need to use failureCode instead of throwing exceptions.  Failures to
     convert that are due to JS exceptions (from toString or valueOf methods) or
     out of memory conditions need to throw exceptions no matter what
@@ -4105,16 +4106,19 @@ def getJSToNativeConversionInfo(type, de
 
         setToNullCode = "${declName} = nullptr;\n"
         template = wrapObjectTemplate(templateBody, type, setToNullCode,
                                       failureCode)
         return JSToNativeConversionInfo(template, declType=declType,
                                         dealWithOptional=isOptional,
                                         declArgs=declArgs)
 
+    def incrementNestingLevel():
+        return 1 if nestingLevel is "" else ++nestingLevel
+
     assert not (isEnforceRange and isClamp)  # These are mutually exclusive
 
     if type.isArray():
         raise TypeError("Can't handle array arguments yet")
 
     if type.isSequence():
         assert not isEnforceRange and not isClamp
 
@@ -4152,75 +4156,77 @@ def getJSToNativeConversionInfo(type, de
             sequenceClass = "binding_detail::AutoSequence"
 
         # XXXbz we can't include the index in the sourceDescription, because
         # we don't really have a way to pass one in dynamically at runtime...
         elementInfo = getJSToNativeConversionInfo(
             elementType, descriptorProvider, isMember="Sequence",
             exceptionCode=exceptionCode, lenientFloatCode=lenientFloatCode,
             isCallbackReturnValue=isCallbackReturnValue,
-            sourceDescription="element of %s" % sourceDescription)
+            sourceDescription="element of %s" % sourceDescription,
+            nestingLevel=incrementNestingLevel())
         if elementInfo.dealWithOptional:
             raise TypeError("Shouldn't have optional things in sequences")
         if elementInfo.holderType is not None:
             raise TypeError("Shouldn't need holders for sequences")
 
         typeName = CGTemplatedType(sequenceClass, elementInfo.declType)
         sequenceType = typeName.define()
         if nullable:
             typeName = CGTemplatedType("Nullable", typeName)
             arrayRef = "${declName}.SetValue()"
         else:
             arrayRef = "${declName}"
 
         elementConversion = string.Template(elementInfo.template).substitute({
-                "val": "temp",
-                "declName": "slot",
+                "val": "temp" + str(nestingLevel),
+                "declName": "slot" + str(nestingLevel),
                 # We only need holderName here to handle isExternal()
                 # interfaces, which use an internal holder for the
                 # conversion even when forceOwningType ends up true.
-                "holderName": "tempHolder",
+                "holderName": "tempHolder" + str(nestingLevel),
                 "passedToJSImpl": "${passedToJSImpl}"
             })
 
         # NOTE: Keep this in sync with variadic conversions as needed
         templateBody = fill(
             """
-            JS::ForOfIterator iter(cx);
-            if (!iter.init($${val}, JS::ForOfIterator::AllowNonIterable)) {
+            JS::ForOfIterator iter${nestingLevel}(cx);
+            if (!iter${nestingLevel}.init($${val}, JS::ForOfIterator::AllowNonIterable)) {
               $*{exceptionCode}
             }
-            if (!iter.valueIsIterable()) {
+            if (!iter${nestingLevel}.valueIsIterable()) {
               $*{notSequence}
             }
-            ${sequenceType} &arr = ${arrayRef};
-            JS::Rooted<JS::Value> temp(cx);
+            ${sequenceType} &arr${nestingLevel} = ${arrayRef};
+            JS::Rooted<JS::Value> temp${nestingLevel}(cx);
             while (true) {
               bool done;
-              if (!iter.next(&temp, &done)) {
+              if (!iter${nestingLevel}.next(&temp, &done)) {
                 $*{exceptionCode}
               }
               if (done) {
                 break;
               }
-              ${elementType}* slotPtr = arr.AppendElement();
-              if (!slotPtr) {
+              ${elementType}* slotPtr${nestingLevel} = arr${nestingLevel}.AppendElement();
+              if (!slotPtr${nestingLevel}) {
                 JS_ReportOutOfMemory(cx);
                 $*{exceptionCode}
               }
-              ${elementType}& slot = *slotPtr;
+              ${elementType}& slot${nestingLevel} = *slotPtr${nestingLevel};
               $*{elementConversion}
             }
             """,
             exceptionCode=exceptionCode,
             notSequence=notSequence,
             sequenceType=sequenceType,
             arrayRef=arrayRef,
             elementType=elementInfo.declType.define(),
-            elementConversion=elementConversion)
+            elementConversion=elementConversion,
+            nestingLevel=str(nestingLevel))
 
         templateBody = wrapObjectTemplate(templateBody, type,
                                           "${declName}.SetNull();\n", notSequence)
         if isinstance(defaultValue, IDLEmptySequenceValue):
             if type.nullable():
                 codeToSetEmpty = "${declName}.SetValue();\n"
             else:
                 codeToSetEmpty = "/* Array is already empty; nothing to do */\n"
@@ -4257,17 +4263,18 @@ def getJSToNativeConversionInfo(type, de
             valueType = type.inner.inner
         else:
             valueType = type.inner
 
         valueInfo = getJSToNativeConversionInfo(
             valueType, descriptorProvider, isMember="MozMap",
             exceptionCode=exceptionCode, lenientFloatCode=lenientFloatCode,
             isCallbackReturnValue=isCallbackReturnValue,
-            sourceDescription="value in %s" % sourceDescription)
+            sourceDescription="value in %s" % sourceDescription,
+            nestingLevel=incrementNestingLevel())
         if valueInfo.dealWithOptional:
             raise TypeError("Shouldn't have optional things in MozMap")
         if valueInfo.holderType is not None:
             raise TypeError("Shouldn't need holders for MozMap")
 
         typeName = CGTemplatedType("MozMap", valueInfo.declType)
         mozMapType = typeName.define()
         if nullable: