o
    8ήc}\                     @   sJ  d Z ddlmZ ddl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 edd	d
gZeddZedZeZdd ZedZedZedZedZdZeeZG dd deZG dd deZG dd deZeeeegZe eZ!G dd deZ"G dd deZ#G dd de#Z$G d d! d!e#Z%e$e%d"Z&d#d$ Z'dS )%z3
Calling conventions for Numba-compiled functions.
    )
namedtuple)IterableN)ir)typescgutils)PYOBJECTGENERIC_POINTER	TryStatusin_tryexcinfoStatus)codeis_okis_noneis_erroris_stop_iterationis_python_excis_user_exc
excinfoptr    c                 C   s   t t| S N)r   Constant	errcode_t)r    r   :/tmp/pip-target-vg8gfxp4/lib/python/numba/core/callconv.py
_const_int'   s   r      c                   @   sd   e 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S )BaseCallConvc                 C   
   || _ d S r   )context)selfr"   r   r   r   __init__9      
zBaseCallConv.__init__c                 C   s   |t jkr| | d S ||krL| jj|||d}t||j}|| | j	||j
|j}| || W d    n1 s@w   Y  | | d S t|t jss||j
krb| jj||||j
d}| j	||j
|}| || d S td||)N)value)fromtytotyzreturning {0} for {1})r   nonereturn_native_noner"   make_helperr   as_bool_bitvalidif_thenget_return_valuetypedatareturn_value
isinstanceOptionalcastNotImplementedErrorformat)r#   builderrettyvaltyr&   optvalvalidbitretvalr   r   r   return_optional_value<   s,   

z"BaseCallConv.return_optional_valuec                 C      |  |t d S r   )_return_errcode_rawRETCODE_NONEr#   r8   r   r   r   r*   Y      zBaseCallConv.return_native_nonec                 C   s   | j |tdd d S NTmark_exc)r@   RETCODE_EXCrB   r   r   r   
return_exc\   s   zBaseCallConv.return_excc                 C   r?   r   )r@   RETCODE_STOPITrB   r   r   r   return_stop_iteration_   rC   z"BaseCallConv.return_stop_iterationc                 C   s   | j j|  }| S )zQ
        Get the actual type of the return argument for Numba type *ty*.
        )r"   data_model_managerget_return_type
as_pointer)r#   tyrestyper   r   r   rL   b   s   zBaseCallConv.get_return_typec                 C   s   |  |}||_|S )zS
        Initialize and return a call helper object for the given builder.
        )_make_call_helper_BaseCallConv__call_helper)r#   r8   chr   r   r   init_call_helperi   s   
zBaseCallConv.init_call_helperc                 C   s   |j S r   )rQ   rB   r   r   r   _get_call_helperq      zBaseCallConv._get_call_helperc              	   C   s,  |j  }||j6 |  ||j}t|t	|| |
| W d   n1 s0w   Y  || W d   n1 sDw   Y  ||j |d || W d   n1 sdw   Y  ||j || W d   n1 sw   Y  |dd || || dS )zT
        Given a non-ok *status*, raise the corresponding Python exception.
        NPyExc_StopIterationPyExc_SystemErrorz*unknown error when calling native function)functionappend_basic_blockr.   r   	err_clearunserializer   r   	if_likelyis_not_nullraise_objectbranchr   err_set_noner   err_set_stringposition_at_end)r#   r8   apistatusbbendexcr   r   r   raise_errort   s.   




zBaseCallConv.raise_errorc                 C   s    |  |}| |}|||S )z
        Get the decoded (unpacked) Python arguments with *argtypes*
        from LLVM function *func*.  A tuple of LLVM values is returned.
        )get_arguments_get_arg_packerfrom_arguments)r#   r8   argtypesfuncraw_argsarginfor   r   r   decode_arguments   s   

zBaseCallConv.decode_argumentsc                 C   s   | j |S )zF
        Get an argument packer for the given argument types.
        )r"   get_arg_packer)r#   rk   r   r   r   ri      s   zBaseCallConv._get_arg_packerN)__name__
__module____qualname__r$   r>   r*   rH   rJ   rL   rS   rT   rg   ro   ri   r   r   r   r   r    7   s    	r    c                   @   sj   e Zd ZdZdd Zdd Z		dddZd	d
 ZdddZdd Z	dd Z
dddZdd Zdd ZdS )MinimalCallConva  
    A minimal calling convention, suitable for e.g. GPU targets.
    The implemented function signature is:

        retcode_t (<Python return type>*, ... <Python arguments>)

    The return code will be one of the RETCODE_* constants or a
    function-specific user exception id (>= RETCODE_USEREXC).

    Caller is responsible for allocating a slot for the return value
    (passed as a pointer in the first argument).
    c                 C   s   t  S r   )_MinimalCallHelperrB   r   r   r   rP      rU   z!MinimalCallConv._make_call_helperc                 C   sP   |j jd }|j|jjksJ t|jt|jjf||| | |t d S Nr   )rX   argsr0   pointeestrstorer@   
RETCODE_OKr#   r8   r=   retptrr   r   r   r2         zMinimalCallConv.return_valueNc           
      C   s   |d urt |tstd|f |d ur t|ts td|f |d ur<| }|d u r.|}||j|jf}d |v r;d }nd }| |}|	|||}	| j
|t|	dd d S )N-exc should be None or exception class, got %r(exc_args should be None or tuple, got %rTrE   )
issubclassBaseException	TypeErrorr3   tuple_raw_function_namefilenamelinerT   _add_exceptionr@   r   )
r#   r8   rf   exc_argsloc	func_namefnamelocinfocall_helperexc_idr   r   r   return_user_exc   s(   
zMinimalCallConv.return_user_excc                 C   s   |  ||j d S r   )r@   r   )r#   r8   rd   r   r   r   return_status_propagate   s   z'MinimalCallConv.return_status_propagateFc                 C   s    t |tr	t|}|| d S r   )r3   intr   ret)r#   r8   r   rF   r   r   r   r@      s   
z#MinimalCallConv._return_errcode_rawc              
   C   sx   | d|t}| d|t}|||}||}| d|t}| d|t}| d|t}	t||||||	|dd}
|
S )z?
        Given a return *code*, get a Status instance.
        ==>=Nr   r   r   r   r   r   r   r   )	icmp_signedr{   rA   or_not_rG   rI   RETCODE_USEREXCr   )r#   r8   r   normr)   okerrrf   r   r   rd   r   r   r   _get_return_status   s"   
z"MinimalCallConv._get_return_statusc                 C   s4   |  |}t|j}| |}tt|g| }|S zQ
        Get the implemented Function type for *restype* and *argtypes*.
        )ri   listargument_typesrL   r   FunctionTyper   r#   rO   rk   rn   resptrfntyr   r   r   get_function_type   s
   


z!MinimalCallConv.get_function_typec                 C   s>   |rJ |  |}|| |dd |D  d|jd _|S )zA
        Set names and attributes of function arguments.
        c                 S      g | ]}d | qS zarg.r   .0ar   r   r   
<listcomp>      z5MinimalCallConv.decorate_function.<locals>.<listcomp>z.retr   )ri   assign_namesrh   rw   name)r#   fnrw   fe_argtypesnoaliasrn   r   r   r   decorate_function   s   
z!MinimalCallConv.decorate_functionc                 C      |j dd S )@
        Get the Python-level arguments of LLVM *func*.
        r   Nrw   r#   rl   r   r   r   rh        zMinimalCallConv.get_argumentsc                 C   s   |j d jj}t||}|t|| | |}|||}|gt	| }	|
||	}
| ||
}||}| j|||}||fS )z3
        Call the Numba-compiled *callee*.
        r   )rw   r0   rx   r   alloca_oncerz   get_null_valueri   as_argumentsr   callr   loadr"   get_returned_value)r#   r8   calleerestyargtysrw   r9   	retvaltmprn   realargsr   rd   r=   outr   r   r   call_function  s   

zMinimalCallConv.call_functionNNNF)rq   rr   rs   __doc__rP   r2   r   r   r@   r   r   r   rh   r   r   r   r   r   rt      s    



rt   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ru   z
    A call helper object for the "minimal" calling convention.
    User exceptions are represented as integer codes and stored in
    a mapping for retrieval from the caller.
    c                 C   s
   i | _ d S r   )
exceptionsr#   r   r   r   r$   '  r%   z_MinimalCallHelper.__init__c                 C   s"   t | jt }|||f| j|< |S )aV  
        Add a new user exception to this helper. Returns an integer that can be
        used to refer to the added exception in future.

        Parameters
        ----------
        exc :
            exception type
        exc_args : None or tuple
            exception args
        locinfo : tuple
            location information
        )lenr   FIRST_USEREXC)r#   rf   r   r   r   r   r   r   r   *  s   z!_MinimalCallHelper._add_exceptionc                 C   s@   z| j | W S  ty   d| }t}|f}d}|||f Y S w )z
        Get information about a user exception. Returns a tuple of
        (exception type, exception args, location information).

        Parameters
        ----------
        id : integer
            The ID of the exception to look up
        z#unknown error %d in native functionN)r   KeyErrorSystemError)r#   r   msgrf   r   r   r   r   r   get_exception<  s   
z _MinimalCallHelper.get_exceptionN)rq   rr   rs   r   r$   r   r   r   r   r   r   ru      s
    ru   c                   @   s   e Zd ZdZedZdd Zdd Z		d'dd	Z			d'd
dZ
dd Zdd Zdd Zdd Zdd Zd(ddZdd Zdd Zd(ddZdd  Zd!d" Zd#d$ Z	d)d%d&ZdS )*CPUCallConva  
    The calling convention for CPU targets.
    The implemented function signature is:

        retcode_t (<Python return type>*, excinfo **, ... <Python arguments>)

    The return code will be one of the RETCODE_* constants.
    If RETCODE_USEREXC, the exception info pointer will be filled with
    a pointer to a constant struct describing the raised exception.

    Caller is responsible for allocating slots for the return value
    and the exception info pointer (passed as first and second arguments,
    respectively).
    r   c                 C   s   d S r   r   rB   r   r   r   rP   f  s   zCPUCallConv._make_call_helperc                 C   sP   |  |j}|j|jjksJ t|jt|jjf||| | |t d S r   )_get_return_argumentrX   r0   rx   ry   rz   r@   r{   r|   r   r   r   r2   i  r~   zCPUCallConv.return_valueNc                 C   s   |d urt |tstd|f |d ur t|ts td|f |d u r't }| j|}|d urI| }|d u r;|}||j|j	f}d |v rHd }nd }|||f}|
|}	| |j}
||	|
 d S )Nr   r   )r   r   r   r3   r   r"   get_python_apir   r   r   serialize_object_get_excinfo_argumentrX   rz   )r#   r8   rf   r   r   r   pyapir   r   	struct_gvexcptrr   r   r   set_static_user_excp  s0   

zCPUCallConv.set_static_user_excc                 C   sT   t |dd}| j|||||d | |}|r ||d  d S | j|tdd d S )N_in_try_blockF)r   r   r   targetTrE   )getattrr   check_try_statusr_   r@   r   )r#   r8   rf   r   r   r   try_info	trystatusr   r   r   r     s   

zCPUCallConv.return_user_excc              	   C   s:   z|j W S  ty   tj|tjddd}||_ | Y S w )N	try_stateT)r   zfill)_CPUCallConv__eh_try_stateAttributeErrorr   r   intp_t)r#   r8   ptrr   r   r   _get_try_state  s   
zCPUCallConv._get_try_statec                 C   sJ   |  |}||}|d||d}| |j}||}t||dS )N>r   )r
   r   )r   r   icmp_unsignedr0   r   rX   r	   )r#   r8   try_state_ptr	try_depthr
   r   r   r   r   r   r     s   


zCPUCallConv.check_try_statusc                 C   s6   |  |}||}|||d}||| d S Nr   )r   r   addr0   rz   )r#   r8   r   oldnewr   r   r   set_try_status  s   

zCPUCallConv.set_try_statusc                 C   s\   |  |}||}|||d}||| | |j}t|jj	}||| d S r   )
r   r   subr0   rz   r   rX   r   r   rx   )r#   r8   r   r   r   r   nullr   r   r   unset_try_status  s   

zCPUCallConv.unset_try_statusc                 C   sn   |  |}| |j}||j| |||j | j||j	dd W d    d S 1 s0w   Y  d S rD   )
r   r   rX   rz   r   r.   r   r
   r@   r   )r#   r8   rd   r   r   r   r   r   r     s   
"z#CPUCallConv.return_status_propagateFc                 C   s:   | |}|r|jtddg}|d| d S d S )Nr   ret_is_raise)r   moduleadd_metadatar   IntTypeset_metadata)r#   r8   r   rF   r   mdr   r   r   r@     s
   
zCPUCallConv._return_errcode_rawc              
   C   s   | d|t}| d|t}| d|t}| d|t}|||}||}	| d|t}
||
|t	
tt	j}t|||	|||
||d}|S )zP
        Given a return *code* and *excinfoptr*, get a Status instance.
        r   r   r   )r   r{   rA   rG   rI   r   r   r   selectr   r   excinfo_ptr_t	Undefinedr   )r#   r8   r   r   r   r)   rf   r   r   r   r   rd   r   r   r   r     s(   
zCPUCallConv._get_return_statusc                 C   s<   |  |}t|j}| |}tt|ttg| }|S r   )	ri   r   r   rL   r   r   r   PointerTyper   r   r   r   r   r     s   


zCPUCallConv.get_function_typec                    s     |}| |dd |D   |}d|_|d |d  |}d|_|d |d |rT |}|D ]}t|jt	j
rS|d |d q@ fdd}	tt|	|}
|
rs|jd	}||j|g |S )
zU
        Set names of function arguments, and add useful attributes to them.
        c                 S   r   r   r   r   r   r   r   r     r   z1CPUCallConv.decorate_function.<locals>.<listcomp>r}   	nocapturer   r   c                    s(   t | tjs jj}||   rdS dS NTF)r3   r   Arrayr"   rK   contains_nrt_meminfo)rN   dmmr   r   r   type_may_always_need_nrt  s
   z?CPUCallConv.decorate_function.<locals>.type_may_always_need_nrtnumba_args_may_always_need_nrt)ri   r   rh   r   r   add_attributer   r3   r0   r   r   anymapr   add_named_metadatar   r   )r#   r   rw   r   r   rn   retargexcargr   r  args_may_always_need_nrtnmdr   r   r   r     s:   









zCPUCallConv.decorate_functionc                 C   r   )r      Nr   r   r   r   r   rh   &  r   zCPUCallConv.get_argumentsc                 C   
   |j d S rv   r   r   r   r   r   r   ,  r%   z CPUCallConv._get_return_argumentc                 C   r  r   r   r   r   r   r   r   /  r%   z!CPUCallConv._get_excinfo_argumentc                 C   s   |  |jj}t||}|t|| tj|tt	dd}	| 
|}
t|
||}||	g| }|du r;d}nt|trJt|tsJt|}ntd|j|||d}| ||||	}||}| j|||}||fS )aU  
        Call the Numba-compiled *callee*.
        Parameters:
        -----------
        attrs: LLVM style string or iterable of individual attributes, default
               is None which specifies no attributes. Examples:
               LLVM style string: "noinline fast"
               Equivalent iterable: ("noinline", "fast")
        r   )r   Nr   z,attrs must be an iterable of strings or None)attrs)r   function_typerx   r   r   rz   r   r   r   	excinfo_tri   r   r   r3   r   ry   r   r   r   r   r   r"   r   )r#   r8   r   r   r   rw   r  r9   r   r   rn   r   _attrsr   rd   r=   r   r   r   r   r   2  s*   


zCPUCallConv.call_functionr   r   r   )rq   rr   rs   r   	itertoolscount_status_idsrP   r2   r   r   r   r   r   r   r   r@   r   r   r   rh   r   r   r   r   r   r   r   r   U  s2    

 



-r   c                   @   s   e Zd Zdd ZdddZdS )
ErrorModelc                 C   r!   r   )	call_conv)r#   r  r   r   r   r$   ^  r%   zErrorModel.__init__Nc                 C   s    | j r| j|t|| dS dS r   )raise_on_fp_zero_divisionr  r   ZeroDivisionError)r#   r8   r   r   r   r   r   fp_zero_divisiona  s   zErrorModel.fp_zero_division)NN)rq   rr   rs   r$   r  r   r   r   r   r  \  s    r  c                   @      e Zd ZdZdZdS )PythonErrorModelzL
    The Python error model.  Any invalid FP input raises an exception.
    TNrq   rr   rs   r   r  r   r   r   r   r  j  s    r  c                   @   r  )NumpyErrorModela6  
    In the Numpy error model, floating-point errors don't raise an
    exception.  The FPU exception state is inspected by Numpy at the
    end of a ufunc's execution and a warning is raised if appropriate.

    Note there's no easy way to set the FPU exception state from LLVM.
    Instructions known to set an FP exception can be optimized away:
        https://llvm.org/bugs/show_bug.cgi?id=6050
        http://lists.llvm.org/pipermail/llvm-dev/2014-September/076918.html
        http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20140929/237997.html
    FNr  r   r   r   r   r  q  s    r  )pythonnumpyc                 C   s   t |  |jS )zF
    Create an error model instance for the given target context.
    )error_modelsr  )
model_namer"   r   r   r   create_error_model  r   r"  )(r   collectionsr   collections.abcr   r  llvmliter   
numba.corer   r   numba.core.baser   r   r	   r   r   int32_tr   r   r{   rG   rA   rI   r   r   objectr    rt   ru   LiteralStructTyper  r   r   r   r  r  r  r   r"  r   r   r   r   <module>   sF    
k~1
  	