Esempio n. 1
0
 def generate_python_call(self):
     """code to call the python method"""
     if settings._get_deprecated_virtuals():
         params = ['m_pyself', '(char *) "_%s"' % self.method_name]
     else:
         params = ['m_pyself', '(char *) "%s"' % self.method_name]
     build_params = self.build_params.get_parameters()
     if build_params[0][0] == '"':
         build_params[0] = '(char *) ' + build_params[0]
     params.extend(build_params)
     self.before_call.write_code('py_retval = PyObject_CallMethod(%s);'
                                 % (', '.join(params),))
     self.before_call.write_error_check('py_retval == NULL', failure_cleanup='PyErr_Print();')
     self.before_call.add_cleanup_code('Py_DECREF(py_retval);')
Esempio n. 2
0
 def generate_python_call(self):
     """code to call the python method"""
     if settings._get_deprecated_virtuals():
         params = ['m_pyself', '(char *) "_%s"' % self.method_name]
     else:
         params = ['m_pyself', '(char *) "%s"' % self.method_name]
     build_params = self.build_params.get_parameters()
     if build_params[0][0] == '"':
         build_params[0] = '(char *) ' + build_params[0]
     params.extend(build_params)
     self.before_call.write_code('py_retval = PyObject_CallMethod(%s);'
                                 % (', '.join(params),))
     self.before_call.write_error_check('py_retval == NULL', failure_cleanup='PyErr_Print();')
     self.before_call.add_cleanup_code('Py_DECREF(py_retval);')
Esempio n. 3
0
    def generate_call(self, class_=None):
        "virtual method implementation; do not call"
        #assert isinstance(class_, CppClass)
        if class_ is None:
            class_ = self._class
        if self.template_parameters:
            template_params = '< %s >' % ', '.join(self.template_parameters)
        else:
            template_params = ''


        if self.return_value.ctype == 'void':
            retval_assign = ''
        else:
            if self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR:
                retval_assign = '%s retval = ' % (self.return_value.ctype,)
            else:
                retval_assign = 'retval = '

        if class_.helper_class is not None and self.is_virtual and not self.is_pure_virtual\
                and not settings._get_deprecated_virtuals():
            helper = self.before_call.declare_variable(type_="%s *" % class_.helper_class.name,
                                                       name="helper_class",
                                                       initializer=(
                    "dynamic_cast<%s*> (self->obj)" % class_.helper_class.name))
        else:
            helper = None

        if self.is_static:
            method = '%s::%s%s' % (class_.full_name, self.method_name, template_params)
        else:
            method = 'self->obj->%s%s' % (self.method_name, template_params)

        if self.throw:
            self.before_call.write_code('try\n{')
            self.before_call.indent()

        if self.is_static:
            self.before_call.write_code(retval_assign + (
                    '%s::%s%s(%s);' % (class_.full_name,
                                       self.method_name, template_params,
                                       ", ".join(self.call_params))))
        else:
            if helper is None:
                self.before_call.write_code(retval_assign + (
                        'self->obj->%s%s(%s);' % (self.method_name, template_params,
                                                  ", ".join(self.call_params))))
            else:
                self.before_call.write_code(retval_assign + (
                        '(%s == NULL)? (self->obj->%s%s(%s)) : (self->obj->%s::%s%s(%s));'
                        % (helper,

                           self.method_name, template_params,
                           ", ".join(self.call_params),
                           
                           class_.full_name, self.method_name, template_params,
                           ", ".join(self.call_params)
                           )))

        if self.throw:
            for exc in self.throw:
                self.before_call.unindent()
                self.before_call.write_code('} catch (%s const &exc) {' % exc.full_name)
                self.before_call.indent()
                self.before_call.write_cleanup()
                exc.write_convert_to_python(self.before_call, 'exc')
                self.before_call.write_code('return NULL;')
            self.before_call.unindent()
            self.before_call.write_code('}')
Esempio n. 4
0
    def generate(self, code_sink):
        """generates the proxy virtual method"""
        if self.method.is_const:
            decl_post_modifiers = ['const']
        else:
            decl_post_modifiers = []

        if self.method.throw:
            decl_post_modifiers.append("throw (%s)" % (', '.join([ex.full_name for ex in self.method.throw]),))

        ## if the python subclass doesn't define a virtual method,
        ## just chain to parent class and don't do anything else
        call_params = ', '.join([param.name for param in self.parameters])
        py_method = self.declarations.declare_variable('PyObject*', 'py_method')
        if settings._get_deprecated_virtuals():
            self.before_call.write_code('%s = PyObject_GetAttrString(m_pyself, (char *) "_%s"); PyErr_Clear();'
                                        % (py_method, self.method_name))
        else:
            self.before_call.write_code('%s = PyObject_GetAttrString(m_pyself, (char *) "%s"); PyErr_Clear();'
                                        % (py_method, self.method_name))
        self.before_call.add_cleanup_code('Py_XDECREF(%s);' % py_method)
        
        self.before_call.write_code(
            r'if (%s == NULL || Py_TYPE(%s) == &PyCFunction_Type) {' % (py_method, py_method))
        if self.return_value.ctype == 'void':
            if not (self.method.is_pure_virtual or self.method.visibility == 'private'):
                self.before_call.write_code(r'    %s::%s(%s);'
                                            % (self.class_.full_name, self.method_name, call_params))
            self.before_call.indent()
            self.before_call.write_cleanup()
            self.before_call.write_code('return;')
            self.before_call.unindent()
        else:
            if self.method.is_pure_virtual or self.method.visibility == 'private':
                from . import cppclass
                if isinstance(self.return_value, cppclass.CppClassReturnValue) \
                        and self.return_value.cpp_class.has_trivial_constructor:
                    pass
                else:
                    self.set_error_return('''
PyErr_Print();
Py_FatalError("Error detected, but parent virtual is pure virtual or private virtual, "
              "and return is a class without trival constructor");''')
            else:
                self.set_error_return("return %s::%s(%s);"
                                      % (self.class_.full_name, self.method_name, call_params))
            self.before_call.indent()
            self.before_call.write_cleanup()
            self.before_call.write_code(self.error_return)
            self.before_call.unindent()
        self.before_call.write_code('}')

        ## Set "m_pyself->obj = this" around virtual method call invocation
        self_obj_before = self.declarations.declare_variable(
            '%s*' % self.class_.full_name, 'self_obj_before')
        self.before_call.write_code("%s = reinterpret_cast< %s* >(m_pyself)->obj;" %
                                    (self_obj_before, self.class_.pystruct))
        if self.method.is_const:
            this_expression = ("const_cast< %s* >((const %s*) this)" %
                               (self.class_.full_name, self.class_.full_name))
        else:
            this_expression = "(%s*) this" % (self.class_.full_name)
        self.before_call.write_code("reinterpret_cast< %s* >(m_pyself)->obj = %s;" %
                                    (self.class_.pystruct, this_expression))
        self.before_call.add_cleanup_code("reinterpret_cast< %s* >(m_pyself)->obj = %s;" %
                                          (self.class_.pystruct, self_obj_before))
        
        super(CppVirtualMethodProxy, self).generate(
            code_sink, '::'.join((self._helper_class.name, self.method_name)),
            decl_modifiers=[],
            decl_post_modifiers=decl_post_modifiers)
Esempio n. 5
0
    def generate_call(self, class_=None):
        "virtual method implementation; do not call"
        #assert isinstance(class_, CppClass)
        if class_ is None:
            class_ = self._class
        if self.template_parameters:
            template_params = '< %s >' % ', '.join(self.template_parameters)
        else:
            template_params = ''


        if self.return_value.ctype == 'void':
            retval_assign = ''
        else:
            if self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR:
                retval_assign = '%s retval = ' % (self.return_value.ctype,)
            else:
                retval_assign = 'retval = '

        if class_.helper_class is not None and self.is_virtual and not self.is_pure_virtual\
                and not settings._get_deprecated_virtuals():
            helper = self.before_call.declare_variable(type_="%s *" % class_.helper_class.name,
                                                       name="helper_class",
                                                       initializer=(
                    "dynamic_cast<%s*> (self->obj)" % class_.helper_class.name))
        else:
            helper = None

        if self.is_static:
            method = '%s::%s%s' % (class_.full_name, self.method_name, template_params)
        else:
            method = 'self->obj->%s%s' % (self.method_name, template_params)

        if self.throw:
            self.before_call.write_code('try\n{')
            self.before_call.indent()

        if self.is_static:
            self.before_call.write_code(retval_assign + (
                    '%s::%s%s(%s);' % (class_.full_name,
                                       self.method_name, template_params,
                                       ", ".join(self.call_params))))
        else:
            if helper is None:
                self.before_call.write_code(retval_assign + (
                        'self->obj->%s%s(%s);' % (self.method_name, template_params,
                                                  ", ".join(self.call_params))))
            else:
                self.before_call.write_code(retval_assign + (
                        '(%s == NULL)? (self->obj->%s%s(%s)) : (self->obj->%s::%s%s(%s));'
                        % (helper,

                           self.method_name, template_params,
                           ", ".join(self.call_params),
                           
                           class_.full_name, self.method_name, template_params,
                           ", ".join(self.call_params)
                           )))

        if self.throw:
            for exc in self.throw:
                self.before_call.unindent()
                self.before_call.write_code('} catch (%s const &exc) {' % exc.full_name)
                self.before_call.indent()
                self.before_call.write_cleanup()
                exc.write_convert_to_python(self.before_call, 'exc')
                self.before_call.write_code('return NULL;')
            self.before_call.unindent()
            self.before_call.write_code('}')
Esempio n. 6
0
    def generate(self, code_sink):
        """generates the proxy virtual method"""
        if self.method.is_const:
            decl_post_modifiers = ['const']
        else:
            decl_post_modifiers = []

        if self.method.throw:
            decl_post_modifiers.append("throw (%s)" % (', '.join([ex.full_name for ex in self.method.throw]),))

        ## if the python subclass doesn't define a virtual method,
        ## just chain to parent class and don't do anything else
        call_params = ', '.join([param.name for param in self.parameters])
        py_method = self.declarations.declare_variable('PyObject*', 'py_method')
        if settings._get_deprecated_virtuals():
            self.before_call.write_code('%s = PyObject_GetAttrString(m_pyself, (char *) "_%s"); PyErr_Clear();'
                                        % (py_method, self.method_name))
        else:
            self.before_call.write_code('%s = PyObject_GetAttrString(m_pyself, (char *) "%s"); PyErr_Clear();'
                                        % (py_method, self.method_name))
        self.before_call.add_cleanup_code('Py_XDECREF(%s);' % py_method)
        
        self.before_call.write_code(
            r'if (%s == NULL || Py_TYPE(%s) == &PyCFunction_Type) {' % (py_method, py_method))
        if self.return_value.ctype == 'void':
            if not (self.method.is_pure_virtual or self.method.visibility == 'private'):
                self.before_call.write_code(r'    %s::%s(%s);'
                                            % (self.class_.full_name, self.method_name, call_params))
            self.before_call.indent()
            self.before_call.write_cleanup()
            self.before_call.write_code('return;')
            self.before_call.unindent()
        else:
            if self.method.is_pure_virtual or self.method.visibility == 'private':
                from . import cppclass
                if isinstance(self.return_value, cppclass.CppClassReturnValue) \
                        and self.return_value.cpp_class.has_trivial_constructor:
                    pass
                else:
                    self.set_error_return('''
PyErr_Print();
Py_FatalError("Error detected, but parent virtual is pure virtual or private virtual, "
              "and return is a class without trival constructor");''')
            else:
                self.set_error_return("return %s::%s(%s);"
                                      % (self.class_.full_name, self.method_name, call_params))
            self.before_call.indent()
            self.before_call.write_cleanup()
            self.before_call.write_code(self.error_return)
            self.before_call.unindent()
        self.before_call.write_code('}')

        ## Set "m_pyself->obj = this" around virtual method call invocation
        self_obj_before = self.declarations.declare_variable(
            '%s*' % self.class_.full_name, 'self_obj_before')
        self.before_call.write_code("%s = reinterpret_cast< %s* >(m_pyself)->obj;" %
                                    (self_obj_before, self.class_.pystruct))
        if self.method.is_const:
            this_expression = ("const_cast< %s* >((const %s*) this)" %
                               (self.class_.full_name, self.class_.full_name))
        else:
            this_expression = "(%s*) this" % (self.class_.full_name)
        self.before_call.write_code("reinterpret_cast< %s* >(m_pyself)->obj = %s;" %
                                    (self.class_.pystruct, this_expression))
        self.before_call.add_cleanup_code("reinterpret_cast< %s* >(m_pyself)->obj = %s;" %
                                          (self.class_.pystruct, self_obj_before))
        
        super(CppVirtualMethodProxy, self).generate(
            code_sink, '::'.join((self._helper_class.name, self.method_name)),
            decl_modifiers=[],
            decl_post_modifiers=decl_post_modifiers)