Bug 785096: part3: Removing ccx from codegen/qsgen. r=bholley
authorGabor Krizsanits <gkrizsanits@mozilla.com>
Thu, 20 Sep 2012 15:04:28 +0200
changeset 107616 3cd3840dea0bea00978c13fc338642d0d401c385
parent 107615 343dde4d974df3f3d46ff22b5bfec24fe60b7983
child 107617 e21f9042824fe071845302042b37b8b1200f6653
push id15132
push usergkrizsanits@mozilla.com
push dateThu, 20 Sep 2012 13:05:03 +0000
treeherdermozilla-inbound@3cd3840dea0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs785096
milestone18.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 785096: part3: Removing ccx from codegen/qsgen. r=bholley
js/xpconnect/src/codegen.py
js/xpconnect/src/dombindingsgen.py
js/xpconnect/src/qsgen.py
--- a/js/xpconnect/src/codegen.py
+++ b/js/xpconnect/src/codegen.py
@@ -156,17 +156,17 @@ argumentUnboxingTemplates = {
     }
 
 # From JSData2Native.
 #
 # Omitted optional arguments are treated as though the caller had passed JS
 # `null`; this behavior is from XPCWrappedNative::CallMethod. The 'jsval' type,
 # however, defaults to 'undefined'.
 #
-def writeArgumentUnboxing(f, i, name, type, haveCcx, optional, rvdeclared,
+def writeArgumentUnboxing(f, i, name, type, optional, rvdeclared,
                           nullBehavior, undefinedBehavior):
     # f - file to write to
     # i - int or None - Indicates the source jsval.  If i is an int, the source
     #     jsval is argv[i]; otherwise it is *vp.  But if Python i >= C++ argc,
     #     which can only happen if optional is True, the argument is missing;
     #     use JSVAL_NULL as the source jsval instead.
     # name - str - name of the native C++ variable to create.
     # type - xpidl.{Interface,Native,Builtin} - IDL type of argument
@@ -227,18 +227,16 @@ def writeArgumentUnboxing(f, i, name, ty
             f.write("    xpc_qsSelfRef %sref;\n" % name)
             f.write("    rv = xpc_qsUnwrapArg<%s>("
                     "cx, %s, &%s, &%sref.ptr, %s);\n"
                     % (type.name, argVal, name, name, argPtr))
             f.write("    if (NS_FAILED(rv)) {\n")
             if isSetter:
                 f.write("        xpc_qsThrowBadSetterValue("
                         "cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);\n")
-            elif haveCcx:
-                f.write("        xpc_qsThrowBadArgWithCcx(ccx, rv, %d);\n" % i)
             else:
                 f.write("        xpc_qsThrowBadArgWithDetails(cx, rv, %d, %s, %s);\n" % (i, "\"\"", "\"\""))
             f.write("        return JS_FALSE;\n"
                     "    }\n")
             return True
 
     warn("Unable to unbox argument of type %s (native type %s)" % (type.name, typeName))
     if i is None:
@@ -385,22 +383,16 @@ def writeResultConv(f, type, interfaceRe
         return
     # else fall through; this type isn't supported yet
 
     warn("Unable to convert result of type %s" % type.name)
     f.write("    !; // TODO - Convert `result` to jsval, store in `%s`.\n"
             % jsvalRef)
     f.write("    return xpc_qsThrow(cx, NS_ERROR_UNEXPECTED); // FIXME\n")
 
-def anyParamRequiresCcx(member):
-    return False
-
-def memberNeedsCcx(member):
-    return member.kind == 'method' and anyParamRequiresCcx(member)
-
 def validateParam(member, param):
     def pfail(msg):
         raise UserError(
             member.iface.name + '.' + member.name + ": "
             "parameter " + param.name + ": " + msg)
 
     if param.iid_is is not None:
         pfail("iid_is parameters are not supported.")
@@ -517,25 +509,17 @@ def writeStub(f, customMethodCalls, memb
         f.write("    jsval *vp = vp_.address();\n")
 
     # For methods, compute "this".
     if isMethod:
         f.write("    JSObject *obj = JS_THIS_OBJECT(cx, vp);\n"
                 "    if (!obj)\n"
                 "        return JS_FALSE;\n")
 
-    # Create ccx if needed.
-    haveCcx = memberNeedsCcx(member)
-    if haveCcx:
-        f.write("    XPCCallContext ccx(JS_CALLER, cx, obj, "
-                "JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));\n")
-        if isInterfaceType(member.realtype):
-            f.write("    XPCLazyCallContext lccx(ccx);\n")
-
-    selfname = writeThisUnwrapping(f, member, isMethod, isGetter, customMethodCall, haveCcx)
+    selfname = writeThisUnwrapping(f, member, isMethod, isGetter, customMethodCall)
 
     rvdeclared = False
     if isMethod:
         inArgs = argumentsLength(member)
         # If there are any required arguments, check argc.
         requiredArgs = inArgs
         while requiredArgs and member.params[requiredArgs-1].optional:
             requiredArgs -= 1
@@ -555,26 +539,25 @@ def writeStub(f, customMethodCalls, memb
                 validateParam(member, param)
                 realtype = param.realtype
             else:
                 realtype = xpidl.Forward(name=customMethodCall[argTypeKey],
                                          location='', doccomments='')
             # Emit code to convert this argument from jsval.
             rvdeclared = writeArgumentUnboxing(
                 f, i, argName, realtype,
-                haveCcx=haveCcx,
                 optional=param.optional,
                 rvdeclared=rvdeclared,
                 nullBehavior=param.null,
                 undefinedBehavior=param.undefined)
         if inArgs < len(member.params):
             f.write("    nsWrapperCache *cache;\n")
     elif isSetter:
         rvdeclared = writeArgumentUnboxing(f, None, 'arg0', member.realtype,
-                                           haveCcx=False, optional=False,
+                                           optional=False,
                                            rvdeclared=rvdeclared,
                                            nullBehavior=member.null,
                                            undefinedBehavior=member.undefined)
 
     canFail = not isNotxpcom and (customMethodCall is None or customMethodCall.get('canFail', True))
     if canFail and not rvdeclared:
         f.write("    nsresult rv;\n")
         rvdeclared = True
@@ -638,17 +621,17 @@ def writeStub(f, customMethodCalls, memb
             f.write("    NS_ASSERTION(%s && "
                     "xpc_qsSameResult(debug_result, result),\n"
                     "                 \"Got the wrong answer from the custom "
                     "method call!\");\n" % checkSuccess)
             f.write("#endif\n")
 
     if canFail:
         # Check for errors.
-        writeCheckForFailure(f, isMethod, isGetter, haveCcx)
+        writeCheckForFailure(f, isMethod, isGetter)
 
     # Convert the return value.
     if isMethod or isGetter:
         writeResultWrapping(f, member, 'vp', '*vp')
     else:
         f.write("    return JS_TRUE;\n")
 
     # Epilog.
--- a/js/xpconnect/src/dombindingsgen.py
+++ b/js/xpconnect/src/dombindingsgen.py
@@ -568,26 +568,26 @@ listTemplateFooter = (
 "${nativeClass}*\n"
 "${name}::getNative(JSObject *obj)\n"
 "{\n"
 "    return ${name}Wrapper::getListObject(obj);\n"
 "}\n"
 "\n")
 
 def writeBindingStub(f, classname, member, stubName, isSetter=False):
-    def writeThisUnwrapping(f, member, isMethod, isGetter, customMethodCall, haveCcx):
+    def writeThisUnwrapping(f, member, isMethod, isGetter, customMethodCall):
         if isMethod:
             f.write("    JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));\n"
                     "    if (!%sWrapper::instanceIsListObject(cx, obj, callee))\n"
                     "        return false;\n" % classname)
         else:
             f.write("    if (!%sWrapper::instanceIsListObject(cx, obj, NULL))\n"
                     "        return false;\n" % classname)
         return "%sWrapper::getListObject(obj)" % classname
-    def writeCheckForFailure(f, isMethod, isGeter, haveCcx):
+    def writeCheckForFailure(f, isMethod, isGeter):
         f.write("    if (NS_FAILED(rv))\n"
                 "        return xpc_qsThrowMethodFailedWithDetails(cx, rv, \"%s\", \"%s\");\n" % (classname, member.name))
     def writeResultWrapping(f, member, jsvalPtr, jsvalRef):
         if member.kind == 'method' and member.notxpcom and len(member.params) > 0 and member.params[len(member.params) - 1].paramtype == 'out':
             assert member.params[len(member.params) - 1].realtype.kind == 'native' and member.params[len(member.params) - 1].realtype.nativename == 'nsWrapperCache'
             template = "    return Wrap(cx, obj, result, cache, ${jsvalPtr});\n"
         else:
             template = "    return Wrap(cx, obj, result, ${jsvalPtr});\n"
--- a/js/xpconnect/src/qsgen.py
+++ b/js/xpconnect/src/qsgen.py
@@ -485,17 +485,17 @@ argumentUnboxingTemplates = {
     }
 
 # From JSData2Native.
 #
 # Omitted optional arguments are treated as though the caller had passed JS
 # `null`; this behavior is from XPCWrappedNative::CallMethod. The 'jsval' type,
 # however, defaults to 'undefined'.
 #
-def writeArgumentUnboxing(f, i, name, type, haveCcx, optional, rvdeclared,
+def writeArgumentUnboxing(f, i, name, type, optional, rvdeclared,
                           nullBehavior, undefinedBehavior):
     # f - file to write to
     # i - int or None - Indicates the source jsval.  If i is an int, the source
     #     jsval is argv[i]; otherwise it is *vp.  But if Python i >= C++ argc,
     #     which can only happen if optional is True, the argument is missing;
     #     use JSVAL_NULL as the source jsval instead.
     # name - str - name of the native C++ variable to create.
     # type - xpidl.{Interface,Native,Builtin} - IDL type of argument
@@ -556,18 +556,16 @@ def writeArgumentUnboxing(f, i, name, ty
             f.write("    xpc_qsSelfRef %sref;\n" % name)
             f.write("    rv = xpc_qsUnwrapArg<%s>("
                     "cx, %s, &%s, &%sref.ptr, %s);\n"
                     % (type.name, argVal, name, name, argPtr))
             f.write("    if (NS_FAILED(rv)) {\n")
             if isSetter:
                 f.write("        xpc_qsThrowBadSetterValue("
                         "cx, rv, JSVAL_TO_OBJECT(*tvr.jsval_addr()), id);\n")
-            elif haveCcx:
-                f.write("        xpc_qsThrowBadArgWithCcx(ccx, rv, %d);\n" % i)
             else:
                 f.write("        xpc_qsThrowBadArg(cx, rv, vp, %d);\n" % i)
             f.write("        return JS_FALSE;\n"
                     "    }\n")
             return True
 
     warn("Unable to unbox argument of type %s (native type %s)" % (type.name, typeName))
     if i is None:
@@ -718,24 +716,18 @@ def writeResultConv(f, type, jsvalPtr, j
                     % (jsvalPtr, jsvalPtr, type.name, type.name, jsvalPtr))
             return
 
     warn("Unable to convert result of type %s" % type.name)
     f.write("    !; // TODO - Convert `result` to jsval, store in `%s`.\n"
             % jsvalRef)
     f.write("    return xpc_qsThrow(cx, NS_ERROR_UNEXPECTED); // FIXME\n")
 
-def anyParamRequiresCcx(member):
-    return False
-
-def memberNeedsCcx(member):
-    return member.kind == 'method' and anyParamRequiresCcx(member)
-
 def memberNeedsCallee(member):
-    return memberNeedsCcx(member) or isInterfaceType(member.realtype)
+    return isInterfaceType(member.realtype)
 
 def validateParam(member, param):
     def pfail(msg):
         raise UserError(
             member.iface.name + '.' + member.name + ": "
             "parameter " + param.name + ": " + msg)
 
     if param.iid_is is not None:
@@ -846,71 +838,50 @@ def writeQuickStub(f, customMethodCalls,
         f.write("    jsval *vp = vp_.address();\n")
 
     # For methods, compute "this".
     if isMethod:
         f.write("    JSObject *obj = JS_THIS_OBJECT(cx, vp);\n"
                 "    if (!obj)\n"
                 "        return JS_FALSE;\n")
 
-    # Create ccx if needed.
-    haveCcx = memberNeedsCcx(member)
-    if haveCcx and not unwrapThisFailureFatal:
-        raise UserError(member.iface.name + '.' + member.name + ": "
-                        "Unwrapping this failure must be fatal when we have a ccx")
-
-    if haveCcx:
-        f.write("    XPCCallContext ccx(JS_CALLER, cx, obj, "
-                "JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));\n")
-        if isInterfaceType(member.realtype):
-            f.write("    XPCLazyCallContext lccx(ccx);\n")
-
     # Get the 'self' pointer.
     if customMethodCall is None or not 'thisType' in customMethodCall:
         f.write("    %s *self;\n" % member.iface.name)
     else:
         f.write("    %s *self;\n" % customMethodCall['thisType'])
     f.write("    xpc_qsSelfRef selfref;\n")
-    # Don't use FromCcx for getters or setters; the way we construct the ccx in
-    # a getter/setter causes it to find the wrong wrapper in some cases.
-    if haveCcx:
-        # Undocumented, but the interpreter puts 'this' at argv[-1],
-        # which is vp[1]; and it's ok to overwrite it.
-        f.write("    if (!xpc_qsUnwrapThisFromCcx(ccx, &self, &selfref.ptr, "
-                "&vp[1]))\n")
-        f.write("        return JS_FALSE;\n")
+    if isGetter:
+        pthisval = 'vp'
+    elif isSetter:
+        f.write("    JS::AutoValueRooter tvr(cx);\n")
+        pthisval = 'tvr.jsval_addr()'
     else:
-        if isGetter:
-            pthisval = 'vp'
-        elif isSetter:
-            f.write("    JS::AutoValueRooter tvr(cx);\n")
-            pthisval = 'tvr.jsval_addr()'
-        else:
-            pthisval = '&vp[1]' # as above, ok to overwrite vp[1]
+        pthisval = '&vp[1]' # as above, ok to overwrite vp[1]
+
+    if unwrapThisFailureFatal:
+        unwrapFatalArg = "true"
+    else:
+        unwrapFatalArg = "false"
 
-        if unwrapThisFailureFatal:
-            unwrapFatalArg = "true"
-        else:
-            unwrapFatalArg = "false"
+    if not isSetter and isInterfaceType(member.realtype):
+        f.write("    XPCLazyCallContext lccx(JS_CALLER, cx, obj);\n")
+        f.write("    if (!xpc_qsUnwrapThis(cx, obj, &self, "
+                "&selfref.ptr, %s, &lccx, %s))\n" % (pthisval, unwrapFatalArg))
+    else:
+        f.write("    if (!xpc_qsUnwrapThis(cx, obj, &self, "
+                "&selfref.ptr, %s, nullptr, %s))\n" % (pthisval, unwrapFatalArg))
+    f.write("        return JS_FALSE;\n")
 
-        if not isSetter and isInterfaceType(member.realtype):
-            f.write("    XPCLazyCallContext lccx(JS_CALLER, cx, obj);\n")
-            f.write("    if (!xpc_qsUnwrapThis(cx, obj, &self, "
-                    "&selfref.ptr, %s, &lccx, %s))\n" % (pthisval, unwrapFatalArg))
-        else:
-            f.write("    if (!xpc_qsUnwrapThis(cx, obj, &self, "
-                    "&selfref.ptr, %s, nullptr, %s))\n" % (pthisval, unwrapFatalArg))
-        f.write("        return JS_FALSE;\n")
-
-        if not unwrapThisFailureFatal:
-            f.write("      if (!self) {\n")
-            if (isGetter):
-                f.write("        *vp = JSVAL_NULL;\n")
-            f.write("        return JS_TRUE;\n")
-            f.write("    }\n");
+    if not unwrapThisFailureFatal:
+        f.write("      if (!self) {\n")
+        if (isGetter):
+            f.write("        *vp = JSVAL_NULL;\n")
+        f.write("        return JS_TRUE;\n")
+        f.write("    }\n");
 
     if isMethod:
         # If there are any required arguments, check argc.
         requiredArgs = len(member.params)
         while requiredArgs and member.params[requiredArgs-1].optional:
             requiredArgs -= 1
         if requiredArgs:
             f.write("    if (argc < %d)\n" % requiredArgs)
@@ -929,24 +900,23 @@ def writeQuickStub(f, customMethodCalls,
                 validateParam(member, param)
                 realtype = param.realtype
             else:
                 realtype = xpidl.Forward(name=customMethodCall[argTypeKey],
                                          location='', doccomments='')
             # Emit code to convert this argument from jsval.
             rvdeclared = writeArgumentUnboxing(
                 f, i, argName, realtype,
-                haveCcx=haveCcx,
                 optional=param.optional,
                 rvdeclared=rvdeclared,
                 nullBehavior=param.null,
                 undefinedBehavior=param.undefined)
     elif isSetter:
         rvdeclared = writeArgumentUnboxing(f, None, 'arg0', member.realtype,
-                                           haveCcx=False, optional=False,
+                                           optional=False,
                                            rvdeclared=rvdeclared,
                                            nullBehavior=member.null,
                                            undefinedBehavior=member.undefined)
 
     canFail = customMethodCall is None or customMethodCall.get('canFail', True)
     if canFail and not rvdeclared:
         f.write("    nsresult rv;\n")
         rvdeclared = True
@@ -1009,22 +979,18 @@ def writeQuickStub(f, customMethodCalls,
                     "                 \"Got the wrong answer from the custom "
                     "method call!\");\n" % checkSuccess)
             f.write("#endif\n")
 
     if canFail:
         # Check for errors.
         f.write("    if (NS_FAILED(rv))\n")
         if isMethod:
-            if haveCcx:
-                f.write("        return xpc_qsThrowMethodFailedWithCcx("
-                        "ccx, rv);\n")
-            else:
-                f.write("        return xpc_qsThrowMethodFailed("
-                        "cx, rv, vp);\n")
+            f.write("        return xpc_qsThrowMethodFailed("
+                    "cx, rv, vp);\n")
         else:
             if isGetter:
                 thisval = '*vp'
             else:
                 thisval = '*tvr.jsval_addr()'
             f.write("        return xpc_qsThrowGetterSetterFailed(cx, rv, " +
                     "JSVAL_TO_OBJECT(%s), id);\n" % thisval)