def writeResultDecl(f, member, varname): type = member.realtype if isVoidType(type): return # nothing to declare t = xpidl.unaliasType(type) if t.kind == 'builtin': if not t.nativename.endswith('*'): if type.kind == 'typedef': typeName = type.name # use it else: typeName = t.nativename f.write(" %s %s;\n" % (typeName, varname)) return elif t.kind == 'native': name = xpidl.getBuiltinOrNativeTypeName(t) if name in ('[domstring]', '[astring]'): f.write(" nsString %s;\n" % varname) return elif name == '[jsval]': return # nothing to declare; see special case in outParamForm elif t.kind in ('interface', 'forward'): if member.kind == 'method' and member.notxpcom: f.write(" %s *%s;\n" % (type.name, varname)) else: f.write(" nsCOMPtr<%s> %s;\n" % (type.name, varname)) return warn("Unable to declare result of type %s" % type.name) f.write(" !; // TODO - Declare out parameter `%s`.\n" % varname)
def writeResultConv(f, type, interfaceResultTemplate, jsvalPtr, jsvalRef): """ Emit code to convert the C++ variable `result` to a jsval. The emitted code contains a return statement; it returns JS_TRUE on success, JS_FALSE on error. """ # From NativeData2JS. typeName = xpidl.getBuiltinOrNativeTypeName(type) if typeName is not None: template = resultConvTemplates.get(typeName) elif isInterfaceType(type): if isVariantType(type): template = " return xpc_qsVariantToJsval(lccx, result, ${jsvalPtr});\n" else: template = (" if (!result) {\n" " *${jsvalPtr} = JSVAL_NULL;\n" " return JS_TRUE;\n" " }\n") template += interfaceResultTemplate if template is not None: values = {'jsvalRef': jsvalRef, 'jsvalPtr': jsvalPtr, 'typeName': type.name} f.write(string.Template(template).substitute(values)) 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 writeResultConv(f, type, interfaceResultTemplate, jsvalPtr, jsvalRef): """ Emit code to convert the C++ variable `result` to a jsval. The emitted code contains a return statement; it returns JS_TRUE on success, JS_FALSE on error. """ # From NativeData2JS. typeName = xpidl.getBuiltinOrNativeTypeName(type) if typeName is not None: template = resultConvTemplates.get(typeName) elif isInterfaceType(type): if isVariantType(type): template = " return xpc_qsVariantToJsval(lccx, result, ${jsvalPtr});\n" else: template = (" if (!result) {\n" " *${jsvalPtr} = JSVAL_NULL;\n" " return JS_TRUE;\n" " }\n") template += interfaceResultTemplate if template is not None: values = { 'jsvalRef': jsvalRef, 'jsvalPtr': jsvalPtr, 'typeName': type.name } f.write(string.Template(template).substitute(values)) 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 writeResultDecl(f, member, varname): type = member.realtype if isVoidType(type): return # nothing to declare t = xpidl.unaliasType(type) if t.kind == "builtin": if not t.nativename.endswith("*"): if type.kind == "typedef": typeName = type.name # use it else: typeName = t.nativename f.write(" %s %s;\n" % (typeName, varname)) return elif t.kind == "native": name = xpidl.getBuiltinOrNativeTypeName(t) if name in ("[domstring]", "[astring]"): f.write(" nsString %s;\n" % varname) return elif name == "[jsval]": return # nothing to declare; see special case in outParamForm elif t.kind in ("interface", "forward"): if member.kind == "method" and member.notxpcom: f.write(" %s *%s;\n" % (type.name, varname)) else: f.write(" nsCOMPtr<%s> %s;\n" % (type.name, varname)) return warn("Unable to declare result of type %s" % type.name) f.write(" !; // TODO - Declare out parameter `%s`.\n" % varname)
def writeArgumentUnboxing(f, i, name, type, haveCcx, 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 # optional - bool - True if the parameter is optional. # rvdeclared - bool - False if no |nsresult rv| has been declared earlier. typeName = xpidl.getBuiltinOrNativeTypeName(type) isSetter = (i is None) if isSetter: argPtr = "vp" argVal = "*vp" elif optional: if typeName == "[jsval]": val = "JSVAL_VOID" else: val = "JSVAL_NULL" argVal = "(%d < argc ? argv[%d] : %s)" % (i, i, val) argPtr = "(%d < argc ? &argv[%d] : NULL)" % (i, i) else: argVal = "argv[%d]" % i argPtr = "&" + argVal params = { 'name': name, 'argVal': argVal, 'argPtr': argPtr, 'nullBehavior': nullBehavior or 'DefaultNullBehavior', 'undefinedBehavior': undefinedBehavior or 'DefaultUndefinedBehavior' } if typeName is not None: template = argumentUnboxingTemplates.get(typeName) if template is not None: f.write(string.Template(template).substitute(params)) return rvdeclared # else fall through; the type isn't supported yet. elif isInterfaceType(type): if type.name == 'nsIVariant': # Totally custom. assert haveCcx template = ( " nsCOMPtr<nsIVariant> ${name}(already_AddRefed<nsIVariant>(" "XPCVariant::newVariant(ccx, ${argVal})));\n" " if (!${name}) {\n" " xpc_qsThrowBadArgWithCcx(ccx, NS_ERROR_XPC_BAD_CONVERT_JS, %d);\n" " return JS_FALSE;\n" " }\n") % i f.write(string.Template(template).substitute(params)) return rvdeclared elif type.name == 'nsIAtom': # Should have special atomizing behavior. Fall through. pass else: if not rvdeclared: f.write(" nsresult rv;\n"); f.write(" %s *%s;\n" % (type.name, name)) 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: src = '*vp' else: src = 'argv[%d]' % i f.write(" !; // TODO - Unbox argument %s = %s\n" % (name, src)) return rvdeclared
def writeArgumentUnboxing(f, i, name, type, haveCcx, 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 # optional - bool - True if the parameter is optional. # rvdeclared - bool - False if no |nsresult rv| has been declared earlier. typeName = xpidl.getBuiltinOrNativeTypeName(type) isSetter = (i is None) if isSetter: argPtr = "vp" argVal = "*vp" elif optional: if typeName == "[jsval]": val = "JSVAL_VOID" else: val = "JSVAL_NULL" argVal = "(%d < argc ? argv[%d] : %s)" % (i, i, val) argPtr = "(%d < argc ? &argv[%d] : NULL)" % (i, i) else: argVal = "argv[%d]" % i argPtr = "&" + argVal params = { 'name': name, 'argVal': argVal, 'argPtr': argPtr, 'nullBehavior': nullBehavior or 'DefaultNullBehavior', 'undefinedBehavior': undefinedBehavior or 'DefaultUndefinedBehavior' } if typeName is not None: template = argumentUnboxingTemplates.get(typeName) if template is not None: f.write(string.Template(template).substitute(params)) return rvdeclared # else fall through; the type isn't supported yet. elif isInterfaceType(type): if type.name == 'nsIVariant': # Totally custom. assert haveCcx template = ( " nsCOMPtr<nsIVariant> ${name}(already_AddRefed<nsIVariant>(" "XPCVariant::newVariant(ccx, ${argVal})));\n" " if (!${name}) {\n" " xpc_qsThrowBadArgWithCcx(ccx, NS_ERROR_XPC_BAD_CONVERT_JS, %d);\n" " return JS_FALSE;\n" " }\n") % i f.write(string.Template(template).substitute(params)) return rvdeclared elif type.name == 'nsIAtom': # Should have special atomizing behavior. Fall through. pass else: if not rvdeclared: f.write(" nsresult rv;\n") f.write(" %s *%s;\n" % (type.name, name)) 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: src = '*vp' else: src = 'argv[%d]' % i f.write(" !; // TODO - Unbox argument %s = %s\n" % (name, src)) return rvdeclared