Skip to content

Commit fcbb2dd

Browse files
authored
[mypyc] Simplify argument parsing in legacy wrapper functions (#10234)
Only include the argument parsing functionality we need. This speeds up the call_type_from_interpreted microbenchmark by about 17% on Python 3.8. This will also speed up most wrapper functions on Python 3.6 and earlier, since they don't use the new-style "fastcall" wrappers. This also speeds up the test suite a little, since there's less code to compile.
1 parent 797544d commit fcbb2dd

File tree

3 files changed

+74
-1317
lines changed

3 files changed

+74
-1317
lines changed

mypyc/codegen/emitwrapper.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def make_static_kwlist(args: List[RuntimeArg]) -> str:
8888
return 'static const char * const kwlist[] = {{{}0}};'.format(arg_names)
8989

9090

91-
def make_format_string(func_name: str, groups: List[List[RuntimeArg]]) -> str:
91+
def make_format_string(func_name: Optional[str], groups: List[List[RuntimeArg]]) -> str:
9292
"""Return a format string that specifies the accepted arguments.
9393
9494
The format string is an extended subset of what is supported by
@@ -103,17 +103,19 @@ def make_format_string(func_name: str, groups: List[List[RuntimeArg]]) -> str:
103103
104104
These are used by both vectorcall and legacy wrapper functions.
105105
"""
106-
main_format = ''
106+
format = ''
107107
if groups[ARG_STAR] or groups[ARG_STAR2]:
108-
main_format += '%'
109-
main_format += 'O' * len(groups[ARG_POS])
108+
format += '%'
109+
format += 'O' * len(groups[ARG_POS])
110110
if groups[ARG_OPT] or groups[ARG_NAMED_OPT] or groups[ARG_NAMED]:
111-
main_format += '|' + 'O' * len(groups[ARG_OPT])
111+
format += '|' + 'O' * len(groups[ARG_OPT])
112112
if groups[ARG_NAMED_OPT] or groups[ARG_NAMED]:
113-
main_format += '$' + 'O' * len(groups[ARG_NAMED_OPT])
113+
format += '$' + 'O' * len(groups[ARG_NAMED_OPT])
114114
if groups[ARG_NAMED]:
115-
main_format += '@' + 'O' * len(groups[ARG_NAMED])
116-
return '{}:{}'.format(main_format, func_name)
115+
format += '@' + 'O' * len(groups[ARG_NAMED])
116+
if func_name is not None:
117+
format += ':{}'.format(func_name)
118+
return format
117119

118120

119121
def generate_wrapper_function(fn: FuncIR,
@@ -237,8 +239,8 @@ def generate_legacy_wrapper_function(fn: FuncIR,
237239
arg_ptrs += ['&obj_{}'.format(arg.name) for arg in reordered_args]
238240

239241
emitter.emit_lines(
240-
'if (!CPyArg_ParseTupleAndKeywords(args, kw, "{}", kwlist{})) {{'.format(
241-
make_format_string(fn.name, groups), ''.join(', ' + n for n in arg_ptrs)),
242+
'if (!CPyArg_ParseTupleAndKeywords(args, kw, "{}", "{}", kwlist{})) {{'.format(
243+
make_format_string(None, groups), fn.name, ''.join(', ' + n for n in arg_ptrs)),
242244
'return NULL;',
243245
'}')
244246
traceback_code = generate_traceback_code(fn, emitter, source_path, module_name)

mypyc/lib-rt/CPy.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ CPyTagged CPyTagged_Id(PyObject *o);
516516
void CPyDebug_Print(const char *msg);
517517
void CPy_Init(void);
518518
int CPyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
519-
const char *, const char * const *, ...);
519+
const char *, const char *, const char * const *, ...);
520520
int CPyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
521521
CPyArg_Parser *parser, ...);
522522
int CPyArg_ParseStackAndKeywordsNoArgs(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
@@ -535,7 +535,6 @@ int CPyStatics_Initialize(PyObject **statics,
535535
const double *complex_numbers,
536536
const int *tuples);
537537

538-
539538
#ifdef __cplusplus
540539
}
541540
#endif

0 commit comments

Comments
 (0)