Ejemplo 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);")
Ejemplo 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);')
Ejemplo 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("}")
Ejemplo 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 || %s->ob_type == &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.write_cleanup()
            self.before_call.write_code(r"    return;")
        else:
            if self.method.is_pure_virtual or self.method.visibility == "private":
                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,
        )
Ejemplo 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('}')
Ejemplo 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 || %s->ob_type == &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.write_cleanup()
            self.before_call.write_code(r'    return;')
        else:
            if self.method.is_pure_virtual or self.method.visibility == 'private':
                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)