o
    1&ir                     @   sx  d Z ddlmZ ddlmZ ddlZddlZddlmZ ddl	m
Z
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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 dZ!dZ"dZ#dZ$dZ%e&e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errors)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   >C:\wamp64\www\opt\env\Lib\site-packages\numba/core/callconv.py
_const_int+      r      c                   @   sl   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d ZdS )BaseCallConvc                 C   
   || _ d S r   )context)selfr%   r   r   r   __init__<      
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)ZfromtyZtotyzreturning {0} for {1})r   nonereturn_native_noner%   Zmake_helperr   Zas_bool_bitZvalidif_thenZget_return_valuetypedatareturn_value
isinstanceOptionalcastNotImplementedErrorformat)r&   builderrettyZvaltyr)   optvalZvalidbitretvalr   r   r   return_optional_value?   s,   

z"BaseCallConv.return_optional_valuec                 C      |  |t d S r   )_return_errcode_rawRETCODE_NONEr&   r5   r   r   r   r+   \      zBaseCallConv.return_native_nonec                 C   r:   r   )r;   RETCODE_EXCr=   r   r   r   
return_exc_   r>   zBaseCallConv.return_excc                 C   r:   r   )r;   RETCODE_STOPITr=   r   r   r   return_stop_iterationb   r>   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   rD   e   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&   r5   chr   r   r   init_call_helperl   s   
zBaseCallConv.init_call_helperc                 C   s   |j S r   )rI   r=   r   r   r   _get_call_helpert      zBaseCallConv._get_call_helperc                 C   s   | |jS r   )unserializer   )r&   r5   pyapistatusr   r   r   unpack_exceptionw   r   zBaseCallConv.unpack_exceptionc              	   C   s.  |j  }||j7 |  | |||}t|t|| |	| W d   n1 s1w   Y  |
| W d   n1 sEw   Y  ||j |d |
| W d   n1 sew   Y  ||j |
| W d   n1 sw   Y  |dd |
| || dS )zT
        Given a non-ok *status*, raise the corresponding Python exception.
        NZPyExc_StopIterationZPyExc_SystemErrorz*unknown error when calling native function)functionappend_basic_blockr,   r   Z	err_clearrQ   r   Z	if_likelyZis_not_nullZraise_objectbranchr   Zerr_set_noner   err_set_stringZposition_at_end)r&   r5   rO   rP   Zbbendexcr   r   r   raise_errorz   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_packerZfrom_arguments)r&   r5   argtypesfuncZ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%   Zget_arg_packer)r&   rZ   r   r   r   rY      s   zBaseCallConv._get_arg_packerN)__name__
__module____qualname__r'   r9   r+   r@   rB   rD   rK   rL   rQ   rW   r]   rY   r   r   r   r   r#   :   s    	r#   c                   @   sh   e Zd ZdZdd Zdd Z		d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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   )_MinimalCallHelperr=   r   r   r   rH      rM   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   )rR   argsr-   pointeestrstorer;   
RETCODE_OKr&   r5   r8   retptrr   r   r   r/         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 }| |}|	|||}	| 
|t|	 d S )N-exc should be None or exception class, got %r(exc_args should be None or tuple, got %r)
issubclassBaseException	TypeErrorr0   tuple_raw_function_namefilenamelinerL   _add_exceptionr;   r   )
r&   r5   rV   exc_argsloc	func_namefnamelocinfoZcall_helperexc_idr   r   r   return_user_exc   s(   
zMinimalCallConv.return_user_excc                 C   s   |  ||j d S r   )r;   r   )r&   r5   rP   r   r   r   return_status_propagate   s   z'MinimalCallConv.return_status_propagatec                 C   s    t |tr	t|}|| d S r   )r0   intr   retr&   r5   r   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_signedrh   r<   or_not_r?   rA   RETCODE_USEREXCr   )r&   r5   r   normr*   okerrrV   r   r   rP   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*.
        )rY   listargument_typesrD   r   FunctionTyper   r&   rG   rZ   r\   Zresptrfntyr   r   r   get_function_type   s
   


z!MinimalCallConv.get_function_typeFc                 C   s>   |rJ |  |}|| |dd |D  d|jd _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   N)rY   assign_namesrX   rd   name)r&   fnrd   fe_argtypesnoaliasr\   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rd   r&   r[   r   r   r   rX        zMinimalCallConv.get_argumentsc                 C   s   |j d jj}t||}|t|| | |}|||}|gt	| }	|
||	}
| ||
}||}| j|||}||fS )z3
        Call the Numba-compiled *callee*.
        r   )rd   r-   re   r   alloca_oncerg   get_null_valuerY   as_argumentsr   callr   loadr%   get_returned_value)r&   r5   calleerestyargtysrd   r6   	retvaltmpr\   realargsr   rP   r8   outr   r   r   call_function  s   

zMinimalCallConv.call_functionNNNF)r^   r_   r`   __doc__rH   r/   r|   r}   r;   r   r   r   rX   r   r   r   r   r   ra      s    



ra   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	rb   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&   rV   rv   rz   r{   r   r   r   ru   /  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{   msgrV   rv   rz   r   r   r   get_exceptionA  s   
z _MinimalCallHelper.get_exceptionN)r^   r_   r`   r   r'   ru   r   r   r   r   r   rb   %  s
    rb            c                   @   s   e Zd ZdZedZdd Zdd Zdd Z					d5d
dZ
				d5ddZdd Zdd Zdd Zdd Z				d6ddZ		d6d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d7d+d,Zd-d. Zd/d0 Zd1d2 Z		d8d3d4Zd	S )9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   r=   r   r   r   rH   r  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_argumentrR   r-   re   rf   rg   r;   rh   ri   r   r   r   r/   u  rk   zCPUCallConv.return_valuec                 C   sJ   |d ur|  }|d u r|}||j|jf}d |v rd }nd }|||f}|S r   )rr   rs   rt   )r&   rV   rv   rw   rx   ry   rz   r   r   r   build_excinfo_struct|  s   
z CPUCallConv.build_excinfo_structNc                 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|}| ||||}||}| 	|j
}|||}	|jtddg}
|	d|
 d S )Nrl   rm   r"   Znumba_exception_output)rn   ro   rp   r0   rq   r%   get_python_apir   serialize_object_get_excinfo_argumentrR   rg   moduleadd_metadatar   IntTypeZset_metadata)r&   r5   rV   rv   rw   rx   rO   	struct_gvexcptrrg   mdr   r   r   set_static_user_exc  s"   %
zCPUCallConv.set_static_user_excc                 C   sP   t |dd}| j|||||d | | |r ||d  d S | |t d S )NZ_in_try_blockF)rv   rw   rx   target)getattrr   check_try_statusrT   r;   r   )r&   r5   rV   rv   rw   rx   Ztry_infor   r   r   r|     s   

zCPUCallConv.return_user_excc                 C   s<  |j }|||t}|||t}|||||j}|||t}|||t	}	t
ttg}
||	|
 }|||g}t||}t||) d}|d| |jj}
t|
jt
jsr|t|
j n|  W d    n1 sw   Y  |||}| jjr| jj !||||j" |S )Nz<Error creating Python tuple from runtime exception argumentsZPyExc_RuntimeError)#r   extract_valuer   PICKLE_BUF_IDXPICKLE_BUFSZ_IDXZbytes_from_string_and_sizeZsext
py_ssize_tHASH_BUF_IDXUNWRAP_FUNC_IDXr   r   r   r	   bitcastrE   r   r   Zis_nullZif_unlikelyrU   rR   function_typer0   return_typeZVoidTyper   r   Zret_voidZbuild_dynamic_excinfo_structr%   Z
enable_nrtnrtfreeZvoidptr)r&   r5   rO   rP   excinfo_ptrZ	picklebufZpicklebuf_szZstatic_exc_bytesZdyn_argsZfunc_ptrr   r   Zpy_tuplefailedr   r   r   r   r   unpack_dynamic_exception  sF   



z$CPUCallConv.unpack_dynamic_exceptionc              	   C   s   |j }|||t}|d|td}||@\}}| | |||}	|j}
W d    n1 s4w   Y  | |	|}|j}W d    n1 sNw   Y  W d    n1 s]w   Y  |
|j}||	|
 ||| |S )N>r   )r   r   r   ALLOC_FLAG_IDXr   int32_tZif_elser   blockrN   phir-   Zadd_incoming)r&   r5   rO   rP   r   Z
alloc_flaggtZthenZ	otherwiseZdyn_excZbb_thenZ
static_excZbb_elser   r   r   r   rQ     s(   
zCPUCallConv.unpack_exceptionc                 C   s`  t t|  }d| }||jv r|j|S tt	t	g}t
|||}d|_|jd |jd |d}t|}	| j|	}
| }|	|jd |}dd |D }g }| jj|	d	d
}t|D ]-\}}|	|	||}|
j|||d}|t|jkrd| d}t||| qj| jj !|	| "|	j# |
$|}|	%| |S )NZ__excinfo_unwrap_argsZexternalZnounwindZnoinline r   c                 S   s   g | ]}|d ur|qS r   r   )r   typr   r   r   r   F  s    z@CPUCallConv.emit_unwrap_dynamic_exception_fn.<locals>.<listcomp>T)Zreturn_pyobject)env_managerzCannot convert native z to a Python object.)&hashlibsha1rf   encode	hexdigestglobalsgetr   r   r	   Functionlinkage
attributesaddrS   Z	IRBuilderr%   r   rE   r   rd   Zget_env_manager	enumerater   r   Zfrom_native_valuer   r   r-   r   ZTypingErrorappendr   r   r   rR   Z
tuple_packr   )r&   r   Zst_typenb_types_hashr   r   r   Zbb_entryr5   rO   Zst_type_ptrst_ptrZobjsr   ir   valobjr   tupr   r   r    emit_unwrap_dynamic_exception_fn   s@   








z,CPUCallConv.emit_unwrap_dynamic_exception_fnc           
   
   C   sv   | | j|}|| jj||| }dd |D }td}t|D ]\}}	|	|	|
||t|g q&|S )zP
        Create an anonymous struct containing the given LLVM *values*.
        c                 S   s   g | ]
}t |tjr|qS r   r0   r   Valuer   argr   r   r   r   m  s    z4CPUCallConv.emit_wrap_args_insts.<locals>.<listcomp>r   )r   r%   get_abi_sizeofr   r   allocaterE   r   r   rg   gep)
r&   r5   rO   struct_typerv   st_sizer   zeroidxr   r   r   r   emit_wrap_args_instsb  s   z CPUCallConv.emit_wrap_args_instsc              
      sj  t |tstd|f |durt|tstd|f | j|}| j  t fdd|D }| ||||}| 	|j
}	|||}
tdd |D }| ||||}| |j||}|| jt}|| jj||t}td}||
t||
t||t||ttt|f}t|D ]\}}| ||!||t|g q| ||	 dS )zf
        Compute the required bits to emit an exception with dynamic (runtime)
        values
        z(exc should be an exception class, got %rNrm   c                    s    g | ]}t |tjr n|qS r   r   r   dummyr   r   r     s     z4CPUCallConv.set_dynamic_user_exc.<locals>.<listcomp>c                 S   s   g | ]}t |tjr|jqS r   )r0   r   r   r-   r   r   r   r   r     s    
r   )"rn   ro   rp   r0   rq   r%   r   Zget_dummy_valuer   r   rR   r   r   r   LiteralStructTyper  r   r   r   r   	excinfo_tr   r   r   excinfo_ptr_tr   r   r   r   r	   r   r   rg   r  )r&   r5   rV   rv   r   rw   rx   rO   Zexc_args_staticZ
excinfo_ppr   r  r   Z	unwrap_fnZexc_sizeZ	excinfo_pr  Z
exc_fieldsr  r   r   r  r   set_dynamic_user_excu  sL   
1






z CPUCallConv.set_dynamic_user_excc                 C   s&   | j ||||||d | |t dS )zF
        Same as ::return_user_exc but for dynamic exceptions
        )rw   rx   N)r  r;   r   )r&   r5   rV   rv   r   rw   rx   r   r   r   return_dynamic_user_exc  s   z#CPUCallConv.return_dynamic_user_excc              	   C   s:   z|j W S  ty   tj|tjddd}||_ | Y S w )NZ	try_stateT)r   zfill)Z_CPUCallConv__eh_try_stateAttributeErrorr   r   Zintp_t)r&   r5   ptrr   r   r   _get_try_state  s   
zCPUCallConv._get_try_statec                 C   sJ   |  |}||}|d||d}| |j}||}t||dS )Nr   r   )r   r   )r  r   Zicmp_unsignedr-   r   rR   r
   )r&   r5   try_state_ptrZ	try_depthr   r   r   r   r   r   r     s   


zCPUCallConv.check_try_statusc                 C   s6   |  |}||}|||d}||| d S Nr"   )r  r   r   r-   rg   )r&   r5   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   subr-   rg   r   rR   r   r   re   )r&   r5   r  r  r  r   nullr   r   r   unset_try_status  s   

zCPUCallConv.unset_try_statusc                 C   sj   |  |}| |j}||j| |||j | ||j	 W d    d S 1 s.w   Y  d S r   )
r   r   rR   rg   r   r,   r   r   r;   r   )r&   r5   rP   Z	trystatusr   r   r   r   r}     s   
"z#CPUCallConv.return_status_propagatec                 C   s   | | d S r   )r   r   r   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   rh   r<   r?   rA   r   r   r   selectr   r   r  	Undefinedr   )r&   r5   r   r   r   r*   rV   r   r   r   r   rP   r   r   r   r     s(   
zCPUCallConv._get_return_statusc                 C   s<   |  |}t|j}| |}tt|ttg| }|S r   )	rY   r   r   rD   r   r   r   PointerTyper  r   r   r   r   r   &  s   


zCPUCallConv.get_function_typeFc                    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|	|}
|
ru|jd	}||j|g d
S d
S )zU
        Set names of function arguments, and add useful attributes to them.
        c                 S   r   r   r   r   r   r   r   r   8  r   z1CPUCallConv.decorate_function.<locals>.<listcomp>rj   Z	nocapturer   r   c                    s(   t | tjs jj}||   rdS dS NTF)r0   r   Arrayr%   rC   Zcontains_nrt_meminfo)rF   Zdmmr   r   r   type_may_always_need_nrtK  s
   z?CPUCallConv.decorate_function.<locals>.type_may_always_need_nrtZnumba_args_may_always_need_nrtN)rY   r   rX   r   r   Zadd_attributer   r0   r-   r   r  anymapr   Zadd_named_metadatar   r   )r&   r   rd   r   r   r\   ZretargZexcargr   r  Zargs_may_always_need_nrtZnmdr   r   r   r   2  s:   









zCPUCallConv.decorate_functionc                 C   r   )r   r   Nr   r   r   r   r   rX   ]  r   zCPUCallConv.get_argumentsc                 C   
   |j d S rc   r   r   r   r   r   r   c  r(   z CPUCallConv._get_return_argumentc                 C   r"  r  r   r   r   r   r   r   f  r(   z!CPUCallConv._get_excinfo_argumentc                 C   s  |  |j}| |jj}||krd| d| }	t|	t||}
|t||
 tj|t	
tdd}| |}t|||}|
|g| }|du rQd}nt|tr`t|ts`t|}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")
        zFunction type returns z but resty=r   )r   Nr   z,attrs must be an iterable of strings or None)attrs)rD   re   r   r   
ValueErrorr   r   rg   r   r   r  r
  rY   r   r   r0   r   rf   rq   rp   r   r   r   r%   r   )r&   r5   r   r   r   rd   r#  r6   Zactual_rettymr   r   r\   r   Z_attrsr   rP   r8   r   r   r   r   r   i  s2   


zCPUCallConv.call_functionr   NNr   r   )r^   r_   r`   r   	itertoolscountZ_status_idsrH   r/   r   r   r|   r   rQ   r   r  r  r  r  r   r  r  r}   r;   r   r   r   rX   r   r   r   r   r   r   r   r   a  sF    

9
4B
^
	

+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&   r5   rv   rw   r   r   r   fp_zero_division  s   zErrorModel.fp_zero_divisionr&  )r^   r_   r`   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r^   r_   r`   r   r+  r   r   r   r   r/    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
    FNr0  r   r   r   r   r1    s    r1  )pythonnumpyc                 C   s   t |  |jS )zF
    Create an error model instance for the given target context.
    )error_modelsr*  )Z
model_namer%   r   r   r   create_error_model  r   r5  )0r   collectionsr   collections.abcr   r'  r   Zllvmliter   Z
numba.corer   r   r   Znumba.core.baser   r	   r
   r   r   r   Zint64_tr   r   rh   r?   r<   rA   r   r   objectr#   ra   rb   r   r   r   r   r   r	  r
  r  r  r   r)  r/  r1  r4  r5  r   r   r   r   <module>   s\    

n}2
    8