Example #1
0
def is_fastcall_supported(fn: FuncIR, capi_version: Tuple[int, int]) -> bool:
    if fn.class_name is not None:
        if fn.name == '__call__':
            # We can use vectorcalls (PEP 590) when supported
            return use_vectorcall(capi_version)
        # TODO: Support fastcall for __init__.
        return use_fastcall(capi_version) and fn.name != '__init__'
    return use_fastcall(capi_version)
Example #2
0
def generate_methods_table(cl: ClassIR, name: str, emitter: Emitter) -> None:
    emitter.emit_line('static PyMethodDef {}[] = {{'.format(name))
    for fn in cl.methods.values():
        if fn.decl.is_prop_setter or fn.decl.is_prop_getter:
            continue
        emitter.emit_line('{{"{}",'.format(fn.name))
        emitter.emit_line(' (PyCFunction){}{},'.format(PREFIX,
                                                       fn.cname(
                                                           emitter.names)))
        if use_fastcall(emitter.capi_version):
            flags = ['METH_FASTCALL']
        else:
            flags = ['METH_VARARGS']
        flags.append('METH_KEYWORDS')
        if fn.decl.kind == FUNC_STATICMETHOD:
            flags.append('METH_STATIC')
        elif fn.decl.kind == FUNC_CLASSMETHOD:
            flags.append('METH_CLASS')

        emitter.emit_line(' {}, NULL}},'.format(' | '.join(flags)))

    # Provide a default __getstate__ and __setstate__
    if not cl.has_method('__setstate__') and not cl.has_method('__getstate__'):
        emitter.emit_lines(
            '{"__setstate__", (PyCFunction)CPyPickle_SetState, METH_O, NULL},',
            '{"__getstate__", (PyCFunction)CPyPickle_GetState, METH_NOARGS, NULL},',
        )

    emitter.emit_line('{NULL}  /* Sentinel */')
    emitter.emit_line('};')