Skip to content

Commit a726892

Browse files
[mypyc] Refactor: Use WrapperGenerator for generate_wrapper_core (python#12209)
The WrapperGenerator is an abstract class for wrapper generation, originally from generate_wrapper_core. The latter one is fully covered by the WrapperGenerator.
1 parent 608f274 commit a726892

File tree

1 file changed

+16
-49
lines changed

1 file changed

+16
-49
lines changed

mypyc/codegen/emitwrapper.py

+16-49
Original file line numberDiff line numberDiff line change
@@ -286,21 +286,20 @@ def generate_bin_op_wrapper(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
286286
gen.emit_header()
287287
if fn.name not in reverse_op_methods and fn.name in reverse_op_method_names:
288288
# There's only a reverse operator method.
289-
generate_bin_op_reverse_only_wrapper(cl, fn, emitter, gen)
289+
generate_bin_op_reverse_only_wrapper(emitter, gen)
290290
else:
291291
rmethod = reverse_op_methods[fn.name]
292292
fn_rev = cl.get_method(rmethod)
293293
if fn_rev is None:
294294
# There's only a forward operator method.
295-
generate_bin_op_forward_only_wrapper(cl, fn, emitter, gen)
295+
generate_bin_op_forward_only_wrapper(fn, emitter, gen)
296296
else:
297297
# There's both a forward and a reverse operator method.
298298
generate_bin_op_both_wrappers(cl, fn, fn_rev, emitter, gen)
299299
return wrapper_name
300300

301301

302-
def generate_bin_op_forward_only_wrapper(cl: ClassIR,
303-
fn: FuncIR,
302+
def generate_bin_op_forward_only_wrapper(fn: FuncIR,
304303
emitter: Emitter,
305304
gen: 'WrapperGenerator') -> None:
306305
gen.emit_arg_processing(error=GotoHandler('typefail'), raise_exception=False)
@@ -331,9 +330,7 @@ def generate_bin_op_forward_only_wrapper(cl: ClassIR,
331330
gen.finish()
332331

333332

334-
def generate_bin_op_reverse_only_wrapper(cl: ClassIR,
335-
fn_rev: FuncIR,
336-
emitter: Emitter,
333+
def generate_bin_op_reverse_only_wrapper(emitter: Emitter,
337334
gen: 'WrapperGenerator') -> None:
338335
gen.arg_names = ['right', 'left']
339336
gen.emit_arg_processing(error=GotoHandler('typefail'), raise_exception=False)
@@ -650,47 +647,17 @@ def generate_wrapper_core(fn: FuncIR,
650647
It converts the PyObject *s to the necessary types, checking and unboxing if necessary,
651648
makes the call, then boxes the result if necessary and returns it.
652649
"""
650+
gen = WrapperGenerator(None, emitter)
651+
gen.set_target(fn)
652+
gen.arg_names = arg_names or [arg.name for arg in fn.args]
653+
gen.cleanups = cleanups or []
654+
gen.optional_args = optional_args or []
655+
gen.traceback_code = traceback_code or ''
653656

654-
optional_args = optional_args or []
655-
cleanups = cleanups or []
656-
use_goto = bool(cleanups or traceback_code)
657-
error = ReturnHandler('NULL') if not use_goto else GotoHandler('fail')
658-
659-
arg_names = arg_names or [arg.name for arg in fn.args]
660-
for arg_name, arg in zip(arg_names, fn.args):
661-
# Suppress the argument check for *args/**kwargs, since we know it must be right.
662-
typ = arg.type if arg.kind not in (ARG_STAR, ARG_STAR2) else object_rprimitive
663-
generate_arg_check(arg_name,
664-
typ,
665-
emitter,
666-
error,
667-
optional=arg in optional_args)
668-
native_args = ', '.join('arg_{}'.format(arg) for arg in arg_names)
669-
if fn.ret_type.is_unboxed or use_goto:
670-
# TODO: The Py_RETURN macros return the correct PyObject * with reference count handling.
671-
# Are they relevant?
672-
emitter.emit_line('{}retval = {}{}({});'.format(emitter.ctype_spaced(fn.ret_type),
673-
NATIVE_PREFIX,
674-
fn.cname(emitter.names),
675-
native_args))
676-
emitter.emit_lines(*cleanups)
677-
if fn.ret_type.is_unboxed:
678-
emitter.emit_error_check('retval', fn.ret_type, 'return NULL;')
679-
emitter.emit_box('retval', 'retbox', fn.ret_type, declare_dest=True)
680-
681-
emitter.emit_line('return {};'.format('retbox' if fn.ret_type.is_unboxed else 'retval'))
682-
else:
683-
emitter.emit_line('return {}{}({});'.format(NATIVE_PREFIX,
684-
fn.cname(emitter.names),
685-
native_args))
686-
# TODO: Tracebacks?
687-
688-
if use_goto:
689-
emitter.emit_label('fail')
690-
emitter.emit_lines(*cleanups)
691-
if traceback_code:
692-
emitter.emit_lines(traceback_code)
693-
emitter.emit_lines('return NULL;')
657+
error = ReturnHandler('NULL') if not gen.use_goto() else GotoHandler('fail')
658+
gen.emit_arg_processing(error=error)
659+
gen.emit_call()
660+
gen.emit_error_handling()
694661

695662

696663
def generate_arg_check(name: str,
@@ -741,7 +708,7 @@ class WrapperGenerator:
741708

742709
# TODO: Use this for more wrappers
743710

744-
def __init__(self, cl: ClassIR, emitter: Emitter) -> None:
711+
def __init__(self, cl: Optional[ClassIR], emitter: Emitter) -> None:
745712
self.cl = cl
746713
self.emitter = emitter
747714
self.cleanups: List[str] = []
@@ -764,7 +731,7 @@ def wrapper_name(self) -> str:
764731
"""Return the name of the wrapper function."""
765732
return '{}{}{}'.format(DUNDER_PREFIX,
766733
self.target_name,
767-
self.cl.name_prefix(self.emitter.names))
734+
self.cl.name_prefix(self.emitter.names) if self.cl else '')
768735

769736
def use_goto(self) -> bool:
770737
"""Do we use a goto for error handling (instead of straight return)?"""

0 commit comments

Comments
 (0)