B
      ›\Ô   ã               @   sD   d dl mZmZmZ d dlmZ d dlmZmZ G dd„ de	ƒZ
dS )é    )Úprint_functionÚabsolute_importÚdivision)Úir)ÚcgutilsÚtypesc               @   s    e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&S )'Ú
NRTContextzF
    An object providing access to NRT APIs in the lowering pass.
    c             C   s   || _ || _d S )N)Ú_contextÚ_enabled)ÚselfÚcontextZenabled© r   ú4lib/python3.7/site-packages/numba/runtime/context.pyÚ__init__   s    zNRTContext.__init__c             C   s   | j stdƒ‚d S )NzNRT required but not enabled)r
   ÚRuntimeError)r   r   r   r   Ú_require_nrt   s    zNRTContext._require_nrtc             C   sH   |   ¡  |j}t tjtjg¡}|j|dd}|j 	d¡ | 
||g¡S )zG
        Low-level allocate a new memory area of `size` bytes.
        ZNRT_Allocate)ÚnameÚnoalias)r   Úmoduler   ÚFunctionTyper   Ú	voidptr_tÚintp_tÚget_or_insert_functionÚreturn_valueÚadd_attributeÚcall)r   ÚbuilderÚsizeÚmodÚfntyÚfnr   r   r   Úallocate   s    zNRTContext.allocatec             C   s>   |   ¡  |j}t t ¡ tjg¡}|j|dd}| ||g¡S )zI
        Low-level free a memory area allocated with allocate().
        ZNRT_Free)r   )	r   r   r   r   ÚVoidTyper   r   r   r   )r   r   Úptrr   r   r    r   r   r   Úfree!   s
    zNRTContext.freec             C   sH   |   ¡  |j}t tjtjg¡}|j|dd}|j 	d¡ | 
||g¡S )z|
        Allocate a new MemInfo with a data payload of `size` bytes.

        A pointer to the MemInfo is returned.
        ZNRT_MemInfo_alloc_safe)r   r   )r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r    r   r   r   Úmeminfo_alloc,   s    zNRTContext.meminfo_allocc             C   sX   |   ¡  |j}t tjtjtjg¡}|j|dd}|j 	d¡ | 
||| |tj¡g¡S )NZNRT_MemInfo_alloc_dtor_safe)r   r   )r   r   r   r   r   r   r   r   r   r   r   Zbitcast)r   r   r   Údtorr   r   r    r   r   r   Úmeminfo_alloc_dtor:   s    zNRTContext.meminfo_alloc_dtorc             C   s„   |   ¡  |j}t d¡}t tjtj|g¡}|j|dd}|j	 
d¡ t|tƒrb| j tj|¡}n|j|ksttdƒ‚| |||g¡S )zÿ
        Allocate a new MemInfo with an aligned data payload of `size` bytes.
        The data pointer is aligned to `align` bytes.  `align` can be either
        a Python int or a LLVM uint32 value.

        A pointer to the MemInfo is returned.
        é    ZNRT_MemInfo_alloc_safe_aligned)r   r   zalign must be a uint32)r   r   r   ZIntTyper   r   r   r   r   r   r   Ú
isinstanceÚintr	   Zget_constantr   Zuint32ÚtypeÚAssertionErrorr   )r   r   r   Zalignr   Úu32r   r    r   r   r   Úmeminfo_alloc_alignedF   s    

z NRTContext.meminfo_alloc_alignedc             C   sH   |   ¡  |j}t tjtjg¡}|j|dd}|j 	d¡ | 
||g¡S )a  
        Allocate a MemInfo pointing to a variable-sized data area.  The area
        is separately allocated (i.e. two allocations are made) so that
        re-allocating it doesn't change the MemInfo's address.

        A pointer to the MemInfo is returned.
        ZNRT_MemInfo_new_varsize)r   r   )r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r    r   r   r   Úmeminfo_new_varsize\   s    zNRTContext.meminfo_new_varsizec             C   sB   |   ¡  |j}t tjtjtjg¡}|j|dd}| |||g¡S )z
        Like meminfo_new_varsize() but also set the destructor for
        cleaning up references to objects inside the allocation.
        ZNRT_MemInfo_new_varsize_dtor)r   )	r   r   r   r   r   r   r   r   r   )r   r   r   r&   r   r   r    r   r   r   Úmeminfo_new_varsize_dtorl   s    
z#NRTContext.meminfo_new_varsize_dtorc             C   s   |   |||d¡S )a¾  
        Allocate a new data area for a MemInfo created by meminfo_new_varsize().
        The new data pointer is returned, for convenience.

        Contrary to realloc(), this always allocates a new area and doesn't
        copy the old data.  This is useful if resizing a container needs
        more than simply copying the data area (e.g. for hash tables).

        The old pointer will have to be freed with meminfo_varsize_free().
        ZNRT_MemInfo_varsize_alloc)Ú_call_varsize_alloc)r   r   Úmeminfor   r   r   r   Úmeminfo_varsize_allocz   s    
z NRTContext.meminfo_varsize_allocc             C   s   |   |||d¡S )z‡
        Reallocate a data area allocated by meminfo_new_varsize().
        The new data pointer is returned, for convenience.
        ZNRT_MemInfo_varsize_realloc)r1   )r   r   r2   r   r   r   r   Úmeminfo_varsize_reallocˆ   s    
z"NRTContext.meminfo_varsize_reallocc             C   sD   |   ¡  |j}t t ¡ tjtjg¡}|j|dd}| |||f¡S )z
        Free a memory area allocated for a NRT varsize object.
        Note this does *not* free the NRT object itself!
        ZNRT_MemInfo_varsize_free)r   )	r   r   r   r   r"   r   r   r   r   )r   r   r2   r#   r   r   r    r   r   r   Úmeminfo_varsize_free   s    
zNRTContext.meminfo_varsize_freec             C   sN   |   ¡  |j}t tjtjtjg¡}|j||d}|j 	d¡ | 
|||g¡S )N)r   r   )r   r   r   r   r   r   r   r   r   r   r   )r   r   r2   r   Úfuncnamer   r   r    r   r   r   r1      s    zNRTContext._call_varsize_allocc             C   s6   |   ¡  ddlm} |j}|j|dd}| ||g¡S )z¯
        Given a MemInfo pointer, return a pointer to the allocated data
        managed by it.  This works for MemInfos allocated with all the
        above methods.
        r   )Úmeminfo_data_tyZNRT_MemInfo_data_fast)r   )r   Únumba.runtime.nrtdynmodr7   r   r   r   )r   r   r2   r7   r   r    r   r   r   Úmeminfo_data§   s    zNRTContext.meminfo_datac             C   sr   | j j| }| |¡}g }| ¡ r<| ||¡}| ||f¡ x0|D ](\}}	|	|ƒ}
|  |||
¡}| |¡ qBW |S )zCReturn a list of *(type, meminfo)* inside the given value.
        )r	   Zdata_model_managerZtraverseZhas_nrt_meminfoZget_nrt_meminfoÚappendÚget_meminfosÚextend)r   r   ZtyÚvalZ	datamodelÚmembersÚmeminfosÚmiZmtypÚgetterZfieldZinner_meminfosr   r   r   r;   ¶   s    
zNRTContext.get_meminfosc             C   sz   |   ¡  ddlm} |  |||¡}xR|D ]J\}}|j}	|	j||d}
|
jd  d¡ |
jd  d¡ | |
|g¡ q(W dS )zGCall function of *funcname* on every meminfo found in *value*.
        r   )Úincref_decref_ty)r   r   Z	nocaptureN)	r   r8   rB   r;   r   r   Úargsr   r   )r   r   ÚtypÚvaluer6   rB   r?   Ú_r@   r   r    r   r   r   Ú_call_incref_decrefÇ   s    zNRTContext._call_incref_decrefc             C   s   |   |||d¡ dS )zG
        Recursively incref the given *value* and its members.
        Z
NRT_increfN)rG   )r   r   rD   rE   r   r   r   ÚincrefØ   s    zNRTContext.increfc             C   s   |   |||d¡ dS )zG
        Recursively decref the given *value* and its members.
        Z
NRT_decrefN)rG   )r   r   rD   rE   r   r   r   ÚdecrefÞ   s    zNRTContext.decrefN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r!   r$   r%   r'   r.   r/   r0   r3   r4   r5   r1   r9   r;   rG   rH   rI   r   r   r   r   r      s&   
r   N)Z
__future__r   r   r   Zllvmliter   Znumbar   r   Úobjectr   r   r   r   r   Ú<module>   s   