Helper that simplifies the generation of wrapper functions.
| 838 | |
| 839 | |
| 840 | class WrapperGenerator: |
| 841 | """Helper that simplifies the generation of wrapper functions.""" |
| 842 | |
| 843 | # TODO: Use this for more wrappers |
| 844 | |
| 845 | def __init__(self, cl: ClassIR | None, emitter: Emitter) -> None: |
| 846 | self.cl = cl |
| 847 | self.emitter = emitter |
| 848 | self.cleanups: list[str] = [] |
| 849 | self.optional_args: list[RuntimeArg] = [] |
| 850 | self.traceback_code = "" |
| 851 | |
| 852 | def set_target(self, fn: FuncIR) -> None: |
| 853 | """Set the wrapped function. |
| 854 | |
| 855 | It's fine to modify the attributes initialized here later to customize |
| 856 | the wrapper function. |
| 857 | """ |
| 858 | self.target_name = fn.name |
| 859 | self.target_cname = fn.cname(self.emitter.names) |
| 860 | # Cached native-call expression so cross-group targets go through the |
| 861 | # exports table; same as `NATIVE_PREFIX + cname` for in-group calls. |
| 862 | self.target_native_call = self.emitter.native_function_call(fn.decl) |
| 863 | self.num_bitmap_args = fn.sig.num_bitmap_args |
| 864 | if self.num_bitmap_args: |
| 865 | self.args = fn.args[: -self.num_bitmap_args] |
| 866 | else: |
| 867 | self.args = fn.args |
| 868 | self.arg_names = [arg.name for arg in self.args] |
| 869 | self.ret_type = fn.ret_type |
| 870 | |
| 871 | def wrapper_name(self) -> str: |
| 872 | """Return the name of the wrapper function.""" |
| 873 | return "{}{}{}".format( |
| 874 | DUNDER_PREFIX, |
| 875 | self.target_name, |
| 876 | self.cl.name_prefix(self.emitter.names) if self.cl else "", |
| 877 | ) |
| 878 | |
| 879 | def use_goto(self) -> bool: |
| 880 | """Do we use a goto for error handling (instead of straight return)?""" |
| 881 | return bool(self.cleanups or self.traceback_code) |
| 882 | |
| 883 | def emit_header(self) -> None: |
| 884 | """Emit the function header of the wrapper implementation.""" |
| 885 | input_args = ", ".join(f"PyObject *obj_{arg}" for arg in self.arg_names) |
| 886 | self.emitter.emit_line( |
| 887 | "static PyObject *{name}({input_args}) {{".format( |
| 888 | name=self.wrapper_name(), input_args=input_args |
| 889 | ) |
| 890 | ) |
| 891 | |
| 892 | def emit_arg_processing( |
| 893 | self, error: ErrorHandler | None = None, raise_exception: bool = True |
| 894 | ) -> None: |
| 895 | """Emit validation and unboxing of arguments.""" |
| 896 | error = error or self.error() |
| 897 | bitmap_arg_index = 0 |
no outgoing calls
no test coverage detected
searching dependent graphs…