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)
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('};')