U
    9%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   U/var/www/html/Darija-Ai-API/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
   Zreflect_native_valuevaluer   cleanupr   Z
enable_nrtZnrtZdecrefr	   r   nativer   tyr   r   cleanup_arg&   s
    
z(_ArgManager.add_arg.<locals>.cleanup_argz	arg%d.err   )r
   Zto_native_valuer   if_unlikelyr	   Z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
   argmanZsave_threadthread_state)r   r	   r
   r*   r   r   r   r   P   s    z_GilManager.__init__c                 C   s   | j | j | j  d S r   )r
   Zrestore_threadr+   r*   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   r-   r.   r/   r0   Zcall_helperr1   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)r/   Zllvm_cpython_wrapper_namer   Zget_argument_typer   ZpyobjectllvmliteZirFunctionTypeFunctionr-   r   r    argsr2   Zget_python_apibuild_wrapper)
r   ZwrapnameZpyobjZwraptywrapperr	   closurer7   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   )Z
alloca_obj).0_r
   r   r   
<listcomp>   s     z/PyCallWrapper.build_wrapper.<locals>.<listcomp>z==zarg.end)Znoinline)attrsz# callwrapper: emit_cleanupz# callwrapper: emit_cleanup endT)Zlikely)(lenr/   ZargtypesrangeZunpack_tuplequalnameZicmp_unsignedr   typer   r   retZget_null_objectr    r!   get_envr   r   zip
isinstancer   ZOmittedr   r#   loadr1   r)   Z	call_convZcall_functionr.   restypedebug_printr$   Zif_thenZis_okZis_noneZreturn_none_simplified_return_typeZfrom_native_returnZraise_error)r   r
   r	   r:   r7   r;   r   ZobjsZparseokpredr   r   Zcleanup_managerZ	innerargsr"   r   valstatusretvalZrettyr   r?   r   r8   ~   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)Zreturn_pyobjectZ	debug_msg)r   Zget_env_namer/   Zdeclare_env_globalr-   rJ   Zget_env_bodyZemit_environment_sentryenv_nameZget_env_managerr0   )r   r
   r	   envnameZgvptrZenvptrZenv_bodyr   r   r   r   rG      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)r/   rK   rI   r   OptionalrE   )r   rK   r   r   r   rM      s    z%PyCallWrapper._simplified_return_typec                 C   s   t jr| j|d| d S )NzDEBUGJIT: {0})r   Z	DEBUG_JITr   rL   format)r   r	   msgr   r   r   rL      s    zPyCallWrapper.debug_printN)	r%   r&   r'   r   r<   r8   rG   rM   rL   r   r   r   r   r,   [   s   	Gr,   )Zllvmlite.irr   r   r4   Z
numba.corer   r   r   objectr   r)   r,   r   r   r   r   <module>   s
   C