示例#1
0
    def generateCallbackFunction(self, ifaceName, name, exception, ret, argInfo):
        global retv # Workaround for Python 1.x
        retv = ret
        rtype = ternary(ret == None, lambda: None, lambda: GetTypeInformation(retv))
        global rtypev
        rtypev = rtype
        rname = ternary(rtype == None, lambda: "void", lambda: rtypev.cppReturnSignatureType)
        argsig = ''
        for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo):
            argt = GetTypeInformation(argType)
            if argsig != '':
                argsig = argsig + ', '
            global argtv
            argtv = argt
            argsig = '%s%s arg%d' % (argsig, ternary(argOut, lambda: argtv.cppOutSignatureType, lambda: argtv.cppInSignatureType), i)

        self.cxx.out('%s %s(%s)' % (rname, name, argsig))
        self.cxx.out('  throw(std::exception&)')
        self.cxx.out('{')
        self.cxx.inc_indent()

        self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();')
        self.cxx.out('std::vector<iface::CGRS::GenericValue*> inValSeq;')
        self.cxx.out('scoped_destroy<std::vector<iface::CGRS::GenericValue*> > inValSeqReleaser(inValSeq, ' +\
                     'new container_destructor<std::vector<iface::CGRS::GenericValue*> >(new objref_destructor<iface::CGRS::GenericValue>()));')
        for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo):
            if argIn:
                self.cxx.out('{')
                self.cxx.inc_indent()
                argt = GetTypeInformation(argType)
                # Note: Objects can actually have one of two incompatible interfaces - callback or normal.
                self.cxx.out('iface::%s* genval;' % argt.genericIface)
                self.cxx.out(argt.convertNativeToGeneric('%sarg%d' % (argt.deref(argOut), i), 'genval'))
                self.cxx.out('inValSeq.push_back(genval);')
                self.cxx.dec_indent()
                self.cxx.out('}')
        self.cxx.out('std::vector<iface::CGRS::GenericValue*> outValSeq;')
        self.cxx.out('scoped_destroy<std::vector<iface::CGRS::GenericValue*> > outValSeqReleaser(outValSeq, new container_destructor<std::vector<iface::CGRS::GenericValue*> >(new objref_destructor<iface::CGRS::GenericValue>()));')
        self.cxx.out('bool wasException = false;')
        self.cxx.out('ObjRef<iface::CGRS::GenericValue> genret = mValue->invokeOnInterface("%s", "%s", inValSeq, outValSeq, &wasException);' % (ifaceName, name))
        self.cxx.out('if (wasException) throw %s();' % exception)

        self.cxx.out('std::vector<iface::CGRS::GenericValue*>::iterator outVali = outValSeq.begin();')
        for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo):
            if argOut:
                argt = GetTypeInformation(argType)
                self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(genout%d, (*outVali), %s);' % (i, argt.genericIface))
                self.cxx.out(argt.convertGenericToNative('genout%d' % i, '%sarg%d' % (argt.deref(1), i)))
                self.cxx.out('outVali++;')
        if rtype != None and not isinstance(rtype, VoidType):
            self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(genreti, genret, %s);' % rtype.genericIface)
            self.cxx.out(rtype.makeStorage('retval'))
            self.cxx.out(rtype.convertGenericToNative('genreti', 'retval'))
            self.cxx.out(rtype.returnStorage('retval'))
        self.cxx.dec_indent()
        self.cxx.out('}')
示例#2
0
    def generateCallbackFunction(self, ifaceName, name, exception, ret, argInfo):
        global retv # Workaround for Python 1.x
        retv = ret 
        rtype = ternary(ret == None, lambda: None, lambda: GetTypeInformation(retv))
        global rtypev
        rtypev = rtype
        rname = ternary(rtype == None, lambda: "void", lambda: rtypev.cppReturnSignatureType)
        argsig = ''
        for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo):
            argt = GetTypeInformation(argType)
            if argsig != '':
                argsig = argsig + ', '
            global argtv
            argtv = argt
            argsig = '%s%s arg%d' % (argsig, ternary(argOut, lambda: argtv.cppOutSignatureType, lambda: argtv.cppInSignatureType), i)

        self.cxx.out('%s %s(%s)' % (rname, name, argsig))
        self.cxx.out('  throw(std::exception&)')
        self.cxx.out('{')
        self.cxx.inc_indent()

        self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();')
        self.cxx.out('std::vector<iface::CGRS::GenericValue*> inValSeq;')
        self.cxx.out('scoped_destroy<std::vector<iface::CGRS::GenericValue*> > inValSeqReleaser(inValSeq, ' +\
                     'new container_destructor<std::vector<iface::CGRS::GenericValue*> >(new objref_destructor<iface::CGRS::GenericValue>()));')
        for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo):
            if argIn:
                self.cxx.out('{')
                self.cxx.inc_indent()
                argt = GetTypeInformation(argType)
                # Note: Objects can actually have one of two incompatible interfaces - callback or normal.
                self.cxx.out('iface::%s* genval;' % argt.genericIface)
                self.cxx.out(argt.convertNativeToGeneric('%sarg%d' % (argt.deref(argOut), i), 'genval'))
                self.cxx.out('inValSeq.push_back(genval);')
                self.cxx.dec_indent()
                self.cxx.out('}')
        self.cxx.out('std::vector<iface::CGRS::GenericValue*> outValSeq;')
        self.cxx.out('scoped_destroy<std::vector<iface::CGRS::GenericValue*> > outValSeqReleaser(outValSeq, new container_destructor<std::vector<iface::CGRS::GenericValue*> >(new objref_destructor<iface::CGRS::GenericValue>()));')
        self.cxx.out('bool wasException = false;')
        self.cxx.out('ObjRef<iface::CGRS::GenericValue> genret = mValue->invokeOnInterface("%s", "%s", inValSeq, outValSeq, &wasException);' % (ifaceName, name))
        self.cxx.out('if (wasException) throw %s();' % exception)

        self.cxx.out('std::vector<iface::CGRS::GenericValue*>::iterator outVali = outValSeq.begin();')
        for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo):
            if argOut:
                argt = GetTypeInformation(argType)
                self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(genout%d, (*outVali), %s);' % (i, argt.genericIface))
                self.cxx.out(argt.convertGenericToNative('genout%d' % i, '%sarg%d' % (argt.deref(1), i)))
                self.cxx.out('outVali++;')
        if rtype != None and not isinstance(rtype, VoidType):
            self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(genreti, genret, %s);' % rtype.genericIface)
            self.cxx.out(rtype.makeStorage('retval'))
            self.cxx.out(rtype.convertGenericToNative('genreti', 'retval'))
            self.cxx.out(rtype.returnStorage('retval'))
        self.cxx.dec_indent()
        self.cxx.out('}')
示例#3
0
    def visitAttribute(self, at):
        for n in at.declarators():
            self.supportedAttributes.append(n.simplename)
            self.generateMethod('get%s' % n.simplename, n.simplename, at.attrType(), [])
            if not at.readonly():
                self.generateMethod('set%s' % n.simplename, n.simplename, None, [("value", at.attrType(), 1, 0)])

            self.cxx.out('class attr%s' % n.simplename)
            self.cxx.out('  : public iface::CGRS::GenericAttribute')
            self.cxx.out('{')
            self.cxx.out('public:')
            self.cxx.inc_indent()
            self.cxx.out('CDA_IMPL_REFCOUNT;')
            self.cxx.out('CDA_IMPL_ID;')
            self.cxx.out('CDA_IMPL_QI1(CGRS::GenericAttribute);')
            self.cxx.out('bool isReadonly() throw() { return %s; }' % ternary(at.readonly(), lambda: "true", lambda: "false"))
            self.cxx.out('std::string name() throw() { return "%s"; }' % n.simplename)
            self.cxx.out('already_AddRefd<iface::CGRS::GenericType> type() throw()')
            self.cxx.out('{')
            self.cxx.inc_indent()
            self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();')
            self.cxx.out(GetTypeInformation(at.attrType()).fetchType())
            self.cxx.dec_indent()
            self.cxx.out('}')
            self.cxx.out('already_AddRefd<iface::CGRS::GenericMethod> getter() throw() { return new methget%s(); }' % n.simplename)
            if at.readonly():
                self.cxx.out('already_AddRefd<iface::CGRS::GenericMethod> setter() throw(std::exception&) { throw iface::CGRS::CGRSError(); }')
            else:
                self.cxx.out('already_AddRefd<iface::CGRS::GenericMethod> setter() throw() { return new methset%s(); }' % n.simplename)
            self.cxx.dec_indent()
            self.cxx.out('};')
示例#4
0
    def visitAttribute(self, at):
        for n in at.declarators():
            self.supportedAttributes.append(n.simplename)
            self.generateMethod('get%s' % n.simplename, n.simplename, at.attrType(), [])
            if not at.readonly():
                self.generateMethod('set%s' % n.simplename, n.simplename, None, [("value", at.attrType(), 1, 0)])

            self.cxx.out('class attr%s' % n.simplename)
            self.cxx.out('  : public iface::CGRS::GenericAttribute')
            self.cxx.out('{')
            self.cxx.out('public:')
            self.cxx.inc_indent()
            self.cxx.out('CDA_IMPL_REFCOUNT;')
            self.cxx.out('CDA_IMPL_ID;')
            self.cxx.out('CDA_IMPL_QI1(CGRS::GenericAttribute);')
            self.cxx.out('bool isReadonly() throw() { return %s; }' % ternary(at.readonly(), lambda: "true", lambda: "false"))
            self.cxx.out('std::string name() throw() { return "%s"; }' % n.simplename)
            self.cxx.out('already_AddRefd<iface::CGRS::GenericType> type() throw()')
            self.cxx.out('{')
            self.cxx.inc_indent()
            self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();')
            self.cxx.out(GetTypeInformation(at.attrType()).fetchType())
            self.cxx.dec_indent()
            self.cxx.out('}')
            self.cxx.out('already_AddRefd<iface::CGRS::GenericMethod> getter() throw() { return new methget%s(); }' % n.simplename)
            if at.readonly():
                self.cxx.out('already_AddRefd<iface::CGRS::GenericMethod> setter() throw(std::exception&) { throw iface::CGRS::CGRSError(); }')
            else:
                self.cxx.out('already_AddRefd<iface::CGRS::GenericMethod> setter() throw() { return new methset%s(); }' % n.simplename)
            self.cxx.dec_indent()
            self.cxx.out('};')
示例#5
0
 def generateCallbackFunctions(self, node, seen):
     if (seen.has_key(node.simplecxxscoped)): return
     seen[node.simplecxxscoped] = 1
     for d in node.inherits():
         self.generateCallbackFunctions(d, seen)
     blacklist = []
     if node.simplecxxscoped == "iface::XPCOM::IObject":
         self.cxx.out('CDA_IMPL_REFCOUNT;')
         self.cxx.out('CDA_IMPL_ID;')
         self.cxx.out(
             'void* query_interface(const std::string& aTarget) throw()')
         self.cxx.out('{')
         self.cxx.inc_indent()
         # Firstly check with the target...
         self.cxx.out('std::vector<iface::CGRS::GenericValue*> valseq;')
         self.cxx.out('bool wasExcept;')
         self.cxx.out('ObjRef<iface::CGRS::GenericValue> qiRet = ')
         self.cxx.out(
             '  mValue->invokeOnInterface("XPCOM::IObject", "query_interface", valseq, valseq, &wasExcept);'
         )
         self.cxx.out('if (wasExcept) return NULL;')
         self.cxx.out(
             'ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();'
         )
         self.cxx.out(
             'ObjRef<iface::CGRS::GenericValue> vv = cgs->makeVoid();\n')
         self.cxx.out('if (!CDA_objcmp(vv, qiRet)) return NULL;')
         self.cxx.out(
             'ObjRef<iface::CGRS::GenericInterface> gi = cgs->getInterfaceByName(aTarget);\n'
         )
         self.cxx.out('if (gi == NULL) return NULL;')
         self.cxx.out(
             'return static_cast<CDA_GenericInterfaceBase*>(gi.getPointer())->makeCallbackProxy(mValue);'
         )
         self.cxx.dec_indent()
         self.cxx.out('}')
         blacklist = ['add_ref', 'release_ref', 'query_interface', 'objid']
     for d in node.callables():
         if isinstance(d, idlast.Operation):
             if d.simplename in blacklist: continue
             global dv
             dv = d
             exception = ternary(d.raises() == [], lambda: "std::exception",
                                 lambda: dv.raises()[0].simplecxxscoped)
             self.generateCallbackFunction(\
                 node.corbacxxscoped, d.simplename, exception, d.returnType(),\
                 map(lambda x: (x.paramType(), x.is_in(), x.is_out()),\
                         d.parameters()))
         elif isinstance(d, idlast.Attribute):
             for a in d.declarators():
                 if a.simplename in blacklist: continue
                 self.generateCallbackFunction(\
                     node.corbacxxscoped, a.simplename, 'std::exception', d.attrType(), [])
                 if not d.readonly():
                     self.generateCallbackFunction(\
                         node.corbacxxscoped, a.simplename, 'std::exception', None, [(d.attrType(), 1, 0)])
示例#6
0
 def generateCallbackFunctions(self, node, seen):
     if (seen.has_key(node.simplecxxscoped)): return
     seen[node.simplecxxscoped] = 1
     for d in node.inherits():
         self.generateCallbackFunctions(d, seen)
     blacklist = []
     if node.simplecxxscoped == "iface::XPCOM::IObject":
         self.cxx.out('CDA_IMPL_REFCOUNT;')
         self.cxx.out('CDA_IMPL_ID;')
         self.cxx.out('void* query_interface(const std::string& aTarget) throw()')
         self.cxx.out('{')
         self.cxx.inc_indent()
         # Firstly check with the target...
         self.cxx.out('std::vector<iface::CGRS::GenericValue*> valseq;')
         self.cxx.out('bool wasExcept;')
         self.cxx.out('ObjRef<iface::CGRS::GenericValue> qiRet = ')
         self.cxx.out('  mValue->invokeOnInterface("XPCOM::IObject", "query_interface", valseq, valseq, &wasExcept);')
         self.cxx.out('if (wasExcept) return NULL;')
         self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();')
         self.cxx.out('ObjRef<iface::CGRS::GenericValue> vv = cgs->makeVoid();\n')
         self.cxx.out('if (!CDA_objcmp(vv, qiRet)) return NULL;')
         self.cxx.out('ObjRef<iface::CGRS::GenericInterface> gi = cgs->getInterfaceByName(aTarget);\n')
         self.cxx.out('if (gi == NULL) return NULL;')
         self.cxx.out('return static_cast<CDA_GenericInterfaceBase*>(gi.getPointer())->makeCallbackProxy(mValue);')
         self.cxx.dec_indent()
         self.cxx.out('}')
         blacklist = ['add_ref', 'release_ref', 'query_interface', 'objid']
     for d in node.callables():
         if isinstance(d, idlast.Operation):
             if d.simplename in blacklist: continue
             global dv
             dv = d
             exception = ternary(d.raises() == [], lambda: "std::exception", lambda: dv.raises()[0].simplecxxscoped)
             self.generateCallbackFunction(\
                 node.corbacxxscoped, d.simplename, exception, d.returnType(),\
                 map(lambda x: (x.paramType(), x.is_in(), x.is_out()),\
                         d.parameters()))
         elif isinstance(d, idlast.Attribute):
             for a in d.declarators():
                 if a.simplename in blacklist: continue
                 self.generateCallbackFunction(\
                     node.corbacxxscoped, a.simplename, 'std::exception', d.attrType(), [])
                 if not d.readonly():
                     self.generateCallbackFunction(\
                         node.corbacxxscoped, a.simplename, 'std::exception', None, [(d.attrType(), 1, 0)])
示例#7
0
    def generateMethod(self, classname, cxxmethodname, retType, params):
        self.cxx.out('class meth%s' % classname)
        self.cxx.out('  : public iface::CGRS::GenericMethod')
        self.cxx.out('{')
        self.cxx.out('public:')
        self.cxx.inc_indent()

        self.cxx.out('CDA_IMPL_REFCOUNT;')
        self.cxx.out('CDA_IMPL_ID;')
        self.cxx.out('CDA_IMPL_QI1(CGRS::GenericMethod);')
        self.cxx.out('std::vector<iface::CGRS::GenericParameter*> parameters() throw()')
        self.cxx.out('{')
        self.cxx.inc_indent()
        self.cxx.out('std::vector<iface::CGRS::GenericParameter*> params;')

        for (pname, ptype, pIsIn, pIsOut) in params:
            self.cxx.out('params.push_back(new Param%s());' % pname)

        self.cxx.out('return params;')
        self.cxx.dec_indent()
        self.cxx.out('}')

        self.cxx.out('already_AddRefd<iface::CGRS::GenericType> returnType() throw()')
        self.cxx.out('{')
        self.cxx.inc_indent()
        self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();')
        self.cxx.out(GetTypeInformation(retType).fetchType())
        self.cxx.dec_indent()
        self.cxx.out('}')

        self.cxx.out('already_AddRefd<iface::CGRS::GenericValue>')
        self.cxx.out('invoke(iface::CGRS::ObjectValue* aInvokeOn, const std::vector<iface::CGRS::GenericValue*>& aInValues,')
        self.cxx.out('       std::vector<iface::CGRS::GenericValue*>& aOutValues, bool* aWasException)')
        self.cxx.out('  throw(std::exception&)')
        self.cxx.out('{')
        self.cxx.inc_indent()
        self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();')
        self.cxx.out('if (aInvokeOn == NULL) throw iface::CGRS::CGRSError();')
        self.cxx.out('ObjRef<iface::XPCOM::IObject> obj = aInvokeOn->asObject();')
        self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(obji, obj, %s);' % self.iface)
        self.cxx.out('if (obji == NULL) throw iface::CGRS::CGRSError();')

        incnt = 0
        for (pname, ptype, pIsIn, pIsOut) in params:
            if pIsIn:
                incnt = incnt + 1
        self.cxx.out('if (aInValues.size() != %d) throw iface::CGRS::CGRSError();' % incnt)

        inidx = 0
        pidx = 0
        paramstring = ''
        for (pname, ptype, pIsIn, pIsOut) in params:
            ti = GetTypeInformation(ptype)
            self.cxx.out(ti.makeStorage('param%d' % pidx))
            self.cxx.out(ti.makeScopedDestructor('param%d' % pidx))
            if pIsIn:
                self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(inValues%d, (aInValues[%d]), %s);' % (inidx, inidx, ti.genericIface))
                self.cxx.out(ti.convertGenericToNative('inValues%d' % inidx, 'param%d' % pidx))
                inidx = inidx + 1
            if pidx != 0:
                paramstring = paramstring + ', '
            paramstring = paramstring + '%sparam%d' % (ti.ref(pIsOut), pidx)
            pidx = pidx + 1

        rti = GetTypeInformation(retType)
        self.cxx.out(rti.makeStorage('retval'))
        self.cxx.out(rti.makeScopedDestructor('retval'))
        self.cxx.out('*aWasException = false;')
        self.cxx.out('try')
        self.cxx.out('{')
        self.cxx.inc_indent()
        if rti.typename == 'void':
            retAssign = ''
        else:
            retAssign = 'retval = '
        self.cxx.out('%sobji->%s(%s);' % (retAssign, cxxmethodname, paramstring))
        self.cxx.dec_indent()
        self.cxx.out('}')
        self.cxx.out('catch (...)')
        self.cxx.out('{')
        self.cxx.inc_indent()
        self.cxx.out(rti.defaultStorageValue('retval'))
        pidx = 0
        for (pname, ptype, pIsIn, pIsOut) in params:
            if pIsOut:
                self.cxx.out(rti.defaultStorageValue('param%d' % pidx))
            pidx = pidx + 1
        self.cxx.out('*aWasException = true;')
        self.cxx.dec_indent()
        self.cxx.out('}')

        pidx = 0
        for (pname, ptype, pIsIn, pIsOut) in params:
            ti = GetTypeInformation(ptype)
            if pIsOut:
                self.cxx.out('{')
                self.cxx.inc_indent()
                self.cxx.out('iface::CGRS::GenericValue* gval;')
                self.cxx.out(ti.convertNativeToGeneric('param%d' % pidx, 'gval'))
                self.cxx.out('aOutValues.push_back(gval);')
                self.cxx.dec_indent()
                self.cxx.out('}')
            pidx = pidx + 1

        if rti.typename != 'void':
            self.cxx.out('ObjRef<iface::%s> gretval;' % rti.genericIface)
            self.cxx.out(rti.convertNativeToGeneric('retval', 'gretval'))
            self.cxx.out('gretval->add_ref();')
            self.cxx.out('return gretval.getPointer();')
        else:
            self.cxx.out('return cgs->makeVoid();')

        self.cxx.dec_indent()
        self.cxx.out('}')

        self.cxx.dec_indent()
        self.cxx.out('private:')
        self.cxx.inc_indent()

        for (pname, ptype, pIsIn, pIsOut) in params:
            self.cxx.out('class Param%s' % pname)
            self.cxx.out('  : public iface::CGRS::GenericParameter')
            self.cxx.out('{')
            self.cxx.out('public:')
            self.cxx.inc_indent()
            self.cxx.out('CDA_IMPL_ID;')
            self.cxx.out('CDA_IMPL_REFCOUNT;')
            self.cxx.out('CDA_IMPL_QI1(CGRS::GenericParameter);')
            self.cxx.out('bool isIn() throw() { return ' + ternary(pIsIn, lambda: "true", lambda: "false") + "; }")
            self.cxx.out('bool isOut() throw() { return ' + ternary(pIsOut, lambda: "true", lambda: "false") + "; }")
            self.cxx.out('std::string name() throw() { return "%s"; }' % pname)
            self.cxx.out('already_AddRefd<iface::CGRS::GenericType> type() throw()')
            self.cxx.out('{')
            self.cxx.inc_indent()
            self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();')
            self.cxx.out(GetTypeInformation(ptype).fetchType())
            self.cxx.dec_indent()
            self.cxx.out('}')
            self.cxx.dec_indent()
            self.cxx.out('};')
        self.cxx.dec_indent()
        self.cxx.out('};')
示例#8
0
    def generateMethod(self, classname, cxxmethodname, retType, params):
        self.cxx.out('class meth%s' % classname)
        self.cxx.out('  : public iface::CGRS::GenericMethod')
        self.cxx.out('{')
        self.cxx.out('public:')
        self.cxx.inc_indent()

        self.cxx.out('CDA_IMPL_REFCOUNT;')
        self.cxx.out('CDA_IMPL_ID;')
        self.cxx.out('CDA_IMPL_QI1(CGRS::GenericMethod);')
        self.cxx.out(
            'std::vector<iface::CGRS::GenericParameter*> parameters() throw()')
        self.cxx.out('{')
        self.cxx.inc_indent()
        self.cxx.out('std::vector<iface::CGRS::GenericParameter*> params;')

        for (pname, ptype, pIsIn, pIsOut) in params:
            self.cxx.out('params.push_back(new Param%s());' % pname)

        self.cxx.out('return params;')
        self.cxx.dec_indent()
        self.cxx.out('}')

        self.cxx.out(
            'already_AddRefd<iface::CGRS::GenericType> returnType() throw()')
        self.cxx.out('{')
        self.cxx.inc_indent()
        self.cxx.out(
            'ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();'
        )
        self.cxx.out(GetTypeInformation(retType).fetchType())
        self.cxx.dec_indent()
        self.cxx.out('}')

        self.cxx.out('already_AddRefd<iface::CGRS::GenericValue>')
        self.cxx.out(
            'invoke(iface::CGRS::ObjectValue* aInvokeOn, const std::vector<iface::CGRS::GenericValue*>& aInValues,'
        )
        self.cxx.out(
            '       std::vector<iface::CGRS::GenericValue*>& aOutValues, bool* aWasException)'
        )
        self.cxx.out('  throw(std::exception&)')
        self.cxx.out('{')
        self.cxx.inc_indent()
        self.cxx.out(
            'ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();'
        )
        self.cxx.out('if (aInvokeOn == NULL) throw iface::CGRS::CGRSError();')
        self.cxx.out(
            'ObjRef<iface::XPCOM::IObject> obj = aInvokeOn->asObject();')
        self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(obji, obj, %s);' %
                     self.iface)
        self.cxx.out('if (obji == NULL) throw iface::CGRS::CGRSError();')

        incnt = 0
        for (pname, ptype, pIsIn, pIsOut) in params:
            if pIsIn:
                incnt = incnt + 1
        self.cxx.out(
            'if (aInValues.size() != %d) throw iface::CGRS::CGRSError();' %
            incnt)

        inidx = 0
        pidx = 0
        paramstring = ''
        for (pname, ptype, pIsIn, pIsOut) in params:
            ti = GetTypeInformation(ptype)
            self.cxx.out(ti.makeStorage('param%d' % pidx))
            self.cxx.out(ti.makeScopedDestructor('param%d' % pidx))
            if pIsIn:
                self.cxx.out(
                    'DECLARE_QUERY_INTERFACE_OBJREF(inValues%d, (aInValues[%d]), %s);'
                    % (inidx, inidx, ti.genericIface))
                self.cxx.out(
                    ti.convertGenericToNative('inValues%d' % inidx,
                                              'param%d' % pidx))
                inidx = inidx + 1
            if pidx != 0:
                paramstring = paramstring + ', '
            paramstring = paramstring + '%sparam%d' % (ti.ref(pIsOut), pidx)
            pidx = pidx + 1

        rti = GetTypeInformation(retType)
        self.cxx.out(rti.makeStorage('retval'))
        self.cxx.out(rti.makeScopedDestructor('retval'))
        self.cxx.out('*aWasException = false;')
        self.cxx.out('try')
        self.cxx.out('{')
        self.cxx.inc_indent()
        if rti.typename == 'void':
            retAssign = ''
        else:
            retAssign = 'retval = '
        self.cxx.out('%sobji->%s(%s);' %
                     (retAssign, cxxmethodname, paramstring))
        self.cxx.dec_indent()
        self.cxx.out('}')
        self.cxx.out('catch (...)')
        self.cxx.out('{')
        self.cxx.inc_indent()
        self.cxx.out(rti.defaultStorageValue('retval'))
        pidx = 0
        for (pname, ptype, pIsIn, pIsOut) in params:
            if pIsOut:
                self.cxx.out(rti.defaultStorageValue('param%d' % pidx))
            pidx = pidx + 1
        self.cxx.out('*aWasException = true;')
        self.cxx.dec_indent()
        self.cxx.out('}')

        pidx = 0
        for (pname, ptype, pIsIn, pIsOut) in params:
            ti = GetTypeInformation(ptype)
            if pIsOut:
                self.cxx.out('{')
                self.cxx.inc_indent()
                self.cxx.out('iface::CGRS::GenericValue* gval;')
                self.cxx.out(
                    ti.convertNativeToGeneric('param%d' % pidx, 'gval'))
                self.cxx.out('aOutValues.push_back(gval);')
                self.cxx.dec_indent()
                self.cxx.out('}')
            pidx = pidx + 1

        if rti.typename != 'void':
            self.cxx.out('ObjRef<iface::%s> gretval;' % rti.genericIface)
            self.cxx.out(rti.convertNativeToGeneric('retval', 'gretval'))
            self.cxx.out('gretval->add_ref();')
            self.cxx.out('return gretval.getPointer();')
        else:
            self.cxx.out('return cgs->makeVoid();')

        self.cxx.dec_indent()
        self.cxx.out('}')

        self.cxx.dec_indent()
        self.cxx.out('private:')
        self.cxx.inc_indent()

        for (pname, ptype, pIsIn, pIsOut) in params:
            self.cxx.out('class Param%s' % pname)
            self.cxx.out('  : public iface::CGRS::GenericParameter')
            self.cxx.out('{')
            self.cxx.out('public:')
            self.cxx.inc_indent()
            self.cxx.out('CDA_IMPL_ID;')
            self.cxx.out('CDA_IMPL_REFCOUNT;')
            self.cxx.out('CDA_IMPL_QI1(CGRS::GenericParameter);')
            self.cxx.out('bool isIn() throw() { return ' +
                         ternary(pIsIn, lambda: "true", lambda: "false") +
                         "; }")
            self.cxx.out('bool isOut() throw() { return ' +
                         ternary(pIsOut, lambda: "true", lambda: "false") +
                         "; }")
            self.cxx.out('std::string name() throw() { return "%s"; }' % pname)
            self.cxx.out(
                'already_AddRefd<iface::CGRS::GenericType> type() throw()')
            self.cxx.out('{')
            self.cxx.inc_indent()
            self.cxx.out(
                'ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();'
            )
            self.cxx.out(GetTypeInformation(ptype).fetchType())
            self.cxx.dec_indent()
            self.cxx.out('}')
            self.cxx.dec_indent()
            self.cxx.out('};')
        self.cxx.dec_indent()
        self.cxx.out('};')