Ejemplo n.º 1
0
    def visitAttribute(self, node):
        ti = jnutils.GetTypeInformation(node.attrType().unalias())

        for n in node.declarators():
            self.writeMethod(
                jnutils.CppName(n.identifier()),
                jnutils.JavaMangleName(jnutils.AccessorName(n, 0)), ti, [])

        if not node.readonly():
            for n in node.declarators():
                self.writeMethod(
                    jnutils.CppName(n.identifier()),
                    jnutils.JavaMangleName(jnutils.AccessorName(n, 1)), None,
                    [['param', ti, jnutils.Type.IN]])
Ejemplo n.º 2
0
    def visitAttribute(self, node):
        ti = jnutils.GetTypeInformation(node.attrType().unalias())

        for n in node.declarators():
            self.pushManglePart(jnutils.AccessorName(n, 0))
            self.calculateMangled()
            self.writeMethod(self.mangled, jnutils.CppName(n.identifier()), ti,
                             [], [])
            self.popManglePart()

        if not node.readonly():
            itype = ti.jniType(jnutils.Type.IN)
            for n in node.declarators():
                self.pushManglePart(jnutils.AccessorName(n, 1))
                self.calculateMangled()
                self.writeMethod(self.mangled, jnutils.CppName(n.identifier()),
                                 None, [['param', ti, jnutils.Type.IN]], [])
                self.popManglePart()
Ejemplo n.º 3
0
 def visitOperation(self, node):
     rti = jnutils.GetTypeInformation(node.returnType().unalias())
     params = []
     for p in node.parameters():
         dirn = [jnutils.Type.IN, jnutils.Type.OUT,
                 jnutils.Type.INOUT][p.direction()]
         pti = jnutils.GetTypeInformation(p.paramType().unalias())
         params.append([p.identifier(), pti, dirn])
     self.writeMethod(jnutils.CppName(node.identifier()),
                      jnutils.JavaMangleName(node.identifier()), rti,
                      params)
Ejemplo n.º 4
0
 def visitOperation(self, node):
     rti = jnutils.GetTypeInformation(node.returnType().unalias())
     params = []
     for p in node.parameters():
         dirn = [jnutils.Type.IN, jnutils.Type.OUT,
                 jnutils.Type.INOUT][p.direction()]
         pti = jnutils.GetTypeInformation(p.paramType().unalias())
         params.append([p.identifier(), pti, dirn])
     self.pushManglePart(node.identifier())
     self.calculateMangled()
     self.writeMethod(self.mangled, jnutils.CppName(node.identifier()), rti,
                      params, node.raises())
     self.popManglePart()
Ejemplo n.º 5
0
    def writeMethod(self, name, pcmName, rtype, params, excepts):
        if rtype == None:
            rtypeName = 'void'
        else:
            rtypeName = rtype.jniType(jnutils.Type.RETURN)

        paramString = 'JNIEnv* env, jobject thisptr'
        for (pname, ti, dirn) in params:
            tiName = ti.jniType(dirn)
            paramString = paramString + ', ' + tiName + ' ' + pname

        self.hxx.out('extern "C" { PUBLIC_JAVAMOD_PRE ' + rtypeName + ' ' +
                     name + '(' + paramString + ') PUBLIC_JAVAMOD_POST; };')
        self.cppMod.out(rtypeName + ' ' + name + '(' + paramString + ')')
        self.cppMod.out('{')
        self.cppMod.inc_indent()

        if (rtype != None and rtypeName != 'void'):
            needRet = 1
            self.cppMod.out(rtype.pcmType(jnutils.Type.DERIVE) + ' _pcm_ret;')
        else:
            needRet = 0

        pcmParams = ''
        for (pname, ti, dirn) in params:
            # We need to convert in parameters to the CXX type...
            indirect = ''
            if dirn != jnutils.Type.IN:
                indirect = ti.cref
            if pcmParams != '':
                pcmParams = pcmParams + ', '
            self.cppMod.out(
                ti.pcmType(jnutils.Type.DERIVE) + ' _pcm_' + pname + ';')
            pcmParams = pcmParams + indirect + '_pcm_' + pname
            if dirn == jnutils.Type.OUT:
                continue
            self.cppMod.out(
                ti.convertToPCM(pname, '_pcm_' + pname,
                                dirn != jnutils.Type.IN))

        # Next, we need to extract the 'this' pointer...
        self.cppMod.out(self.cxxclass + '* pcm_this;')
        self.cppMod.out('{')
        self.cppMod.inc_indent()
        self.cppMod.out('jclass thisclazz = env->GetObjectClass(thisptr);')
        self.cppMod.out(
            'jfieldID fid = env->GetFieldID(thisclazz, "nativePtr", "J");')
        self.cppMod.out('pcm_this = reinterpret_cast<' + self.cxxclass +
                        '*>(env->GetLongField(thisptr, fid));')
        self.cppMod.dec_indent()
        self.cppMod.out('}')

        # Make the call to the PCM interface...
        if needRet:
            retsave = '_pcm_ret = '
        else:
            retsave = ''

        self.cppMod.out('try')
        self.cppMod.out('{')
        self.cppMod.inc_indent()

        self.cppMod.out(retsave + 'pcm_this->' + pcmName + '(' + pcmParams +
                        ');')

        self.cppMod.dec_indent()
        self.cppMod.out('}')
        for e in excepts:
            self.cppMod.out('catch (%s& _except)' %
                            ('iface::' + jnutils.ScopedCppName(e)))
            self.cppMod.out('{')
            self.cppMod.inc_indent()
            # Clean up parameters...
            for (pname, ti, dirn) in params:
                self.cppMod.out(ti.pcmDestroy('_pcm_' + pname))
            sigArgs = ''
            invokeArgs = ''
            for mem in e.members():
                ti = jnutils.GetTypeInformation(mem.memberType())
                for d in mem.declarators():
                    jniName = '_ejni_' + d.identifier()
                    self.cppMod.out('%s %s;' %
                                    (ti.jniType(jnutils.Type.IN), jniName))
                    self.cppMod.out(
                        ti.convertToJNI(
                            jniName,
                            '_except.%s' % (jnutils.CppName(d.identifier()))))
                    sigArgs = sigArgs + ti.javaSig(jnutils.Type.IN)
                    invokeArgs = invokeArgs + ',' + jniName
            self.cppMod.out('jclass eclazz = env->FindClass("%s");' %
                            string.join(e.scopedName(), '/'))
            self.cppMod.out(
                'jmethodID meth = env->GetMethodID(eclazz, "<init>", "(%s)V");'
                % sigArgs)
            self.cppMod.out('jobject eobj = env->NewObject(eclazz, meth%s);' %
                            invokeArgs)
            self.cppMod.out('env->Throw((jthrowable)eobj);')
            if needRet:
                self.cppMod.out('return ' + rtype.failure_return + ';')
            else:
                self.cppMod.out('return;')
            self.cppMod.dec_indent()
            self.cppMod.out('}')
        self.cppMod.out('catch (...)')
        self.cppMod.out('{')
        self.cppMod.inc_indent()
        # Clean up parameters...
        for (pname, ti, dirn) in params:
            self.cppMod.out(ti.pcmDestroy('_pcm_' + pname))
        # Raise an exception...
        self.cppMod.out(
            'jclass eclazz = env->FindClass("java/lang/RuntimeException");')
        self.cppMod.out(
            'env->ThrowNew(eclazz, "Native code threw exception");')
        if needRet:
            self.cppMod.out('return ' + rtype.failure_return + ';')
        else:
            self.cppMod.out('return;')
        self.cppMod.dec_indent()
        self.cppMod.out('}')

        # Convert out / inout parameters to JNI...
        for (pname, ti, dirn) in params:
            if dirn == jnutils.Type.IN:
                continue
            self.cppMod.out(
                ti.convertToJNI(pname, '_pcm_' + pname, indirectOut=1))

        if needRet:
            self.cppMod.out(rtypeName + ' _jni_ret;')
            self.cppMod.out(rtype.convertToJNI('_jni_ret', '_pcm_ret'))

        # Clean up parameters...
        for (pname, ti, dirn) in params:
            self.cppMod.out(ti.pcmDestroy('_pcm_' + pname))
        if needRet:
            self.cppMod.out(rtype.pcmDestroy('_pcm_ret'))
            self.cppMod.out('return _jni_ret;')

        self.cppMod.dec_indent()
        self.cppMod.out('}')
Ejemplo n.º 6
0
    def visitInterface(self, node):
        # If it doesn't have the user-callback pragma, don't bother generating...
        hasCallback = 0
        for p in node.pragmas():
            hasCallback = hasCallback or (p.text() == "user-callback")
        if hasCallback == 0:
            return

        self.syncNamespaces()
        self.hxx.out(
            'PUBLIC_%s_PRE class PUBLIC_%s_POST %s' %
            (self.defname, self.defname, jnutils.CppName(node.identifier())))

        isTerminal = 0
        # See if this is a terminal interface...
        for p in node.pragmas():
            if p.text() == "terminal-interface":
                isTerminal = 1

        virtual = ''
        if not isTerminal:
            virtual = 'virtual '

        inh = filter(lambda x: x.repoId() != REPOID_ISUPPORTS, node.inherits())

        scopedname = jnutils.ScopedCppName(node)
        classname = 'p2j::' + scopedname
        self.classname = classname
        self.javaclass = string.join(node.scopedName(), '/')

        self.hxx.out('    : public @virtual@::iface::@scopedname@',
                     virtual=virtual,
                     scopedname=scopedname)

        if len(inh) == 0:
            self.hxx.out('    , public @virtual@::p2j::XPCOM::IObject',
                         virtual=virtual)
        else:
            for c in inh:
                if isinstance(c, idlast.Declarator) and c.alias():
                    c = c.alias().aliasType().unalias().decl()

                isAmbiguous = 0
                iclassname = jnutils.ScopedCppName(c)
                target = 'ambiguous-inheritance(' + iclassname + ')'
                for p in node.pragmas():
                    if p.text() == target:
                        isAmbiguous = 1
                        break
                if isAmbiguous:
                    virtual = 'virtual '
                else:
                    virtual = ''
                self.hxx.out('    , public @virtual@::p2j::@classname@',
                             virtual=virtual,
                             classname=iclassname)

        self.hxx.out('{')
        self.hxx.out('public:')
        self.hxx.inc_indent()
        self.hxx.out(jnutils.CppName(node.identifier()) + '() {}')
        self.hxx.out('PUBLIC_@defname@_PRE @classname@(JNIEnv* aEnv, ' +
                     'jobject aObject) PUBLIC_@defname@_POST;',
                     classname=jnutils.CppName(node.identifier()),
                     defname=self.defname)

        self.cpp.out(
            classname + '::' + jnutils.CppName(node.identifier()) +
            '(JNIEnv* aEnv, jobject aObject) : ::p2j::XPCOM::IObject(aEnv, aObject)'
        )
        self.cpp.out('{')
        self.cpp.out('}')

        for n in node.contents():
            n.accept(self)

        self.hxx.dec_indent()
        self.hxx.out('};')

        fname = jnutils.CppName(string.join(node.scopedName(),
                                            '_')) + 'Factory'
        self.cpp.out('class ' + fname)
        self.cpp.out('  : public P2JFactory')
        self.cpp.out('{')
        self.cpp.out('public:')
        self.cpp.inc_indent()
        self.cpp.out(fname + '() : ::P2JFactory("' +\
                     scopedname + '", "' + self.javaclass +\
                     '") {}')
        self.cpp.out('void* create(JNIEnv* env, jobject obj) { return reinterpret_cast<void*>(' +\
                     'static_cast< ::iface::' + scopedname + '*>(new ' +\
                     classname + '(env, obj))); }')
        self.cpp.dec_indent()
        self.cpp.out('};')
        self.cpp.out(fname + ' s' + fname + ';')
Ejemplo n.º 7
0
 def visitForward(self, node):
     self.syncNamespaces()
     self.hxx.out('class ' + jnutils.CppName(node.identifier()) + ';')