o
    ØÝ2g ”  ã                   @  s4  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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- dzdd„Z.d{dd„Z/d|dd„Z0d}d d!„Z1d~d"d#„Z2dd&d'„Z3d€d)d*„Z4dzd+d,„Z5d€d-d.„Z6dd1d2„Z7dd3d4„Z8dd5d6„Z9d‚d9d:„Z:d‚d;d<„Z;dƒd>d?„Z<d„dAdB„Z=d…dEdF„Z>dGdHdIdJdKdLdMœZ?d†dNdO„Z@ddPdQ„ZAddRdS„ZBddTdU„ZCddVdW„ZDddXdY„ZEddZd[„ZFd‡d]d^„ZGdd_d`„ZH	a	a	a	adˆd‰dhdi„ZI	adŠdjdkddlœd‹dwdx„ZJG dyd8„ d8ƒZKdaS )Œa  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Úuse_vectorcall)ÚClassIR)ÚFUNC_STATICMETHODÚFuncIRÚ
RuntimeArg)Ú	RInstanceÚRTypeÚis_bool_rprimitiveÚis_int_rprimitiveÚis_object_rprimitiveÚobject_rprimitive)ÚNameGeneratorÚfnr   Únamesr$   ÚreturnÚstrc                 C  ó   dj t|  |¡d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&   © r1   úQ/home/garg/my-data/venv/lib/python3.10/site-packages/mypyc/codegen/emitwrapper.pyÚwrapper_function_header<   s   ýr3   Úemitterr   Úsource_pathÚmodule_namec                 C  s2   |  d|¡}d| dd¡| jp| j| j|f }|S )NÚglobalsz%CPy_AddTraceback("%s", "%s", %d, %s);ú\z\\)Ústatic_nameÚreplaceÚtraceback_namer,   Úline)r%   r4   r5   r6   Úglobals_staticÚtraceback_coder1   r1   r2   Úgenerate_traceback_codeG   s   

ür?   Úargsúlist[RuntimeArg]údict[ArgKind, list[RuntimeArg]]c                   s   ‡ fdd„t D ƒS )zGroup arguments by kind.c                   s    i | ]‰ ˆ ‡ fd d„ˆD ƒ“qS )c                   s   g | ]	}|j ˆ kr|‘qS r1   )Úkind©Ú.0Úarg©Úkr1   r2   Ú
<listcomp>[   ó    z.make_arg_groups.<locals>.<dictcomp>.<listcomp>r1   )rE   ©r@   rG   r2   Ú
<dictcomp>[   s     z#make_arg_groups.<locals>.<dictcomp>)r
   rK   r1   rK   r2   Úmake_arg_groupsY   s   rM   Úgroupsc                 C  s    | t  | t  | t  | t  S )z@Reorder argument groups to match their order in a format string.)r   r   r   r   )rN   r1   r1   r2   Úreorder_arg_groups^   s    rO   c                 C  s    d  dd„ | D ƒ¡}d|› dS )NÚ c                 s  s    | ]
}d |j › dV  qdS )ú"z", N©r,   rD   r1   r1   r2   Ú	<genexpr>d   ó   € z%make_static_kwlist.<locals>.<genexpr>z&static const char * const kwlist[] = {z0};)Újoin)r@   Ú	arg_namesr1   r1   r2   Úmake_static_kwlistc   s   rW   Ú	func_nameú
str | Nonec                 C  sÂ   d}|t  s
|t r|d7 }|dt|t ƒ 7 }|t s$|t s$|t r0|ddt|t ƒ  7 }|t s8|t rD|ddt|t ƒ  7 }|t rT|ddt|t ƒ  7 }| dur_|d| › 7 }|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.
    rP   ú%ÚOú|ú$ú@Nú:)r   r	   Úlenr   r   r   r   )rX   rN   r.   r1   r1   r2   Úmake_format_stringh   s   ra   ÚNonec              
   C  sb  |  t| |jƒ› d¡ t| jƒ}| jjr|d| jj … }| jr6| jj	t
kr6| d¡}|  d|j› d¡ t|ƒ}t|ƒ}|  t|ƒ¡ t| j|ƒ}|  d|› d¡ |D ]}|  d |j|jrcd	nd
¡¡ qVdd„ |t |t  D ƒ}	g }
|t s|t r¥|
|t rŽd|t d j› ndg7 }
|
|t r¡d|t d j› ndg7 }
|
dd„ |D ƒ7 }
| jdkr»t|jƒr»d}nd}d}|sÄd}n#t|ƒdkrÕt|t ƒdkrÕd}nt|ƒt|t ƒt|t ƒ krçd}| d ||d
 dd„ |
D ƒ¡¡dd¡ t| jjƒD ]}t|ƒ}|  t› d|› d¡ qt| |||ƒ}t | ||t |t!  |	|d |  d¡ dS ) zÈGenerate 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_{}{};ú = NULLrP   c                 S  ó   g | ]	}d |j › d‘qS ©zCPy_DECREF(obj_ú);rR   rD   r1   r1   r2   rI   ¨   rJ   z-generate_wrapper_function.<locals>.<listcomp>ú&obj_ÚNULLc                 S  ó   g | ]}d |j › ‘qS ©rk   rR   rD   r1   r1   r2   rI   ®   ó    Ú__call__zPyVectorcall_NARGS(nargs)ÚnargsÚCPyArg_ParseStackAndKeywordsÚ"CPyArg_ParseStackAndKeywordsNoArgsé   Ú"CPyArg_ParseStackAndKeywordsOneArgÚ"CPyArg_ParseStackAndKeywordsSimplez)if (!{}(args, {}, kwnames, &parser{})) {{c                 s  ó    | ]}d | V  qdS ©ú, Nr1   ©rE   Únr1   r1   r2   rS   Á   ó   € z,generate_wrapper_function.<locals>.<genexpr>úreturn NULL;Ú}ú ú = 0;©Úcleanupsr>   )"Ú	emit_liner3   r&   Úlistr@   ÚsigÚnum_bitmap_argsÚ
class_nameÚdeclrC   r   Úpopr,   rM   rO   rW   ra   r.   Úoptionalr   r	   r   Úcapi_versionr`   r   r   Ú
emit_linesrU   Úranger   r   r?   Úgenerate_wrapper_corer   )r%   r4   r5   r6   Ú	real_argsrF   rN   Úreordered_argsÚfmtr‚   Úarg_ptrsrq   Úparse_fnÚir,   r>   r1   r1   r2   Úgenerate_wrapper_function†   sf   

ÿ&& ÿûûr•   c                 C  r)   )NzFPyObject *{prefix}{name}(PyObject *self, PyObject *args, PyObject *kw)r*   r-   r0   r1   r1   r2   Úlegacy_wrapper_function_headerÝ   s   
ÿr–   c              
   C  sØ  |  t| |jƒ› d¡ t| jƒ}| jjr|d| jj … }| jr6| jj	t
kr6| d¡}|  d|j› d¡ t|ƒ}t|ƒ}|  t|ƒ¡ |D ]}|  d |j|jrTdnd¡¡ qGd	d
„ |t |t  D ƒ}g }	|t sp|t r–|	|t rd|t d j› ndg7 }	|	|t r’d|t d j› ndg7 }	|	dd
„ |D ƒ7 }	| d td|ƒ| jd dd„ |	D ƒ¡¡dd¡ t| jjƒD ]}
t|
ƒ}|  t› d|› d¡ q½t| |||ƒ}t| ||t |t  ||d |  d¡ dS )zÅGenerates 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.
    rc   Nr   rd   re   rf   rg   rP   c                 S  rh   ri   rR   rD   r1   r1   r2   rI     rJ   z4generate_legacy_wrapper_function.<locals>.<listcomp>rk   rl   c                 S  rm   rn   rR   rD   r1   r1   r2   rI     ro   zEif (!CPyArg_ParseTupleAndKeywords(args, kw, "{}", "{}", kwlist{})) {{c                 s  rw   rx   r1   rz   r1   r1   r2   rS     r|   z3generate_legacy_wrapper_function.<locals>.<genexpr>r}   r~   r   r€   r   )rƒ   r–   r&   r„   r@   r…   r†   r‡   rˆ   rC   r   r‰   r,   rM   rO   rW   r.   rŠ   r   r	   rŒ   ra   rU   r   r   r   r?   rŽ   r   r   )r%   r4   r5   r6   r   rF   rN   r   r‚   r’   r”   r,   r>   r1   r1   r2   Ú generate_legacy_wrapper_functionã   sN   

ÿ&&ÿûûr—   Úclr   c                 C  s<   t | |ƒ}| |¡ | ¡  | ¡  | ¡  | ¡  | ¡ S )zÏGenerates 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   Úgenr1   r1   r2   Úgenerate_dunder_wrapper"  s   

r¢   c                 C  sp   t | |ƒ}| |¡ t|jƒdv sJ dƒ‚g d¢|_| ¡  | ¡  t|||ddgd | ¡  | 	¡  | 
¡ S )zÚGenerate 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š   r`   r@   rV   r›   rœ   Úhandle_third_pow_argumentr   rž   rŸ   r    r1   r1   r2   Úgenerate_ipow_wrapper0  s"   


þü	r«   c                 C  s¨   t | |ƒ}| |¡ |jdv rg d¢|_nddg|_| ¡ }| ¡  |jtvr4|jtv r4t|||ƒ |S t|j }|  	|¡}|du rJt
|||ƒ |S 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°   N)r™   rš   r,   rV   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_revr1   r1   r2   Úgenerate_bin_op_wrapperJ  s"   





ø
ÿr·   r¡   r™   c                 C  s`   |j tdƒdd t| ||dgd |jd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¡   r1   r1   r2   r³   j  s   
r³   c                 C  sh   ddg|_ |jtdƒdd t| ||dgd | ¡  | ¡  | d¡ | d¡ | d	¡ | ¡  d S )
Nr°   r¯   r¸   Fr¹   r¼   r¨   úPy_INCREF(Py_NotImplemented);úreturn Py_NotImplemented;)	rV   rœ   r   rª   r   r¿   rÀ   rƒ   rž   rÂ   r1   r1   r2   r±   …  s   



r±   r¶   c                 C  s.  |  d | | ¡¡¡ |jtdƒdd t|||dgd |jdkr,t|jƒdkr,d}nd	}|j	|d
 | 
¡  |  d¡ | d¡ |  d | | ¡¡¡ | |¡ ddg|_|jtdƒdd t|||dgd | 	¡  | 
¡  |  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,   r`   r@   r   r¿   rÀ   rš   rV   rÁ   rž   )r˜   r%   r¶   r4   r¡   Úfwd_not_implemented_handlerr1   r1   r2   r´   “  s@   ÿÿ

ÿÿ






r´   rµ   c                 C  sx   | j dv r
| d¡ | d|› d¡ | d t| j  |¡¡ | j dv r:| d¡ | d¡ | d¡ | d	¡ d S d S )
Nr¬   zif (obj_mod == Py_None) {z_Py_IDENTIFIER(rj   zDreturn CPy_CallReverseOpMethod(obj_left, obj_right, "{}", &PyId_{});rÆ   rÃ   rÄ   r~   )r,   rƒ   r.   r   )r%   r4   rµ   r1   r1   r2   rÁ   Ã  s   


ÿÿ



ürÁ   r©   ú	list[str]c                C  s|   | j dvrd S | j dv rt| jƒdks| j dkr:| d¡ |D ]}| |¡ q| 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,   r`   r@   rƒ   rV   r‰   )r%   r4   r¡   r©   r<   r1   r1   r2   rª   Ô  s   
"

ñrª   ÚPy_LTÚPy_GTÚPy_LEÚPy_GEÚPy_EQÚPy_NE)Ú__lt__Ú__gt__Ú__le__Ú__ge__Ú__eq__Ú__ne__c                   sÎ   t ‡ fdd„tD ƒƒ}|sdS t› dˆ  |j¡› }| dj|d¡ | d¡ |D ]&}| dt| › d	¡ ˆ  |¡}|dusBJ ‚t||d
dgd | d¡ q*| d¡ | d¡ | d¡ | d¡ |S )z3Generates a wrapper for richcompare dunder methods.c                 3  s    | ]
}ˆ   |¡r|V  qd S ©N)Ú
has_method)rE   r,   ©r˜   r1   r2   rS   ù  rT   z/generate_richcompare_wrapper.<locals>.<genexpr>NÚ_RichCompare_zHstatic PyObject *{name}(PyObject *obj_lhs, PyObject *obj_rhs, int op) {{rR   zswitch (op) {zcase z: {ÚlhsÚrhs)rV   r~   rÃ   rÄ   )	ÚsortedÚRICHCOMPARE_OPSr   Úname_prefixr&   rƒ   r.   r²   rŽ   )r˜   r4   Úmatchesr,   ÚfuncÚmethodr1   rÙ   r2   Úgenerate_richcompare_wrapperö  s*   ÿÿ





rã   c                 C  sb   t › |j› |  |j¡› }| d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) {{rR   z)instance = instance ? instance : Py_None;úreturn z(self, instance, owner);r~   )r   r,   rß   r&   rƒ   r.   r   r/   ©r˜   r%   r4   r,   r1   r1   r2   Úgenerate_get_wrapper  s   ÿÿ

ræ   c              
   C  sÄ   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å   r1   r1   r2   Úgenerate_hash_wrapper#  s(   


üÿ





rö   c              
   C  sº   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å   r1   r1   r2   Úgenerate_len_wrapper>  s&   


üÿ




r÷   c              	   C  sŠ   t › |j› |  |j¡› }| d|› d¡ | d | |j¡t| 	|j¡¡¡ | 
d|jd¡ t|jƒs9J 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å   r1   r1   r2   Úgenerate_bool_wrapperW  s   ÿÿ

rú   c                 C  sV   d  td|  |j¡¡}d 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__ry   c                 s  ó    | ]	}d |j › V  qdS ©rd   NrR   rD   r1   r1   r2   rS   q  ó   € z,generate_del_item_wrapper.<locals>.<genexpr>rø   ú(ú) {)r.   r   rß   r&   rU   r@   rƒ   Ú#generate_set_del_item_wrapper_inner)r˜   r%   r4   r,   Ú
input_argsr1   r1   r2   Úgenerate_del_item_wrapperk  s
   r  c           	   	   C  s   |   d¡}d}|r|d | krt| |d |ƒ}|j}|jdkr*t|ƒtdttƒg }d t	d|  
|j¡¡}d d	d
„ |D ƒ¡}| d|› d|› d¡ | d|d j› d¡ |durq| 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|||ƒ |S | d|d j› d¡ | d¡ | d¡ |du rë| jdu rë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ü   Nrt   r   Ú___valuerû   Ú__setitem__ry   c                 s  rý   rþ   rR   rD   r1   r1   r2   rS     rÿ   z0generate_set_del_item_wrapper.<locals>.<genexpr>rø   r   r  úif (obj_r£   ú == NULL) {rä   z(obj_z, obj_rj   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  r@   r,   r„   r   r#   r   r.   r   rß   r&   rU   rƒ   r  Úbuiltin_base)	r˜   r%   r4   Ú
method_clsÚdel_namer@   r,   r  Úmsgr1   r1   r2   Úgenerate_set_del_item_wrapperw  sZ   


,
ÿÿ




í

ÿÿ



r  úSequence[RuntimeArg]c              	   C  s¤   |D ]}t |j|j|tdƒƒ qd dd„ |D ƒ¡}| d | | j¡t	|  
|j¡|¡¡ | d| jd¡ | d| j¡ | d¡ | d¡ | d	¡ | d
¡ d S )NÚfailry   c                 s  rý   ©Úarg_NrR   rD   r1   r1   r2   rS   Â  rÿ   z6generate_set_del_item_wrapper_inner.<locals>.<genexpr>z{}val = {}{}({});rù   z
goto fail;z	return 0;rë   r~   )Úgenerate_arg_checkr,   Útyper   rU   rƒ   r.   rñ   rò   r   r/   r&   rô   rõ   rÀ   )r%   r4   r@   rF   Únative_argsr1   r1   r2   r  ½  s   ÿÿ


r  c              	   C  sÀ   t › |j› |  |j¡› }| d|› d¡ td|jd j|tdƒƒ | d 	| 
|j¡t| |j¡¡¡ | d|jd¡ t|jƒrH| d	¡ n| d
¡ | d|j¡ | d¡ | d¡ |S )z5Generates a wrapper for a native __contains__ method.rø   z&(PyObject *self, PyObject *obj_item) {Úitemrt   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  r@   r  r   r.   rñ   rò   r   r/   rô   r    rõ   rå   r1   r1   r2   Úgenerate_contains_wrapperÐ  s    ÿÿ



r  NÚoptional_argsúlist[RuntimeArg] | NonerV   úlist[str] | Noner‚   r>   c                 C  st   t d|ƒ}| | ¡ |r||_|pg |_|pg |_|pd|_| ¡ s&tdƒntdƒ}|j	|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.
    NrP   rl   r  )rº   )r™   rš   rV   r‚   r  r>   Úuse_gotor   r   rœ   r   r¿   )r%   r4   r  rV   r‚   r>   r¡   rº   r1   r1   r2   rŽ   é  s   




rŽ   FT)rŠ   r»   Úbitmap_arg_indexr,   Útypr   rº   úErrorHandler | NonerŠ   Úboolr»   r  Úintc          	   
   C  s  |pt ƒ }|jro|jrZ|rZ| |¡}| | |¡› d| › d|› d¡ | d| › d¡ t|t ƒ}| |› d|td @ › d¡ |jd| › d	| › |d
||dd | d¡ dS |jd| › 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 |jd| › d	| › |d|||d dS )züInsert 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 << rt   Úobj_r  FT)Údeclare_destr»   rº   Úborrowr~   )r$  r»   rº   r%  rŠ   zPyObject *arg_r  rÆ   z = obj_z; )r$  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Úbitmapr1   r1   r2   r    sX   


"ù	
ø
 
ùr  c                   @  sz   e Zd ZdZd(dd	„Zd)dd„Zd*dd„Zd+dd„Zd,dd„Z	d-d.dd„Z	d/d0dd „Z
d1d"d#„Zd,d$d%„Zd,d&d'„ZdS )2r™   z;Helper that simplifies the generation of wrapper functions.r˜   úClassIR | Noner4   r   r'   rb   c                 C  s"   || _ || _g | _g | _d| _d S )NrP   )r˜   r4   r‚   r  r>   )r¥   r˜   r4   r1   r1   r2   Ú__init__N  s
   
zWrapperGenerator.__init__r%   r   c                 C  sd   |j | _| | jj¡| _|jj| _| jr|jd| j … | _n|j| _d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                 S  s   g | ]}|j ‘qS r1   rR   rD   r1   r1   r2   rI   b  s    z/WrapperGenerator.set_target.<locals>.<listcomp>)r,   Útarget_namer/   r4   r&   Útarget_cnamer…   r†   r@   rV   rò   )r¥   r%   r1   r1   r2   rš   U  s   
zWrapperGenerator.set_targetr(   c                 C  s(   d  t| j| jr| j | jj¡¡S d¡S )z(Return the name of the wrapper function.rû   rP   )r.   r   r1  r˜   rß   r4   r&   ©r¥   r1   r1   r2   rŸ   e  s   ýýzWrapperGenerator.wrapper_namer   c                 C  s   t | jp| jƒS )zADo we use a goto for error handling (instead of straight return)?)r   r‚   r>   r3  r1   r1   r2   r  m  s   zWrapperGenerator.use_gotoc                 C  s4   d  dd„ | jD ƒ¡}| j dj|  ¡ |d¡ dS )z7Emit the function header of the wrapper implementation.ry   c                 s  ó    | ]}d |› V  qdS rþ   r1   rD   r1   r1   r2   rS   s  ó   € z/WrapperGenerator.emit_header.<locals>.<genexpr>z(static PyObject *{name}({input_args}) {{)r,   r  N)rU   rV   r4   rƒ   r.   rŸ   )r¥   r  r1   r1   r2   r›   q  s   ÿÿzWrapperGenerator.emit_headerNTrº   r  r»   c              
   C  sx   |p|   ¡ }d}t| j| jƒD ]*\}}|jttfvr|jnt}|| j	v }t
||| j||||d |r9|jr9|d7 }qdS )z*Emit validation and unboxing of arguments.r   )r»   rŠ   r  rt   N)rº   ÚziprV   r@   rC   r   r	   r  r#   r  r  r4   r'  )r¥   rº   r»   r  Úarg_namerF   r  rŠ   r1   r1   r2   rœ   z  s$   
ù
	€òz$WrapperGenerator.emit_arg_processingrP   r¾   c                 C  s*  d  dd„ | jD ƒ¡}| jr$d  dd„ tt| jƒƒD ƒ¡}|› d|› }| j}| j}|js1|  ¡ rh| 	d 
| |¡t| j|¡¡ |j| jŽ  |jrY| d|d¡ |jdd	|d
d | 	d 
|jrbd	nd¡¡ dS |r„t|tƒs„| 	d 
t| j|¡¡ | d|dd¡ dS | 	dt› | j› d|› d¡ dS )zÊEmit 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).
        ry   c                 s  r4  r  r1   rD   r1   r1   r2   rS   –  r5  z-WrapperGenerator.emit_call.<locals>.<genexpr>c                 S  s   g | ]}t |ƒ‘qS r1   )r   )rE   r”   r1   r1   r2   rI   ™  s    z.WrapperGenerator.emit_call.<locals>.<listcomp>z{}retval = {}{}({});rê   r}   ÚretboxT)r$  z
return {};zPyObject *retbox = {}{}({});z"if (retbox == Py_NotImplemented) {r~   zreturn retbox;rä   r   rj   N)rU   rV   r†   Úreversedr   rò   r4   r&  r  rƒ   r.   rñ   r   r2  rŒ   r‚   rô   Úemit_boxÚ
isinstancer   )r¥   r¾   r  Úbitmap_argsrò   r4   r1   r1   r2   r     s@   ÿÿÿÿÿü"zWrapperGenerator.emit_callr   c                 C  s   | j s| jr
tdƒS tdƒS )z2Figure out how to deal with errors in the wrapper.r  rl   )r‚   r>   r   r   r3  r1   r1   r2   rº   ¿  s   zWrapperGenerator.errorc                 C  sH   | 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   r  rÀ   rŒ   r‚   r>   rƒ   )r¥   r4   r1   r1   r2   r¿   È  s   
ûz$WrapperGenerator.emit_error_handlingc                 C  s   | j  d¡ d S )Nr~   )r4   rƒ   r3  r1   r1   r2   rž   Ò  s   zWrapperGenerator.finish)r˜   r/  r4   r   r'   rb   )r%   r   r'   rb   )r'   r(   )r'   r   )r'   rb   )NT)rº   r  r»   r   r'   rb   )rP   )r¾   r(   r'   rb   )r'   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r0  rš   rŸ   r  r›   rœ   r   rº   r¿   rž   r1   r1   r1   r2   r™   I  s    





ÿ
/
	
)r%   r   r&   r$   r'   r(   )
r%   r   r4   r   r5   r(   r6   r(   r'   r(   )r@   rA   r'   rB   )rN   rB   r'   rA   )r@   rA   r'   r(   )rX   rY   rN   rB   r'   r(   )
r%   r   r4   r   r5   r(   r6   r(   r'   rb   )r˜   r   r%   r   r4   r   r'   r(   )r%   r   r4   r   r¡   r™   r'   rb   )r˜   r   r%   r   r¶   r   r4   r   r¡   r™   r'   rb   )r%   r   r4   r   rµ   r(   r'   rb   )
r%   r   r4   r   r¡   r™   r©   rÉ   r'   rb   )r˜   r   r4   r   r'   rY   )r%   r   r4   r   r@   r  r'   rb   )NNNN)r%   r   r4   r   r  r  rV   r  r‚   r  r>   rY   r'   rb   r×   )r,   r(   r  r   r4   r   rº   r  rŠ   r   r»   r   r  r!  r'   rb   )Lr@  Ú
__future__r   Útypingr   Ú
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   r   Úmypyc.ir.class_irr   Úmypyc.ir.func_irr   r   r   Úmypyc.ir.rtypesr   r   r    r!   r"   r#   Úmypyc.namegenr$   r3   r?   rM   rO   rW   ra   r•   r–   r—   r¢   r«   r·   r³   r±   r´   rÁ   rª   rÞ   rã   ræ   rö   r÷   rú   r  r  r  r  rŽ   r  r™   r1   r1   r1   r2   Ú<module>   sp    $$	 







W

?


 


0
ú








F
ú üøD