U
    ,d#m                     @   s  d Z ddlZddlZddlZddlZddlZddlmZ ddl	m
Z ddlmZ ddlmZmZmZm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mZmZmZ ejd
kZ ejdkZ!ej"j#Z$e%ede$ Z&e%ede$ Z'ej"j(Z)ej"j*Z+e'ej"j,Z-ej.j/dkrdndZ0dZ1e1Z2ej3j4Z5ej"j6Z7ej"j8Z9ee:dd Z;edd Z<ee'e'ej=ej>ej>e'ej>dddd Z?edd Z@edd ZAee'e'e'e'e'e'ejBejBdddd  ZCeejDd!eejEd!d"d# ZFeejGd!d$d% ZHeejId!d&d' ZJe re'j/d( d)krLe'd*ZKe'd+ZLe'd,ZMed-ejNidd.d/ ZOn0e'd0ZKe'd1ZLe'd2ZMed-ejNidd3d/ ZOdd4lPmQZQ ee'e'e'e'e'd5dd6d7 ZRnee'e&e'e&d8dd9d7 ZRed:d; ZSeejTd!d<d= ZUdd>lmVZVmWZWmXZXmYZYmZZZm[Z[ G d?d@ d@eZZ\G dAdB dBeZZ]G dCdD dDeZZ^G dEdF dFeZZ_G dGdH dHe[Z`edIdJdKgZadLdM Zbeb Zce9dNkrJe9dOkrdPZdeeed eejNejNdQddRdS ZfeejNejNejNejNejNejNdTddUdV ZgeejNejNejNejNdWddXdY ZheejNejNejNejNejNejNeiejNdZd[ejNejNejNejNd\dd]d^ Zjnd_e9 Zdekeded`da Zldbdc Zmeemddde Znedfe'iddgdh Zoeejpd!didj ZqdS )kz&
Hash implementations for Numba types
    N)
namedtuple)ir)overloadoverload_method	intrinsicregister_jitable)errors)typesutils)	grab_bytegrab_uint64_t)	const_intget_next_intget_next_int32get_state_ptr)      )r   
   zint%szuint%s       =   iCB c                 C   s   dd }|S )Nc                 S   s   |   S N)__hash__)obj r   9/tmp/pip-unpacked-wheel-eu7e0c37/numba/cpython/hashing.pyimpl2   s    zhash_overload.<locals>.implr   )r   r   r   r   r   hash_overload0   s    r   c                 C   s    t | }|tdkrtd}|S )N)
_Py_hash_tint)valZasintr   r   r   process_return7   s    r#   )xymesign_PyHASH_MODULUS_PyHASH_BITS)localsc                 C   s
  t | s>t | r(| dkr tS t S ntr:t }t|S tS t	| \}}d}|dk rbd}| }d}|r|d> t
@ |td ? B }|d9 }|d8 }t|}||8 }||7 }|t
krf|t
8 }qf|dkr|t }ntd d| t  }||> t
@ |t| ? B }|| }t|S )Nr      r      g      A)npisfiniteisinf_PyHASH_INF_py310_or_later_prng_random_hashr#   _PyHASH_NANmathfrexpr)   r*   r!   )vr$   r&   r'   r(   r%   r   r   r   _Py_HashDoubleF   s<    



r8   c                 C   s   dd }t t j}||fS )Nc                 S   s   |d }| |t S )Nr   )Zfpextr   Z
DoubleType)cgctxbuilder	signatureargsr"   r   r   r   r      s    z_fpext.<locals>.impl)r	   float64Zfloat32tyctxr"   r   sigr   r   r   _fpext~   s    rA   c                 C   s   dd }t  }||fS )Nc                 S   s>   t | |d}tt}tdkr*t| ||}nt| |||d}|S )NZinternalr   F)r   r   _hash_widthr   r   )r9   r:   r;   r<   Z	state_ptrbitsvaluer   r   r   r      s    	z_prng_random_hash.<locals>.implr    )r?   r   r@   r   r   r   r3      s    r3   )r$   p1p2p3p4r)   r*   _PyLong_SHIFTc           
      C   s   dt  }td |? }dt  d }d}tt  }t|d ddD ]N}|t > }|t@ }||? }	||	B }|t| |t  ? |@ 7 }|tkr@|t8 }q@t|S )Nr   r   @   r,   r   )rJ   r	   Zuint32r*   ranger)   r    )
r"   Z
_tmp_shiftZ
mask_shiftir$   rH   idxrF   rG   rI   r   r   r   
_long_impl   s    
rO   r   c                    sH   t jdkrdndtdt| ddr.tjntj  fdd}|S )	Nl        r   l         signedFc                    sr    | } t | }|tk rB| dkr&d}qj| kr8t}qjt| }n(d}| dk rX|  } d}t| }|rj| }t|S )Nr   FT)absr)   r    rO   r#   )r"   ZmagretZneeds_negateZ_BIGZ_HASH_I64_MINZ_SIGNED_MINr   r   r      s     


zint_hash.<locals>.impl)sysmaxsizer	   Zint64getattruint64r"   r   r   rT   r   int_hash   s
    
rZ   c                 C   s    | j dkrdd }ndd }|S )NrK   c                 S   s   t | }|S r   )r8   r"   hashedr   r   r   r      s    zfloat_hash.<locals>.implc                 S   s   t t| }t|}|S r   )r.   r=   rA   r8   )r"   Z
fpextendedr\   r   r   r   r     s    )bitwidthrY   r   r   r   
float_hash   s    

r^   c                 C   s   dd }|S )Nc                 S   s(   t | j}t | j}|t|  }t|S r   )hashrealimag_PyHASH_IMAGr#   )r"   ZhashrealZhashimagZcombinedr   r   r   r     s    

zcomplex_hash.<locals>.implr   rY   r   r   r   complex_hash  s    
rc   r      l   Jfq	 l   OkO8 l   g,,> r$   c                 C   s   | t d> | t d? B S )Nr   !   r	   rX   r$   r   r   r   _PyHASH_XXROTATE'  s    rh   l   yn< l   wJ igVc                 C   s   | t d> | t d? B S )N      rf   rg   r   r   r   rh   0  s    )literal_unroll)acclane_PyHASH_XXPRIME_5_PyHASH_XXPRIME_1tlc                 C   s   t | }t}t| D ]:}t|}|tdkr2 dS ||t 7 }t|}|t9 }q||ttdA A 7 }|tdkrxtdS t|S )Nr   is5 iK*\)	lenrn   rk   r_   _Py_uhash_t_PyHASH_XXPRIME_2rh   ro   r#   )tuprp   rl   r$   rm   r   r   r   _tuple_hash9  s    
ru   )r$   r%   multlc                 C   sz   t | }t}td}tt|d ddD ]<\}}t| | }||A }|| }|ttd| | 7 }q(|td7 }t|S )NxV4 r,   r   XB | )rq   _PyHASH_MULTIPLIERrr   	enumeraterL   r_   r    r#   )rt   rp   rv   r$   rM   rw   r%   xxoryr   r   r   ru   Q  s    c                    s    fdd}t |}||fS )Nc                    s  | j }|t}|j\}|\}| |j}t|d}	t|t}
t|d}t	|}t
t|jt|d ddD ]\}}|\}}| |fi }| ||}|||}|||f}||	|}|||
}	t||}||
|}
||
|}
||
|}
qr||	t|d}	|	S )Nrx   ry   r,   r   rz   )Ztyping_contextZresolve_value_typer_   r<   Zget_value_typereturn_typer   Constantr{   rq   r|   zipr	   rL   Zget_call_typeZget_functionZextract_valuexormuladd)r9   r:   r;   r<   Z	typingctxZfntyZtuptyrt   Zltyr$   rv   shiftrp   rM   packedtyrw   r@   r   Z	tuple_valr%   r}   Zlconstr?   r   r   r   n  s.    
$z!_tuple_hash_resolve.<locals>.implrE   r>   r   r   r   _tuple_hash_resolvel  s    r   c                 C   s,   t st| tjrdd }|S dd }|S d S )Nc                 S   s   t | S r   )ru   )r"   r   r   r   r     s    ztuple_hash.<locals>.implc                 S   s   t t| }t|S r   )r    r   r#   r[   r   r   r   r     s    )_py38_or_later
isinstancer	   SequencerY   r   r   r   
tuple_hash  s
    r   )c_size_tc_ubytec_uint64	pythonapi	StructureUnionc                   @   s   e Zd ZdefdefgZdS )FNVprefixsuffixN)__name__
__module____qualname__r   _fields_r   r   r   r   r     s   r   c                   @   s   e Zd ZdefdefgZdS )SIPHASHk0k1N)r   r   r   r   r   r   r   r   r   r     s   r   c                   @   s    e Zd Zded fdefgZdS )DJBX33Apadding   r   Nr   r   r   r   r   r   r   r   r   r   r     s   
r   c                   @   s    e Zd Zded fdefgZdS )EXPATr   r   ZhashsaltNr   r   r   r   r   r     s   
r   c                   @   s2   e Zd Zded fdefdefdefdefgZdS )_Py_HashSecret_tZuc   fnvsiphashdjbx33aexpatN)	r   r   r   r   r   r   r   r   r   r   r   r   r   r     s   
r   _hashsecret_entrysymbolrD   c                     sJ   t td} i   fdd}|d| jj |d| jj |d| jj  S )zRead hash secret from the Python process

    Returns
    -------
    info : dict
        - keys are "djbx33a_suffix", "siphash_k0", siphash_k1".
        - values are the namedtuple[symbol:str, value:int]
    Z_Py_HashSecretc                    s>   d | }t|}t|}t|| t||d | < d S )Nz_numba_hashsecret_{})r   rD   )formatctypesr   	addressofllZ
add_symbolr   )namer"   Zsymbol_nameaddrinfor   r   inject  s
    


z!_build_hashsecret.<locals>.injectdjbx33a_suffix
siphash_k0
siphash_k1)r   in_dllr   r   r   r   r   r   )Zpyhashsecretr   r   r   r   _build_hashsecret  s    r   )Z	siphash24r   r   a  FNV hashing is not implemented in Numba. See PEP 456 https://www.python.org/dev/peps/pep-0456/ for rationale over not using FNV. Numba will continue to work, but hashes for built in types will be computed using siphash24. This will permit e.g. dictionaries to continue to behave as expected, however anything relying on the value of the hash opposed to hash as a derived property is likely to not work as expected.r$   bc                 C   s    t | |> | t d| ? B S )NrK   rf   r   r   r   r   _ROTATE6  s    r   ar   cdstc                 C   sB   | |7 } ||7 }t ||| A }t |||A }t | d} | |||fS )Nr   )r   r   r   r   r   _HALF_ROUND;  s    
r   v0v1v2v3c                 C   st   t | |||dd\} }}}t ||| |dd\}}} }t | |||dd\} }}}t ||| |dd\}}} }| |||fS )Nri   r         )r   r   r   r   r   _DOUBLE_ROUNDI  s
    r   r,   C)r   r   r   r   r   mitmpr   maskjmpohexefefc                 C   s  t |d> }| t dA }|t dA }| t dA }|t dA }d}	|dkrt||	}
|	d7 }	|d8 }||
N }t||||\}}}}||
N }qJt d}|	d }t d	}|d
krd}t ||>  }||@ t t||d |> B }|dkr*d}t ||>  }||@ t t||d |> B }|dkrhd}t ||>  }||@ t t||d |> B }|dkr|t dM }tdD ]>}|d }t ||>  }||@ t t||| |> B }q|dkrd}t ||>  }||@ t t||d |> B }|dkrDd}t ||>  }||@ t t||d |> B }|dkrp| }||@ t t||d B }||O }||N }t||||\}}}}||N }||N }t||||\}}}}t||||\}}}}||A ||A A }|S )N8   l   ue`5{ l   mo\I{# l   ar\c l   ser+# r   r   r,         0      (      r   rd   l        r   r      )r	   rX   r   r   r   rL   )r   r   srcZsrc_szr   r   r   r   r   rN   r   r   Zboffsetr   r   r   rM   r   r   r   
_siphash24T  s    










r   z'Unsupported hashing algorithm in use %sc                    sD   t |tjstdt|j j tj}||} fdd}||fS )z&Emit code to load the hashsecret.
    zrequires literal stringc                    sN   |j }z| }W n* tk
r>   tj|td d}Y nX ||}|S )NrK   r   )moduleZ
get_globalKeyErrorr   ZGlobalVariableZIntTypeload)r9   r:   r@   r<   modgvr7   symr   r   r     s    
z%_inject_hashsecret_read.<locals>.impl)	r   r	   ZStringLiteralr   ZTypingError_hashsecretZliteral_valuer   rX   )r?   r   Zrestyr@   r   r   r   r   _inject_hashsecret_read  s    
r   c                 C   s
   t |  jS r   )r   rD   r   r   r   r   _load_hashsecret  s    r   c                 C   s   dd }|S )Nc                 S   s   t | S r   )r   r   r   r   r   imp  s    z"_impl_load_hashsecret.<locals>.impr   )r   r   r   r   r   _impl_load_hashsecret  s    r   _hashc                 C   s   |dkrt dS |tk r`td}t|D ] }|d> | tt| | }q(||N }|tdN }n*tt	
tdt	
td| |}t |}t |S )Nr   i  r   r   r   r   )r#   _Py_HASH_CUTOFFrr   rL   r.   Zuint8r   r   r   r	   rX   )r"   _lenr   rN   r   r   r   r   _Py_HashBytes  s     r   c                    s   ddl m   fdd}|S )Nr   _kind_to_byte_widthc                    s8    | j }t| }| j}|dkr$|S t| j|| S d S )Nr   )_kindrq   r   r   _data)r"   Z	kindwidthr   Zcurrent_hashr   r   r   r     s    
zunicode_hash.<locals>.impl)Znumba.cpython.unicoder   rY   r   r   r   unicode_hash  s    r   )r__doc__r5   Znumpyr.   rU   r   warningscollectionsr   Zllvmlite.bindingZbindingr   Zllvmliter   Znumba.core.extendingr   r   r   r   Z
numba.corer   r	   r
   Znumba.core.unsafe.bytesr   r   Znumba.cpython.randomimplr   r   r   r   Z	PYVERSIONr   r2   	hash_infowidthrB   rW   r    rr   infr1   nanr4   modulusr)   Zintpr]   r*   r{   rb   int_infobits_per_digitrJ   cutoffr   	algorithmZ_Py_hashfunc_namer_   r   r#   doubleZintcr8   rA   r3   Zint32rO   ZIntegerBooleanrZ   ZFloatr^   Complexrc   ro   rs   rn   rX   rh   Znumbark   ru   r   Z	BaseTupler   r   r   r   r   r   r   r   r   r   r   r   r   r   r   msgwarnr   r   r   Arrayr   
ValueErrorr   r   r   r   ZUnicodeTyper   r   r   r   r   <module>   s"  




1




,








 



*


C




