예제 #1
0
static PyObject *Nuitka_Method_tp_call( struct Nuitka_MethodObject *method, PyObject *args, PyObject *kw )
{
    Py_ssize_t arg_count = PyTuple_Size( args );

    if ( method->m_object == NULL )
    {
        if (unlikely( arg_count < 1 ))
        {
            PyErr_Format(
                PyExc_TypeError,
                "unbound compiled_method %s%s must be called with %s instance as first argument (got nothing instead)",
                GET_CALLABLE_NAME( (PyObject *)method->m_function ),
                GET_CALLABLE_DESC( (PyObject *)method->m_function ),
                GET_CLASS_NAME( method->m_class )
            );
            return NULL;
        }
        else
        {
            PyObject *self = PyTuple_GET_ITEM( args, 0 );
            CHECK_OBJECT( self );

            int result = PyObject_IsInstance( self, method->m_class );

            if (unlikely( result < 0 ))
            {
                return NULL;
            }
            else if (unlikely( result == 0 ))
            {
                PyErr_Format(
                    PyExc_TypeError,
                    "unbound compiled_method %s%s must be called with %s instance as first argument (got %s instance instead)",
                    GET_CALLABLE_NAME( (PyObject *)method->m_function ),
                    GET_CALLABLE_DESC( (PyObject *)method->m_function ),
                    GET_CLASS_NAME( method->m_class ),
                    GET_INSTANCE_CLASS_NAME( (PyObject *)self )
                );

                return NULL;
            }
        }

        return Py_TYPE( method->m_function )->tp_call(
            (PyObject *)method->m_function, args, kw
        );
    }
    else
    {
        return Nuitka_CallMethodFunctionPosArgsKwArgs(
            method->m_function,
            method->m_object,
            &PyTuple_GET_ITEM( args, 0 ),
            arg_count,
            kw
        );
    }
}
예제 #2
0
static PyObject *Nuitka_Method_tp_call( Nuitka_MethodObject *method, PyObject *args, PyObject *kw )
{
    int arg_count = int( PyTuple_Size( args ) );

    if ( method->m_object == NULL )
    {
        if (unlikely( arg_count < 1 ))
        {
            PyErr_Format(
                PyExc_TypeError,
                "unbound compiled_method %s%s must be called with %s instance as first argument (got nothing instead)",
                GET_CALLABLE_NAME( (PyObject *)method->m_function ),
                GET_CALLABLE_DESC( (PyObject *)method->m_function ),
                GET_CLASS_NAME( method->m_class )
            );
            return NULL;
        }
        else
        {
            PyObject *self = PyTuple_GET_ITEM( args, 0 );
            assertObject( self );

            int result = PyObject_IsInstance( self, method->m_class );

            if (unlikely( result < 0 ))
            {
                return NULL;
            }
            else if (unlikely( result == 0 ))
            {
                PyErr_Format(
                    PyExc_TypeError,
                    "unbound compiled_method %s%s must be called with %s instance as first argument (got %s instance instead)",
                    GET_CALLABLE_NAME( (PyObject *)method->m_function ),
                    GET_CALLABLE_DESC( (PyObject *)method->m_function ),
                    GET_CLASS_NAME( method->m_class ),
                    GET_INSTANCE_CLASS_NAME( (PyObject *)self )
                );

                return NULL;
            }
        }

        return Py_TYPE( method->m_function )->tp_call(
            (PyObject *)method->m_function, args, kw
        );
    }
    else
    {
#ifdef _MSC_VER
        PyObject **new_args = (PyObject **)_alloca( sizeof( PyObject * ) *( arg_count + 1 ) );
#else
        PyObject *new_args[ arg_count + 1 ];
#endif
        new_args[ 0 ] = method->m_object;

        for ( int i = 0; i < arg_count; i++ )
        {
            new_args[ i + 1 ] = PyTuple_GET_ITEM( args, i );
        }

        if ( kw || method->m_function->m_direct_arg_parser == NULL )
        {
            return method->m_function->m_code(
                method->m_function,
                new_args,
                arg_count + 1,
                kw
            );
        }
        else
        {
            return method->m_function->m_direct_arg_parser(
                method->m_function,
                new_args,
                arg_count + 1
            );
        }
    }
}