
    X-Ph                       d Z ddlmZ ddlmZ ddlmZmZmZm	Z	m
Z
mZmZ ddlmZmZmZ ddlmZmZmZmZmZ ddlmZmZmZmZmZmZ ddlmZ dd	l m!Z!m"Z"m#Z# dd
l$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z* ddl+m,Z, d^dZ-d_dZ.d`dZ/dadZ0dbdZ1dcd!Z2ddd#Z3d^d$Z4ddd%Z5ded(Z6ded)Z7ded*Z8dfd-Z9dfd.Z:dgd0Z;dhd2Z<did5Z=d6d7d8d9d:d;d<Z>djd=Z?ded>Z@ded?ZAded@ZBdedAZCdedBZDdedCZEdkdEZFdedFZG	 	 	 	 dldmdNZH	 dndOdPddQdod\ZI G d] d,          ZJdGS )pa  Generate CPython API wrapper functions for native functions.

The wrapper functions are used by the CPython runtime when calling
native functions from interpreted code, and when the called function
can't be determined statically in compiled code. They validate, match,
unbox and type check function arguments, and box return values as
needed. All wrappers accept and return 'PyObject *' (boxed) values.

The wrappers aren't used for most calls between two native functions
or methods in a single compilation unit.
    )annotations)Sequence)	ARG_NAMEDARG_NAMED_OPTARG_OPTARG_POSARG_STAR	ARG_STAR2ArgKind)op_methods_to_symbolsreverse_op_method_namesreverse_op_methods)AssignHandlerEmitterErrorHandlerGotoHandlerReturnHandler)BITMAP_BITSBITMAP_TYPEDUNDER_PREFIXNATIVE_PREFIXPREFIXbitmap_name)ClassIR)FUNC_STATICMETHODFuncIR
RuntimeArg)	RInstanceRTypeis_bool_rprimitiveis_int_rprimitiveis_object_rprimitiveobject_rprimitive)NameGeneratorfnr   namesr$   returnstrc                `    d                     t          |                     |                    S )zkReturn header of a vectorcall wrapper function.

    See comment above for a summary of the arguments.
    z`PyObject *{prefix}{name}(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames)prefixnameformatr   cnamer%   r&   s     Y/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/mypyc/codegen/emitwrapper.pywrapper_function_headerr2   ;   s(    	RfF%f112    emitterr   source_pathmodule_namec                    |                     d|          }d|                    dd          | j        p| j        | j        |fz  }|S )Nglobalsz%CPy_AddTraceback("%s", "%s", %d, %s);\z\\)static_namereplacetraceback_namer,   line)r%   r4   r5   r6   globals_statictraceback_codes         r1   generate_traceback_coder@   F   sY     ((K@@N<D&))
$RW
	@ N r3   argslist[RuntimeArg]dict[ArgKind, list[RuntimeArg]]c                *      fdt           D             S )zGroup arguments by kind.c                0    i | ]fd D             S )c                *    g | ]}|j         k    |S  )kind).0argks     r1   
<listcomp>z.make_arg_groups.<locals>.<dictcomp>.<listcomp>Z   s     555sx1}}}}}r3   rG   )rI   rK   rA   s    @r1   
<dictcomp>z#make_arg_groups.<locals>.<dictcomp>Z   s1    GGG!A5555t555GGGr3   )r   )rA   s   `r1   make_arg_groupsrN   X   s    GGGGwGGGGr3   groupsc                p    | t                    | t                   z   | t                   z   | t                   z   S )z@Reorder argument groups to match their order in a format string.)r   r   r   r   )rO   s    r1   reorder_arg_groupsrQ   ]   s)    '?VG_,vm/DDviGXXXr3   c                L    d                     d | D                       }d| dS )N c              3  ,   K   | ]}d |j          dV  dS )"z", Nr,   rI   rJ   s     r1   	<genexpr>z%make_static_kwlist.<locals>.<genexpr>c   s0      ::c)CH)))::::::r3   z&static const char * const kwlist[] = {z0};)join)rA   	arg_namess     r1   make_static_kwlistr[   b   s3    ::T:::::IDYDDDDr3   	func_name
str | Nonec                
   d}|t                    s|t                   r|dz  }|dt          |t                             z  z  }|t                   s|t
                   s|t                   r#|ddt          |t                             z  z   z  }|t
                   s|t                   r#|ddt          |t
                             z  z   z  }|t                   r#|ddt          |t                             z  z   z  }| |d|  z  }|S )	a  Return a format string that specifies the accepted arguments.

    The format string is an extended subset of what is supported by
    PyArg_ParseTupleAndKeywords(). Only the type 'O' is used, and we
    also support some extensions:

    - Required keyword-only arguments are introduced after '@'
    - If the function receives *args or **kwargs, we add a '%' prefix

    Each group requires the previous groups' delimiters to be present
    first.

    These are used by both vectorcall and legacy wrapper functions.
    rS   %O|$@N:)r	   r
   lenr   r   r   r   )r\   rO   r.   s      r1   make_format_stringrf   g   s    Fh 6), #
cCw((((Fg 3&/ 36)3D 3#c&/22222m 9y 1 9#c&"788888i 5#c&"344444/i//!Mr3   Nonec           
        |                     t          | |j                   d           t          | j                  }| j        j        r|d| j        j                  }| j        rH| j        j	        t          k    r3|                    d          }|                     d|j         d           t          |          }t          |          }|                     t          |                     t!          | j        |          }|                     d| d           |D ]9}|                     d                    |j        |j        rd	nd
                     :d |t&                   |t(                   z   D             }	g }
|t&                   s|t(                   r\|
|t&                   rd|t&                   d         j         ndgz  }
|
|t(                   rd|t(                   d         j         ndgz  }
|
d |D             z  }
| j        dk    rd}nd}d}|sd}n|t+          |          dk    r!t+          |t,                             dk    rd}nHt+          |          t+          |t,                             t+          |t.                             z   k    rd}|                    d                    ||d
                    d |
D                                 dd           t5          | j        j                  D ]1}t7          |          }|                     t8           d| d           2t;          | |||          }t=          | ||t.                   |t>                   z   |	|           |                     d           dS )zGenerate a CPython-compatible vectorcall wrapper for a native function.

    In particular, this handles unboxing the arguments, calling the native function, and
    then boxing the return value.
     {Nr   PyObject *obj_ = self;z static CPyArg_Parser parser = {"z", kwlist, 0};PyObject *obj_{}{}; = NULLrS   c                $    g | ]}d |j          dS zCPy_DECREF(obj_);rV   rW   s     r1   rL   z-generate_wrapper_function.<locals>.<listcomp>   &    ___3.#(...___r3   &obj_NULLc                "    g | ]}d |j          S rr   rV   rW   s     r1   rL   z-generate_wrapper_function.<locals>.<listcomp>   #    >>>###>>>r3   __call__zPyVectorcall_NARGS(nargs)nargsCPyArg_ParseStackAndKeywords"CPyArg_ParseStackAndKeywordsNoArgs   "CPyArg_ParseStackAndKeywordsOneArg"CPyArg_ParseStackAndKeywordsSimplez)if (!{}(args, {}, kwnames, &parser{})) {{c              3      K   | ]	}d |z   V  
dS , NrG   rI   ns     r1   rX   z,generate_wrapper_function.<locals>.<genexpr>   s&      $@$@!TAX$@$@$@$@$@$@r3   return NULL;}  = 0;cleanupsr?   ) 	emit_liner2   r&   listrA   signum_bitmap_args
class_namedeclrH   r   popr,   rN   rQ   r[   rf   r.   optionalr	   r
   re   r   r   
emit_linesrY   ranger   r   r@   generate_wrapper_corer   )r%   r4   r5   r6   	real_argsrJ   rO   reordered_argsfmtr   arg_ptrsrx   parse_fnir,   r?   s                   r1   generate_wrapper_functionr      s    0W]CCHHHIII RWI	v 97!7 778		} ?):::mmA=38===>>>
 Y''F'//N(88999
RWf
-
-CN#NNNOOO 
 
!((3T99RTUU	
 	
 	
 	
 `_&:JVT]M^:^___HHh [6), [6(;KW7VH-a05777QWXXF9<MY8VI.q16888SYZZ>>~>>>>H	w*+-H 87	Y1		VG_!5!5!:!:7	Y3vg//#fWo2F2FF	F	F73::eRWW$@$@x$@$@$@@@	
 	
 	   26)** 8 81~~[6646667777,R+{SSN
w&//%    cr3   c                `    d                     t          |                     |                    S )NzFPyObject *{prefix}{name}(PyObject *self, PyObject *args, PyObject *kw)r*   r-   r0   s     r1   legacy_wrapper_function_headerr      s/    SZZBHHUOO [   r3   c           
        |                     t          | |j                   d           t          | j                  }| j        j        r|d| j        j                  }| j        rH| j        j	        t          k    r3|                    d          }|                     d|j         d           t          |          }t          |          }|                     t          |                     |D ]9}|                     d                    |j        |j        rdnd                     :d	 |t$                   |t&                   z   D             }g }	|t$                   s|t&                   r\|	|t$                   rd
|t$                   d         j         ndgz  }	|	|t&                   rd
|t&                   d         j         ndgz  }	|	d |D             z  }	|                    d                    t+          d|          | j        d                    d |	D                                 dd           t/          | j        j                  D ]1}
t1          |
          }|                     t2           d| d           2t5          | |||          }t7          | ||t8                   |t:                   z   ||           |                     d           dS )zGenerates a CPython-compatible legacy wrapper for a native function.

    In particular, this handles unboxing the arguments, calling the native function, and
    then boxing the return value.
    ri   Nr   rj   rk   rl   rm   rS   c                $    g | ]}d |j          dS ro   rV   rW   s     r1   rL   z4generate_legacy_wrapper_function.<locals>.<listcomp>   rq   r3   rr   rs   c                "    g | ]}d |j          S ru   rV   rW   s     r1   rL   z4generate_legacy_wrapper_function.<locals>.<listcomp>  rv   r3   zEif (!CPyArg_ParseTupleAndKeywords(args, kw, "{}", "{}", kwlist{})) {{c              3      K   | ]	}d |z   V  
dS r   rG   r   s     r1   rX   z3generate_legacy_wrapper_function.<locals>.<genexpr>
  s&      >Z>ZAtax>Z>Z>Z>Z>Z>Zr3   r   r   r   r   r   )r   r   r&   r   rA   r   r   r   r   rH   r   r   r,   rN   rQ   r[   r.   r   r	   r
   r   rf   rY   r   r   r   r@   r   r   r   )r%   r4   r5   r6   r   rJ   rO   r   r   r   r   r,   r?   s                r1    generate_legacy_wrapper_functionr      s    7GMJJOOOPPP RWI	v 97!7 778		} ?):::mmA=38===>>>
 Y''F'//N(88999 
 
!((3T99RTUU	
 	
 	
 	
 `_&:JVT]M^:^___HHh [6), [6(;KW7VH-a05777QWXXF9<MY8VI.q16888SYZZ>>~>>>>HOVVtV,,bgrww>Z>ZQY>Z>Z>Z7Z7Z	
 	
 	   26)** 8 81~~[6646667777,R+{SSN
w&//%    cr3   clr   c                   t          | |          }|                    |           |                                 |                                 |                                 |                                 |                                S )zGenerates a wrapper for native __dunder__ methods to be able to fit into the mapping
    protocol slot. This specifically means that the arguments are taken as *PyObjects and returned
    as *PyObjects.
    )WrapperGenerator
set_targetemit_headeremit_arg_processing	emit_callfinishwrapper_namer   r%   r4   gens       r1   generate_dunder_wrapperr   !  ss    
 2w
'
'CNN2OOMMOOOJJLLLr3   c                   t          | |          }|                    |           t          |j                  dv s
J d            g d|_        |                                 |                                 t          |||ddg           |                                 |	                                 |
                                S )zGenerate a wrapper for native __ipow__.

    Since __ipow__ fills a ternary slot, but almost no one defines __ipow__ to take three
    arguments, the wrapper needs to tweaked to force it to accept three arguments.
    )      z*__ipow__ should only take 2 or 3 arguments)selfexpmodz[PyErr_SetString(PyExc_TypeError, "__ipow__ takes 2 positional arguments but 3 were given");r   if_unsupported)r   r   re   rA   rZ   r   r   handle_third_pow_argumentr   r   r   r   s       r1   generate_ipow_wrapperr   /  s     2w
'
'CNN2rw<<6!!!#O!!!***CMOO
i
	    MMOOOJJLLLr3   c                   t          | |          }|                    |           |j        dv r
g d|_        n	ddg|_        |                                }|                                 |j        t          vr |j        t          v rt          |||           nNt          |j                 }| 	                    |          }|t          |||           nt          | ||||           |S )a  Generates a wrapper for a native binary dunder method.

    The same wrapper that handles the forward method (e.g. __add__) also handles
    the corresponding reverse method (e.g. __radd__), if defined.

    Both arguments and the return value are PyObject *.
    __pow____rpow__)leftrightr   r   r   )r   r   r,   rZ   r   r   r   r   $generate_bin_op_reverse_only_wrapper
get_method$generate_bin_op_forward_only_wrappergenerate_bin_op_both_wrappers)r   r%   r4   r   r   rmethodfn_revs          r1   generate_bin_op_wrapperr   I  s     2w
'
'CNN2	w)))000)##%%LOO	w(((RW8O-O-O,R#>>>>$RW-w''>0WcBBBB *"b&'3GGGr3   r   r   c                ^   |                     t          d          d           t          | ||dg           |                    d           |                                 |                    d           t          | |t          | j                            |	                                 d S )NtypefailFerrorraise_exceptiongoto typefail;r   not_implemented_handler)
r   r   r   r   emit_error_handling
emit_label#generate_bin_op_reverse_dunder_callr   r,   r   r%   r4   r   s      r1   r   r   i  s     +j"9"95QQQb'3@P?QRRRRMM*:M;;;z"""  (G5G5PQQQJJLLLLLr3   c                ~   ddg|_         |                    t          d          d           t          | ||dg           |                                 |                                 |                    d           |                    d           |                    d	           |                                 d S )
Nr   r   r   Fr   r   r   Py_INCREF(Py_NotImplemented);return Py_NotImplemented;)	rZ   r   r   r   r   r   r   r   r   r   s      r1   r   r     s     f%CM+j"9"95QQQb'3@P?QRRRRMMOOOz"""56661222JJLLLLLr3   r   c                |   |                     d                    |                    |                                |                    t	          d          d           t          |||dg           |j        dk    rt          |j                  dk    rd}nd	}|	                    |
           |
                                 |                     d           |                    d           |                     d                    |                    |                                |                    |           ddg|_        |                    t	          d          d           t          |||dg           |	                                 |
                                 |                     d           t          |||j                   |                     d           |                    d           |                     d           |                     d           |                                 d S )Nz5if (PyObject_IsInstance(obj_left, (PyObject *){})) {{r   Fr   zgoto typefail2;r   r   r   r   r   r   z6if (PyObject_IsInstance(obj_right, (PyObject *){})) {{r   r   	typefail2} else {r   r   )r   r.   type_struct_namer   r   r   r,   re   rA   r   r   r   r   rZ   r   r   )r   r%   r   r4   r   fwd_not_implemented_handlers         r1   r   r     s?    ?FF$$R((	
 	
  
 +j"9"95QQQb'3@Q?RSSSS 
w)BG 1 1&7##&6#MM*EMFFFcz"""@GG$$R((	
 	
  
 NN6f%CM+k":":ERRRfgsDUCVWWWWMMOOOj!!!'GV[AAAc{###56661222JJLLLLLr3   r   c                   | j         dv r|                    d           |                    d| d           |                    d                    t          | j                  |                     | j         dv rV|                    d           |                    d           |                    d           |                    d	           d S d S )
Nr   zif (obj_mod == Py_None) {z_Py_IDENTIFIER(rp   zDreturn CPy_CallReverseOpMethod(obj_left, obj_right, "{}", &PyId_{});r   r   r   r   )r,   r   r.   r   )r%   r4   r   s      r1   r   r     s    	w)))56663333444NUU!"'*G	
 	
  
 
w)))*%%%9:::5666#	 *)r3   r   	list[str]c               f   | j         dvrd S | j         dv rt          | j                  dk    s| j         dk    rw|                    d           |D ]}|                    |           |                    d           t          |j                  dk    r|j                                         d S d S d S )N)r   r   __ipow__)r   r   r   r   zif (obj_mod != Py_None) {r   r   )r,   re   rA   r   rZ   r   )r%   r4   r   r   r=   s        r1   r   r     s     
w999
***s27||q/@/@RWPZEZEZ 	5666" 	$ 	$Dd#####
 s}""M F[EZ #"r3   Py_LTPy_GTPy_LEPy_GEPy_EQPy_NE)__lt____gt____le____ge____eq____ne__c                    t           fdt          D                       }|sdS t           d                     |j                   }|                    d                    |                     |                    d           |D ]h}|                    dt          |          d                                |          }|J t          ||d	d
g           |                    d           i|                    d           |                    d           |                    d           |                    d           |S )z3Generates a wrapper for richcompare dunder methods.c              3  F   K   | ]}                     |          |V  d S N)
has_method)rI   r,   r   s     r1   rX   z/generate_richcompare_wrapper.<locals>.<genexpr>  s4      MMdt9L9LMTMMMMMMr3   N_RichCompare_zHstatic PyObject *{name}(PyObject *obj_lhs, PyObject *obj_rhs, int op) {{rV   zswitch (op) {zcase z: {lhsrhs)rZ   r   r   r   )	sortedRICHCOMPARE_OPSr   name_prefixr&   r   r.   r   r   )r   r4   matchesr,   funcmethods   `     r1   generate_richcompare_wrapperr     sw    MMMMoMMMMMG tII"..*G*GIIDRYY 	Z 	
 	
  
 o&&&  =/$"7===>>>t$$!!!fg%HHHH#c56661222cKr3   c                p   t            |j         |                     |j                   }|                    d                    |                     |                    d           |                    dt           |                    |j                   d           |                    d           |S )z/Generates a wrapper for native __get__ methods.zOstatic PyObject *{name}(PyObject *self, PyObject *instance, PyObject *owner) {{rV   z)instance = instance ? instance : Py_None;return z(self, instance, owner);r   )r   r,   r   r&   r   r.   r   r/   r   r%   r4   r,   s       r1   generate_get_wrapperr     s    ERWEbnnW]&C&CEEDY`` 	a 	
 	
  
 ABBB``rxx/F/F```aaacKr3   c           
        t            |j         |                     |j                   }|                    d| d           |                    d                    |                    |j                  |                    |j	                  t          |                    |j                                       |                    d|j        d           t          |j                  r|                    d           n|                    d           |                    d|j                   |                    d           |                    d	           |                    d
           |                    d           |S )z0Generates a wrapper for native __hash__ methods.static Py_ssize_t (PyObject *self) {{}retval = {}{}{}(self);retval
return -1;-Py_ssize_t val = CPyTagged_AsSsize_t(retval);*Py_ssize_t val = PyLong_AsSsize_t(retval); if (PyErr_Occurred()) return -1;zif (val == -1) return -2;return val;r   r   r,   r   r&   r   r.   ctype_spacedret_typeget_group_prefixr   r   r/   emit_error_checkr!   emit_dec_refr   s       r1   generate_hash_wrapperr  "  sw   ERWEbnnW]&C&CEEDD4DDDEEE"))  --$$RW--HHW]##		
 	
   Xr{LAAA%% HIJJJJFGGG2;///89991222m$$$cKr3   c           
        t            |j         |                     |j                   }|                    d| d           |                    d                    |                    |j                  |                    |j	                  t          |                    |j                                       |                    d|j        d           t          |j                  r|                    d           n|                    d           |                    d|j                   |                    d           |                    d	           |                    d
           |S )z/Generates a wrapper for native __len__ methods.r   r   r   r   r   r  r  r  r  r   r  r   s       r1   generate_len_wrapperr  =  sb   ERWEbnnW]&C&CEEDD4DDDEEE"))  --$$RW--HHW]##		
 	
   Xr{LAAA%% HIJJJJFGGG2;///8999m$$$cKr3   c           	        t            |j         |                     |j                   }|                    d| d           |                    d                    |                    |j                  t          |	                    |j                                       |
                    d|j        d           t          |j                  s
J d            |                    d           |                    d           |S )	z0Generates a wrapper for native __bool__ methods.static int r   z{}val = {}{}(self);valr   z'Only bool return supported for __bool__r  r   )r   r,   r   r&   r   r.   r  r  r   r/   r	  r    r   s       r1   generate_bool_wrapperr  V  s   ERWEbnnW]&C&CEED=D===>>>$$  --}bhhw}>U>U	
 	
  
 UBK>>> bk**UU,UUUUm$$$cKr3   c                   d                     t          d|                     |j                            }d                    d |j        D                       }|                    d| d| d           t          |||j                   |S )zzGenerates a wrapper for native __delitem__.

    This is only called from a combined __delitem__/__setitem__ wrapper.
    {}{}{}__delitem__r   c              3  *   K   | ]}d |j          V  dS rj   NrV   rW   s     r1   rX   z,generate_del_item_wrapper.<locals>.<genexpr>p  s-      JJ36CH66JJJJJJr3   r  () {)r.   r   r   r&   rY   rA   r   #generate_set_del_item_wrapper_inner)r   r%   r4   r,   
input_argss        r1   generate_del_item_wrapperr  j  s    
 ??=-9V9VWWDJJ"'JJJJJJ;D;;:;;;<<<'GRW===Kr3   c           	        |                      d          }d}|r#|d         | k    rt          | |d         |          }|j        }|j        dk    r,t	          |          t          dt          t                    gz   }d                    t          d| 
                    |j                            }d                    d	 |D                       }|                    d
| d| d           |                    d|d         j         d           |6|                    d| d|d         j         d|d         j         d           n|                    d|d         j         d           |                    d           |                    d                    |d         j                             |                    d           |                    d           |                    d           |                    d           |                      d          }|r|d         | k    rt          |||           n$|                    d|d         j         d           |                    d           |                    d           |A| j        :d| j         d}|                    d| d           |                    d            n?|                    d!                    |d         j        |d         j                             |                    d           |                    d           |                    d           |                    d           |S )"a  Generates a wrapper for native __setitem__ method (also works for __delitem__).

    This is used with the mapping protocol slot. Arguments are taken as *PyObjects and we
    return a negative C int on error.

    Create a separate wrapper function for __delitem__ as needed and have the
    __setitem__ wrapper call it if the value is NULL. Return the name
    of the outer (__setitem__) wrapper.
    r  Nr{   r   ___valuer  __setitem__r   c              3  *   K   | ]}d |j          V  dS r  rV   rW   s     r1   rX   z0generate_set_del_item_wrapper.<locals>.<genexpr>  s-      GG36CH66GGGGGGr3   r  r  r  if (obj_r    == NULL) {r   z(obj_z, obj_rp   z4PyObject *super = CPy_Super(CPyModule_builtins, obj_zif (super == NULL) return -1;zJPyObject *result = PyObject_CallMethod(super, "__delitem__", "O", obj_{});zPy_DECREF(super);zPy_XDECREF(result);zreturn result == NULL ? -1 : 0;r   zPyObject *result;'z)' object does not support item assignmentz"PyErr_SetString(PyExc_TypeError, "z");zresult = NULL;zIresult = PyObject_CallMethod(super, "__setitem__", "OO", obj_{}, obj_{});)get_method_and_classr  rA   r,   r   r   r#   r   r.   r   r   r&   rY   r   r  builtin_base)	r   r%   r4   
method_clsdel_namerA   r,   r  msgs	            r1   generate_set_del_item_wrapperr(  v  s    ((77JH Ijmr)),RAHH7D	w-DzzZ
4EwOOPP??=-9V9VWWDGG$GGGGGJ;D;;:;;;<<< ;a;;;<<<WHWW47<WWtAw|WWWXXXX 	aQUVWQXQ]aaabbb9:::X__Q 	
 	
 	

 	-.../000;<<<c((77J jmr))+B>>>>aQUVWQXQ]aaabbb9:::-..."/"9HbgHHHCK3KKKLLL.//// [bbGL$q',   
 	-.../000;<<<#Kr3   Sequence[RuntimeArg]c           	     v   |D ]+}t          |j        |j        |t          d                     ,d                    d |D                       }|                    d                    |                    | j                  t          | 
                    |j                  |                     |                    d| j        d           |                    d| j                   |                    d           |                    d           |                    d           |                    d	           d S )
Nfailr   c              3  *   K   | ]}d |j          V  dS arg_NrV   rW   s     r1   rX   z6generate_set_del_item_wrapper_inner.<locals>.<genexpr>  s-      >>#-38-->>>>>>r3   z{}val = {}{}({});r  z
goto fail;z	return 0;r   r   )generate_arg_checkr,   typer   rY   r   r.   r  r  r   r/   r&   r	  r
  r   )r%   r4   rA   rJ   native_argss        r1   r  r    s5     M M38SXwF8K8KLLLL))>>>>>>>K""  --}bhhw}>U>UWb	
 	
  
 UBK>>>,,,k"""vl###cr3   c           	        t            |j         |                     |j                   }|                    d| d           t          d|j        d         j        |t          d                     |                    d	                    |
                    |j                  t          |                    |j                                       |                    d|j        d           t          |j                  r|                    d	           nE|                    d
           |                    d|j                   |                    d           |                    d           |S )z5Generates a wrapper for a native __contains__ method.r  z&(PyObject *self, PyObject *obj_item) {itemr{   z-1z{}val = {}{}(self, arg_item);r  r   r  z#int boolval = PyObject_IsTrue(val);zreturn boolval;r   )r   r,   r   r&   r   r/  rA   r0  r   r.   r  r  r   r/   r	  r    r
  r   s       r1   generate_contains_wrapperr4    s[   ERWEbnnW]&C&CEEDQDQQQRRRvrwqzt9L9LMMM'..  --}bhhw}>U>U	
 	
  
 UBK>>>"+&& --((((?@@@UBK000+,,,cKr3   Noptional_argslist[RuntimeArg] | NonerZ   list[str] | Noner   r?   c                x   t          d|          }|                    |            |r||_        |pg |_        |pg |_        |pd|_        |                                st          d          nt          d          }|	                    |           |
                                 |                                 dS )a?  Generates the core part of a wrapper function for a native function.

    This expects each argument as a PyObject * named obj_{arg} as a precondition.
    It converts the PyObject *s to the necessary types, checking and unboxing if necessary,
    makes the call, then boxes the result if necessary and returns it.
    NrS   rs   r+  )r   )r   r   rZ   r   r5  r?   use_gotor   r   r   r   r   )r%   r4   r5  rZ   r   r?   r   r   s           r1   r   r     s     4
)
)CNN2 "!>rCL%+C'-2C),PM&!!![=P=PE%(((MMOOOr3   FT)r   r   bitmap_arg_indexr,   typr   r   ErrorHandler | Noner   boolr   r:  intc          
        |pt                      }|j        r|j        r|r|                    |          }|                    |                    |           d|  d| d           |                    d|  d           t          |t          z            }|                    | d|t          dz
  z   d           |                    d|  d	|  |d
||d           |                    d           dS |                    d|  d	|  |d||d|           dS t          |          r|r|                    d|  d           |                    d|  d           |                    d	|  d|
                    |           d           |                    dd	|  d|  dd           dS |                    d|  d|  d           dS |                    d|  d	|  |d|||           dS )zInsert a runtime check for argument and unbox if necessary.

    The object is named PyObject *obj_{}. This is expected to generate
    a value of name arg_{} (unboxed if necessary). For each primitive a runtime
    check ensures the correct type.
    z arg_z = ;r   z != NULL) {z	 |= 1 << r{   obj_r.  FT)declare_destr   r   borrowr   )rB  r   r   rC  r   zPyObject *arg_r!  r   z = obj_z; )rB  r   r   r   N)r   
is_unboxederror_overlapc_undefined_valuer   ctyper   r   
emit_unboxr"   c_error_valuer   	emit_cast)	r,   r;  r4   r   r   r   r:  initbitmaps	            r1   r/  r/    s     $]__E
~ 0
 	 	,,S11Ds!3!3JJ$JJ4JJJKKK;;;;<<< !1[!@AAFYY2BkTUo2VYYYZZZtt" /     c""""" tt! /!  	 	 	 	 	 
c	"	" 
 	E6t666777;;;;<<<KTKKg.C.CC.H.HKKKLLLz+G$+G+Gt+G+G+GMMMMMCtCCDCCCDDDDD4MM4MM+ 	 	
 	
 	
 	
 	
r3   c                  h    e Zd ZdZddZddZd dZd!dZd"dZ	 d#d$dZ	d%d&dZ
d'dZd"dZd"dZdS )(r   z;Helper that simplifies the generation of wrapper functions.r   ClassIR | Noner4   r   r'   rg   c                L    || _         || _        g | _        g | _        d| _        d S )NrS   )r   r4   r   r5  r?   )r   r   r4   s      r1   __init__zWrapperGenerator.__init__M  s-    #%/1 r3   r%   r   c                (   |j         | _        |                    | j        j                  | _        |j        j        | _        | j        r|j        d| j                  | _        n|j        | _        d | j        D             | _	        |j
        | _
        dS )zSet the wrapped function.

        It's fine to modify the attributes initialized here later to customize
        the wrapper function.
        Nc                    g | ]	}|j         
S rG   rV   rW   s     r1   rL   z/WrapperGenerator.set_target.<locals>.<listcomp>a  s    888s#(888r3   )r,   target_namer/   r4   r&   target_cnamer   r   rA   rZ   r  )r   r%   s     r1   r   zWrapperGenerator.set_targetT  s     7HHT\%788!v5 	  74#7"7 78DIIDI88di888r3   r(   c                    d                     t          | j        | j        r$| j                            | j        j                  nd          S )z(Return the name of the wrapper function.r  rS   )r.   r   rS  r   r   r4   r&   r   s    r1   r   zWrapperGenerator.wrapper_named  sE    7;wFDG 2333B
 
 	
r3   r=  c                8    t          | j        p| j                  S )zADo we use a goto for error handling (instead of straight return)?)r=  r   r?   rV  s    r1   r9  zWrapperGenerator.use_gotol  s    DM8T%8999r3   c                    d                     d | j        D                       }| j                            d                    |                                 |                     dS )z7Emit the function header of the wrapper implementation.r   c              3      K   | ]	}d | V  
dS r  rG   rW   s     r1   rX   z/WrapperGenerator.emit_header.<locals>.<genexpr>r  s+      PP#555PPPPPPr3   z(static PyObject *{name}({input_args}) {{)r,   r  N)rY   rZ   r4   r   r.   r   )r   r  s     r1   r   zWrapperGenerator.emit_headerp  sq    YYPPPPPPP
6==&&((Z >  	
 	
 	
 	
 	
r3   NTr   r<  r   c           
         |p|                                  }d}t          | j        | j                  D ]Z\  }}|j        t
          t          fvr|j        nt          }|| j	        v }t          ||| j        ||||           |r|j        r|dz  }[dS )z*Emit validation and unboxing of arguments.r   )r   r   r:  r{   N)r   ziprZ   rA   rH   r	   r
   r0  r#   r5  r/  r4   rE  )r   r   r   r:  arg_namerJ   r;  r   s           r1   r   z$WrapperGenerator.emit_arg_processingy  s     % ;; 	& 	&MHc!hx.CCC#((IZCd00H /!!1     &C- & A% 	& 	&r3   rS   r   c                   d                     d | j        D                       }| j        rEd                     d t          t	          | j                            D                       }| d| }| j        }| j        }|j        s|                                 r|	                    d
                    |                    |          t          | j        |                      |j        | j          |j        r0|                    d|d           |                    dd|d	           |	                    d

                    |j        rdnd                     dS |rct%          |t&                    sN|	                    d
                    t          | j        |                     |                    d|dd           dS |	                    dt           | j         d| d           dS )zEmit call to the wrapper function.

        If not_implemented_handler is non-empty, use this C code to handle
        a NotImplemented return value (if it's possible based on the return type).
        r   c              3      K   | ]	}d | V  
dS r-  rG   rW   s     r1   rX   z-WrapperGenerator.emit_call.<locals>.<genexpr>  s(      GGsGGGGGGr3   c                ,    g | ]}t          |          S rG   )r   )rI   r   s     r1   rL   z.WrapperGenerator.emit_call.<locals>.<listcomp>  s    OOOAQOOOr3   z{}retval = {}{}({});r   r   retboxT)rB  z
return {};zPyObject *retbox = {}{}({});z"if (retbox == Py_NotImplemented) {r   zreturn retbox;r   r  rp   N)rY   rZ   r   reversedr   r  r4   rD  r9  r   r.   r  r   rT  r   r   r	  emit_box
isinstancer   )r   r   r1  bitmap_argsr  r4   s         r1   r   zWrapperGenerator.emit_call  s1    iiGGGGGGG 	:))OO%8L2M2M)N)NOOO K )99K99K=, 	`$--// 	` &--((22M4CTVa   
 G.." R((8^LLL  8XD QQQl11h>Q2_((W_``aaaaa& `z(I/N/N `!!299%t'8+   
 ""8+$	     !!"^M"^4;L"^"^{"^"^"^_____r3   r   c                Z    | j         s| j        rt          d          S t          d          S )z2Figure out how to deal with errors in the wrapper.r+  rs   )r   r?   r   r   rV  s    r1   r   zWrapperGenerator.error  s4    = 	)D/ 	)v&&& !(((r3   c                    | j         }|                                 r\|                    d            |j        | j          | j        r|                    | j                   |                    d           dS dS )z?Emit error handling block at the end of the wrapper, if needed.r+  r   N)r4   r9  r   r   r   r?   r   )r   r4   s     r1   r   z$WrapperGenerator.emit_error_handling  s    ,==?? 	.v&&&G.." 7!!$"5666n-----	. 	.r3   c                :    | j                             d           d S )Nr   )r4   r   rV  s    r1   r   zWrapperGenerator.finish  s    s#####r3   )r   rN  r4   r   r'   rg   )r%   r   r'   rg   )r'   r(   )r'   r=  )r'   rg   )NT)r   r<  r   r=  r'   rg   )rS   )r   r(   r'   rg   )r'   r   )__name__
__module____qualname____doc__rP  r   r   r9  r   r   r   r   r   r   rG   r3   r1   r   r   H  s        EE! ! ! !$ $ $ $ 
 
 
 
: : : :
 
 
 
 JN& & & & &,,` ,` ,` ,` ,`^) ) ) ). . . .$ $ $ $ $ $r3   )r%   r   r&   r$   r'   r(   )
r%   r   r4   r   r5   r(   r6   r(   r'   r(   )rA   rB   r'   rC   )rO   rC   r'   rB   )rA   rB   r'   r(   )r\   r]   rO   rC   r'   r(   )
r%   r   r4   r   r5   r(   r6   r(   r'   rg   )r   r   r%   r   r4   r   r'   r(   )r%   r   r4   r   r   r   r'   rg   )r   r   r%   r   r   r   r4   r   r   r   r'   rg   )r%   r   r4   r   r   r(   r'   rg   )
r%   r   r4   r   r   r   r   r   r'   rg   )r   r   r4   r   r'   r]   )r%   r   r4   r   rA   r)  r'   rg   )NNNN)r%   r   r4   r   r5  r6  rZ   r7  r   r7  r?   r]   r'   rg   r   )r,   r(   r;  r   r4   r   r   r<  r   r=  r   r=  r:  r>  r'   rg   )Krk  
__future__r   collections.abcr   
mypy.nodesr   r   r   r   r	   r
   r   mypy.operatorsr   r   r   mypyc.codegen.emitr   r   r   r   r   mypyc.commonr   r   r   r   r   r   mypyc.ir.class_irr   mypyc.ir.func_irr   r   r   mypyc.ir.rtypesr   r   r    r!   r"   r#   mypyc.namegenr$   r2   r@   rN   rQ   r[   rf   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r(  r  r4  r   r/  r   rG   r3   r1   <module>rv     sy  
 
 # " " " " " $ $ $ $ $ $ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ] ] ] ] ] ] ] ] ] ] _ _ _ _ _ _ _ _ _ _ _ _ _ _                & % % % % % B B B B B B B B B B                ( ' ' ' ' '*2 2 2 2   $H H H H
Y Y Y Y
E E E E
   <L L L Ln   9 9 9 9~      4   @   6   - - - -`   "       2     <      6   2   (	 	 	 	C C C CL   &   8 .2"&!%!%    @ "&	A
  A
 A
 A
 A
 A
 A
HJ$ J$ J$ J$ J$ J$ J$ J$ J$ J$r3   