B
     \                 @   s   d Z ddlmZmZmZ ddlZddlmZ ddlm	Z	m
Z
 ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ G dd deZG dd deZdS )z2
Implementation of compiled C callbacks (@cfunc).
    )print_functiondivisionabsolute_importN)ir   )utilscompiler)	NullCacheFunctionCache)_FunctionCompiler)registry)	signature)	to_ctypesc               @   s   e Zd Zdd ZdS )_CFuncCompilerc             C   s6   | dd | dd | dd |jr2td|S )NZno_cpython_wrapperTZ
no_compileZenable_pyobjectFz&object mode not allowed in C callbacks)setZforce_pyobjectNotImplementedError)selfflags r   .lib/python3.7/site-packages/numba/ccallback.py_customize_flags   s    z_CFuncCompiler._customize_flagsN)__name__
__module____qualname__r   r   r   r   r   r      s   r   c               @   s   e Zd ZdZejZejfddZ	dd Z
ejdd Zdd	 Zd
d Zedd Zedd Zejdd Zejdd Zdd Zedd Zdd ZdS )CFunczD
    A compiled C callback, as created by the @cfunc decorator.
    c             C   s   |\}}|d krt d|j| _t|d| j| _|| _|| _t|f| | _t|| j	|||d| _
d | _d | _t | _d| _d S )Nz(C callback needs an explicit return typer   )pipeline_classr   )	TypeErrorr   getattrr   __wrapped___pyfuncr   _sigr   _targetdescr	_compiler_wrapper_name_wrapper_addressr	   _cache_cache_hits)r   ZpyfuncsiglocalsZoptionsr   argsreturn_typer   r   r   __init__(   s    
zCFunc.__init__c             C   s   t | j| _d S )N)r
   r   r%   )r   r   r   r   enable_caching<   s    zCFunc.enable_cachingc             C   sj   | j | j| jj}|d kr6|  }| j | j| n|  jd7  _|j| _	|j
j| _| j	| j| _d S )Nr   )r%   Zload_overloadr    r!   target_context_compile_uncachedZsave_overloadr&   library_libraryfndescllvm_cfunc_wrapper_namer#   Zget_pointer_to_functionr$   )r   cresr   r   r   compile?   s    
zCFunc.compilec                s   | j }| j|j|j}|jr"t|j}|j}|	|j
}|j  fdd|jD } |j}t||}|||j}	t|	d}
|  |
||	j || |  |S )Nc                s   g | ]}  |qS r   )get_value_type).0ty)contextr   r   
<listcomp>[   s    z+CFunc._compile_uncached.<locals>.<listcomp>entry)r    r"   r4   r)   r*   Z
objectmodeAssertionErrorr1   r/   Zcreate_ir_moduleZunique_namer-   r5   r   FunctionTypeadd_functionr2   Z	IRBuilderZappend_basic_block_build_c_wrapperZadd_ir_modulefinalize)r   r'   r3   r1   r/   moduleZll_argtypesZll_return_typeZwraptyZwrapfnbuilderr   )r8   r   r.   M   s     

zCFunc._compile_uncachedc          	   C   s   | j }||}|j|j|j}|j||jj	}|j
|||j|j|\}	}
|j|	jddX | }|j|||	 ||jt| }||}|| || || W d Q R X ||
 d S )NF)Zlikely)r    Zget_python_apiZ	call_convZget_function_typer*   r)   r@   r=   r1   Zllvm_func_nameZcall_functionZif_thenZis_errorZ
gil_ensureZraise_errorZinsert_const_stringreprZstring_from_stringZerr_write_unraisableZdecrefZgil_releaseZret)r   r8   rA   r3   Zc_argsr'   ZpyapiZfntyfnZstatusoutZ	gil_stateZcstrZstrobjr   r   r   r>   i   s    



zCFunc._build_c_wrapperc             C   s   | j S )zG
        The process-wide symbol the C callback is exposed as.
        )r#   )r   r   r   r   native_name   s    zCFunc.native_namec             C   s   | j S )z0
        The address of the C callback.
        )r$   )r   r   r   r   address   s    zCFunc.addressc             C   s   ddl }| }|d| jS )zF
        A cffi function pointer representing the C callback.
        r   Nzvoid *)cffiZFFIcastrF   )r   rG   Zffir   r   r   rG      s    z
CFunc.cffic             C   s8   dd | j jD }t| j j}tj|f| }|| jS )zG
        A ctypes function object representing the C callback.
        c             S   s   g | ]}t |qS r   )r   )r6   r7   r   r   r   r9      s    z CFunc.ctypes.<locals>.<listcomp>)r    r)   r   r*   ctypesZ	CFUNCTYPErF   )r   Zctypes_argsZctypes_restypeZfunctyper   r   r   rI      s    zCFunc.ctypesc             C   s
   | j  S )zB
        Return the LLVM IR of the C callback definition.
        )r0   Zget_llvm_str)r   r   r   r   inspect_llvm   s    zCFunc.inspect_llvmc             C   s   | j S )N)r&   )r   r   r   r   
cache_hits   s    zCFunc.cache_hitsc             C   s   d| j f S )Nz<Numba C callback %r>)r   )r   r   r   r   __repr__   s    zCFunc.__repr__N)r   r   r   __doc__r   Z
cpu_targetr!   r   ZPipeliner+   r,   Zglobal_compiler_lockr4   r.   r>   propertyrE   rF   r   Zcached_propertyrG   rI   rJ   rK   rL   r   r   r   r   r   "   s   	
r   )rM   Z
__future__r   r   r   rI   Zllvmliter    r   r   Zcachingr	   r
   Z
dispatcherr   Ztargetsr   typingr   Ztyping.ctypes_utilsr   r   objectr   r   r   r   r   <module>   s   