U
    ?hB  ã                   @   sÈ   d Z ddlmZ ddlmZmZ ddlmZmZ e ej	¡Z
e e d¡¡Ze e
eeee
g¡Ze e ¡ eg¡Ze eeg¡Zdd„ Zdd	„ Zd
d„ ZdZdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )z%
Dynamically generate the NRT module
é    )Úconfig)ÚtypesÚcgutils)ÚirÚbindingé   c                 C   sX   t  | td¡}t | ¡ ¡}|j\}| |t 	¡ ¡}| 
t  ||dd¡¡}| |¡ dS )zt
    Implement NRT_MemInfo_data_fast in the module.  This allows LLVM
    to inline lookup of the data pointer.
    ZNRT_MemInfo_data_fastr   é   N)r   Úget_or_insert_functionÚmeminfo_data_tyr   Ú	IRBuilderÚappend_basic_blockÚargsÚbitcastÚ_meminfo_struct_typeÚ
as_pointerÚloadZgepÚret)ÚmoduleÚfnÚbuilderÚptrZ
struct_ptrZdata_ptr© r   úN/var/www/html/venv/lib/python3.8/site-packages/numba/core/runtime/nrtdynmod.pyÚ_define_nrt_meminfo_data   s    ÿr   c              	   C   s°   t  | td¡}|j d¡ t | ¡ ¡}|j\}| 	d|t  
|j¡¡}t  ||¡ | ¡  W 5 Q R X | ||jd j¡}tjr–t  |d| |¡|¡ | ||g¡ | ¡  dS )z,
    Implement NRT_incref in the module
    Z
NRT_increfÚnoinlineú==r   z*** NRT_Incref %zu [%p]
N)r   r	   Úincref_decref_tyÚ
attributesÚaddr   r   r   r   Úicmp_unsignedÚget_null_valueÚtypeÚif_unlikelyÚret_voidr   r   Ú	DEBUG_NRTÚprintfr   Úcall)r   Zatomic_incrZ	fn_increfr   r   Úis_nullÚword_ptrr   r   r   Ú_define_nrt_incref)   s     ÿÿr)   c           
   	   C   s   t  | td¡}|j d¡ tj| t t ¡ t	g¡dd}t 
| ¡ ¡}|j\}| d|t  |j¡¡}t  ||¡ | ¡  W 5 Q R X | d¡ | ||jd j¡}tjr¾t  |d| |¡|¡ | ||g¡}| d|t |jd¡¡}	t  ||	¡ | d	¡ | ||g¡ W 5 Q R X | ¡  d
S )z,
    Implement NRT_decref in the module
    Z
NRT_decrefr   ZNRT_MemInfo_call_dtor©Únamer   Úreleaser   z*** NRT_Decref %zu [%p]
ÚacquireN)r   r	   r   r   r   r   ÚFunctionÚFunctionTypeÚVoidTypeÚ_pointer_typer   r   r   r   r    r!   r"   r#   Zfencer   r   r$   r%   r   r&   ÚConstant)
r   Zatomic_decrZ	fn_decrefZcalldtorr   r   r'   r(   ZnewrefctZ
refct_eq_0r   r   r   Ú_define_nrt_decref?   s:    ÿþ
ÿÿÿ
r3   c                 C   s´   t  tt ¡ g¡}t j| |d |¡d}|j\}| ¡ }t  |¡}t  	td¡}t
s€|j||||d}	t||ƒ|	|ƒ}
| |
¡ n0| |¡}	t||ƒ|	|ƒ}| ||¡ | |	¡ |S )zâDefine a llvm function for atomic increment/decrement to the given module
    Argument ``op`` is the operation "add"/"sub".  Argument ``ordering`` is
    the memory ordering.  The generated function returns the new value.
    znrt_atomic_{0}r*   é   ©Úordering)r   r/   Ú
_word_typer   r.   Úformatr   r   r   r2   Ú_disable_atomicityZ
atomic_rmwÚgetattrr   r   Ústore)r   Úopr6   ÚftypeZ	fn_atomicr   Úbbr   ZONEZoldvalÚresZnewvalr   r   r   Ú_define_atomic_inc_deco   s    


r@   c                 C   sš   t  t  d¡t ¡ ttt ¡ g¡}t j| |dd}|j\}}}}| ¡ }t  |¡}	|	j	||||d}
t
 |	|
d¡\}}|	 ||¡ |	 |	 ||j¡¡ |S )a¨  Define a llvm function for atomic compare-and-swap.
    The generated function is a direct wrapper of the LLVM cmpxchg with the
    difference that the a int indicate success (1) or failure (0) is returned
    and the last argument is a output pointer for storing the old value.

    Note
    ----
    On failure, the generated function behaves like an atomic load.  The loaded
    value is stored to the last argument.
    é    Znrt_atomic_casr*   r5   é   )r   r/   ÚIntTyper7   r   r.   r   r   r   Zcmpxchgr   Zunpack_tupler;   r   ZzextÚreturn_type)r   r6   r=   Zfn_casr   ÚcmpÚreplZoldptrr>   r   ZouttupÚoldÚokr   r   r   Ú_define_atomic_casŠ   s     þ
rI   c                 C   sL   | j  tjd¡}tj||dd}| ¡ }t |¡}d}| j  |t	|f¡ |S )zÑ
    Defines an abort function due to unresolved symbol.

    The function takes no args and will always raise an exception.
    It should be safe to call this function with incorrect number of arguments.
    r   Znrt_unresolved_abortr*   z6numba jitted function aborted due to unresolved symbol)
Z	call_convZget_function_typer   Únoner   r.   r   r   Zreturn_user_excÚRuntimeError)Úctxr   Zfntyr   r>   r   Úmsgr   r   r   Ú_define_nrt_unresolved_abort¥   s    
rN   c                 C   sr   |   ¡ }| d¡}| d¡}t|ddd}t|ddd}t|dd t|ƒ t||ƒ t||ƒ t| |ƒ ||fS )zl
    Create an IR module defining the LLVM NRT functions.
    A (IR module, library) tuple is returned.
    ZnrtZ
nrt_moduler   Ú	monotonicr5   Úsub)	ÚcodegenZcreate_libraryZcreate_ir_moduler@   rI   r   r)   r3   rN   )rL   rQ   ÚlibraryÚir_modZ
atomic_incZ
atomic_decr   r   r   Úcreate_nrt_moduleµ   s    




rT   c                 C   s"   t | ƒ\}}| |¡ | ¡  |S )z‰
    Compile all LLVM NRT functions and return a library containing them.
    The library is created using the given target context.
    )rT   Zadd_ir_moduleÚfinalize)rL   rS   rR   r   r   r   Úcompile_nrt_functionsÍ   s    
rV   N)Ú__doc__Z
numba.corer   r   r   Zllvmliter   r   rC   ZMACHINE_BITSr7   ZPointerTyper1   ZLiteralStructTyper   r/   r0   r   r
   r   r)   r3   r9   r@   rI   rN   rT   rV   r   r   r   r   Ú<module>   s.   û	-