U
    ú¾|e!  ã                   @   s`   d dl mZmZ d dl Zd dlmZmZmZ G dd„ deƒZ	G dd„ deƒZ
G dd	„ d	eƒZdS )
é    )ÚConstantÚ	IRBuilderN)ÚtypesÚconfigÚcgutilsc                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	Ú_ArgManagerzA
    A utility class to handle argument unboxing and cleanup
    c                 C   s.   || _ || _|| _|| _d| _g | _|| _d S )Nr   )ÚcontextÚbuilderÚapiÚenv_managerÚ	arg_countÚcleanupsÚnextblk)Úselfr   r	   r
   r   ÚendblkÚnargs© r   úS/var/www/website-v5/atlas_env/lib/python3.8/site-packages/numba/core/callwrapper.pyÚ__init__   s    z_ArgManager.__init__c              	      s¬   ˆj  ˆ|¡‰ t ˆjˆ j¡� ˆj ˆj¡ W 5 Q R X ‡ ‡‡fdd„}ˆj 	|¡ ˆj 
dˆj ¡}ˆj |¡� |ƒ  ˆj ˆj¡ W 5 Q R X |ˆ_ˆ jd7  _ˆ jS )ak  
        Unbox argument and emit code that handles any error during unboxing.
        Args are cleaned up in reverse order of the parameter list, and
        cleanup begins as soon as unboxing of any argument fails. E.g. failure
        on arg2 will result in control flow going through:

            arg2.err -> arg1.err -> arg0.err -> arg.end (returns)
        c                      sH   ˆj  ˆˆ jˆj¡ ˆ jd k	r&ˆ  ¡  ˆjjrDˆjj ˆj	ˆˆ j¡ d S ©N)
r
   Úreflect_native_valueÚvaluer   Úcleanupr   Ú
enable_nrtÚnrtÚdecrefr	   r   ©Únativer   Útyr   r   Úcleanup_arg&   s
    
z(_ArgManager.add_arg.<locals>.cleanup_argz	arg%d.erré   )r
   Úto_native_valuer   Úif_unlikelyr	   Úis_errorÚbranchr   r   ÚappendÚappend_basic_blockr   Ú
goto_blockr   )r   Úobjr   r   Z
cleanupblkr   r   r   Úadd_arg   s    
ÿz_ArgManager.add_argc                 C   s   | j D ]
}|ƒ  qdS )zR
        Emit the cleanup code after returning from the wrapped function.
        N)r   )r   Zdtorr   r   r   Úemit_cleanupB   s    
z_ArgManager.emit_cleanupN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r)   r*   r   r   r   r   r      s   	.r   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú_GilManagerzY
    A utility class to handle releasing the GIL and then re-acquiring it
    again.
    c                 C   s    || _ || _|| _| ¡ | _d S r   )r	   r
   ÚargmanÚsave_threadÚthread_state)r   r	   r
   r0   r   r   r   r   P   s    z_GilManager.__init__c                 C   s   | j  | j¡ | j ¡  d S r   )r
   Úrestore_threadr2   r0   r*   )r   r   r   r   r*   V   s    z_GilManager.emit_cleanupN)r+   r,   r-   r.   r   r*   r   r   r   r   r/   J   s   r/   c                   @   s<   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )ÚPyCallWrapperc                 C   s(   || _ || _|| _|| _|| _|| _d S r   )r   ÚmoduleÚfuncÚfndescÚenvÚrelease_gil)r   r   r5   r6   r7   r8   Úcall_helperr9   r   r   r   r   \   s    zPyCallWrapper.__init__c           
      C   s�   | j j}| j tj¡}tj ||||g¡}tjj	| j
||d�}t| d¡ƒ}|j\}}}d|_d|_d|_| j |¡}	|  |	||||¡ ||	fS )N)ÚnameÚentryZ
py_closureZpy_argsZpy_kws)r7   Úllvm_cpython_wrapper_namer   Úget_argument_typer   ÚpyobjectÚllvmliteÚirÚFunctionTypeÚFunctionr5   r   r&   Úargsr;   Úget_python_apiÚbuild_wrapper)
r   ZwrapnameÚpyobjÚwraptyÚwrapperr	   ÚclosurerD   Úkwsr
   r   r   r   Úbuilde   s    zPyCallWrapper.buildc              
      sò  t | jjƒ}‡ fdd„t|ƒD ƒ}ˆ j|| jj||f|žŽ }| d|t|jd ƒ¡}	t	 
||	¡� | ˆ  ¡ ¡ W 5 Q R X | d¡}
| |
¡� | ˆ  ¡ ¡ W 5 Q R X |  ˆ |¡}t| j|ˆ ||
|ƒ}g }t|| jjƒD ]<\}}t|tjƒrø| d ¡ qØ| | |¡|¡}| |¡ qØ| j�r*t|ˆ |ƒ}| jjj|| j| jj| jj|dd�\}}|  |d¡ |  ¡  |  |d¡ |j!|j"d	d
��F | !|j#¡� ˆ  $¡  W 5 Q R X |  %¡ }ˆ  &|||¡}| |¡ W 5 Q R X | jj '|ˆ |¡ | ˆ  ¡ ¡ d S )Nc                    s   g | ]}ˆ   ¡ ‘qS r   )Ú
alloca_obj)Ú.0Ú_©r
   r   r   Ú
<listcomp>�   s     z/PyCallWrapper.build_wrapper.<locals>.<listcomp>z==zarg.end)Únoinline)Úattrsz# callwrapper: emit_cleanupz# callwrapper: emit_cleanup endT)Úlikely)(Úlenr7   ÚargtypesÚrangeÚunpack_tupleÚqualnameÚicmp_unsignedr   Útyper   r"   ÚretÚget_null_objectr&   r'   Úget_envr   r   ÚzipÚ
isinstancer   ÚOmittedr%   r)   Úloadr9   r/   Ú	call_convÚcall_functionr6   ÚrestypeÚdebug_printr*   Úif_thenÚis_okÚis_noneÚreturn_noneÚ_simplified_return_typeÚfrom_native_returnÚraise_error)r   r
   r	   rJ   rD   rK   r   ÚobjsZparseokÚpredr   r   Zcleanup_managerZ	innerargsr(   r   ÚvalÚstatusÚretvalÚrettyr   rP   r   rF   ~   sf     ÿÿ
ý

  ÿ    þ
zPyCallWrapper.build_wrapperc                 C   s^   | j  | j¡}| j  |j|¡}| |¡}| j  ||¡}|j|d| jjd� | 	| j
||¡}|S )zpGet the Environment object which is declared as a global
        in the module of the wrapped function.
        T)Úreturn_pyobjectÚ	debug_msg)r   Úget_env_namer7   Údeclare_env_globalr5   rb   Úget_env_bodyÚemit_environment_sentryÚenv_nameÚget_env_managerr8   )r   r
   r	   ÚenvnameZgvptrÚenvptrÚenv_bodyr   r   r   r   r^   Å   s    
ÿzPyCallWrapper.get_envc                 C   s"   | j j}t|tjƒr|jS |S dS )z…
        The NPM callconv has already converted simplified optional types.
        We can simply use the value type from it.
        N)r7   re   r`   r   ÚOptionalr[   )r   re   r   r   r   rk   Ô   s    z%PyCallWrapper._simplified_return_typec                 C   s   t jr| j |d |¡¡ d S )NzDEBUGJIT: {0})r   Ú	DEBUG_JITr   rf   Úformat)r   r	   Úmsgr   r   r   rf   à   s    zPyCallWrapper.debug_printN)	r+   r,   r-   r   rL   rF   r^   rk   rf   r   r   r   r   r4   [   s   	Gr4   )Úllvmlite.irr   r   r@   Ú
numba.corer   r   r   Úobjectr   r/   r4   r   r   r   r   Ú<module>   s
   C