U
    ,d+                     @   s&  d dl mZmZ d dlZd dlZd dlZd dlmZmZ d dl	m
Z
mZmZ d dlmZ eddgZdZd	d
 Zdd Zdd ZeejZeejZeeB ZeeddgZejZejZG dd deZdZdZ dZ!ej"#dZ$dd Z%dd Z&G dd deZ'G dd deZ(G dd dej)Z*dS )    )
namedtupleOrderedDictN)CodeType
ModuleType)errorsutils	serialize)	PYVERSIONopcode_infoZargsize   c                 C   s   t | dd}|rt | |S | S )z
    Objects that wraps function should provide a "__numba__" magic attribute
    that contains a name of an attribute that contains the actual python
    function object.
    Z	__numba__Ngetattr)objattr r   7/tmp/pip-unpacked-wheel-eu7e0c37/numba/core/bytecode.pyget_function_object   s    
r   c                 C   s   t | dt | ddS )z"Shamelessly borrowed from llpython__code__	func_codeNr   )r   r   r   r   get_code_object   s    r   c                 C   s0   g }| D ]"}t j|}|d k	r|| q|S N)disopmapgetappend)seqlstscr   r   r   _as_opcodes#   s    r   RETURN_VALUERAISE_VARARGSc                   @   sP   e Zd ZdZdZdd Zedd Zedd Zd	d
 Z	dd Z
edd ZdS )ByteCodeInstz
    Attributes
    ----------
    - offset:
        byte offset of opcode
    - opcode:
        opcode integer value
    - arg:
        instruction arg
    - lineno:
        -1 means unknown
    )offsetnextopcodeopnamearglinenoc                 C   s.   || _ || _|| _tj| | _|| _d| _d S )N)r#   r$   r%   r   r&   r'   r(   selfr#   r%   r'   
nextoffsetr   r   r   __init__C   s    zByteCodeInst.__init__c                 C   s
   | j tkS r   )r%   JUMP_OPSr+   r   r   r   is_jumpK   s    zByteCodeInst.is_jumpc                 C   s
   | j tkS r   )r%   TERM_OPSr/   r   r   r   is_terminatorO   s    zByteCodeInst.is_terminatorc                 C   sx   | j s
ttdkrJ| jtkr,| j| jd  S | jtks:t| jd d S n*| jtkr`| j| j S | jtksnt| jS d S )N)   
   r   )r0   AssertionErrorr	   r%   JREL_OPSr$   r'   JABS_OPSr/   r   r   r   get_jump_targetS   s    	


zByteCodeInst.get_jump_targetc                 C   s   d| j | j| jf S )Nz%s(arg=%s, lineno=%d))r&   r'   r(   r/   r   r   r   __repr__j   s    zByteCodeInst.__repr__c                 C   s&   | j drdS | j dkrdS dS dS )zREffect of the block stack
        Returns +1 (push), 0 (none) or -1 (pop)
        ZSETUP_   	POP_BLOCKr)   r   N)r&   
startswithr/   r   r   r   block_effectm   s
    
zByteCodeInst.block_effectN)__name__
__module____qualname____doc__	__slots__r-   propertyr0   r2   r8   r9   r=   r   r   r   r   r"   4   s   

r"   r:   NOPc                 c   s   d}t | }d }}||k r| | }|t7 }|tkr| | |B }ttD ]}|| ||  d| > O }qH|t7 }|tkr|dt > }qnd}|t7 }d}||||fV  |}qdS )zd
    Returns a 4-int-tuple of
    (bytecode offset, opcode, argument, offset of next bytecode).
    r      N)lenCODE_LENHAVE_ARGUMENTrangeARG_LENEXTENDED_ARG
NO_ARG_LEN)codeextended_argnr#   iopr'   jr   r   r   _unpack_opargs   s&    rS   c                 c   sJ   dt dtfV  | D ]2\}}}}|tkr.|t7 }|t |||t fV  qdS )zpPatch the bytecode stream.

    - Adds a NOP bytecode at the start to avoid jump target being at the entry.
    r   N)
OPCODE_NOP_FIXED_OFFSETr7   )Z	bc_streamr#   r%   r'   r,   r   r   r   _patched_opargs   s
    rV   c                   @   s8   e Zd Zdd Zdd Zdd Zdd ZeZd	d
 ZdS )ByteCodeIterc                 C   s    || _ ttt| j j| _d S r   )rM   iterrV   rS   co_code)r+   rM   r   r   r   r-      s    zByteCodeIter.__init__c                 C   s   | S r   r   r/   r   r   r   __iter__   s    zByteCodeIter.__iter__c                 C   s
   t | jS r   )r$   rX   r/   r   r   r   _fetch_opcode   s    zByteCodeIter._fetch_opcodec                 C   s$   |   \}}}}|t||||dfS )N)r#   r%   r'   r,   )r[   r"   r*   r   r   r   r$      s    
zByteCodeIter.nextc                 C   s4   d}t |D ]"}t| j\}}||d| > O }q|S )Nr   rE   )rI   r$   rX   )r+   sizebufrP   _offsetbyter   r   r   read_arg   s
    zByteCodeIter.read_argN)	r>   r?   r@   r-   rZ   r[   r$   __next__r`   r   r   r   r   rW      s   rW   c                   @   s\   e Zd ZdZdZdd Zedd Zdd Zd	d
 Z	dd Z
dd Zedd Zdd ZdS )ByteCodezF
    The decoded bytecode of a function, and related information.
    )func_idco_namesco_varnames	co_constsco_cellvarsco_freevarstablelabelsc                 C   s   |j }tdd t|jD }|d tt|}| || || _	|j
| _
|j| _|j| _|j| _|j| _|| _t|| _d S )Nc                 s   s   | ]}|t  V  qd S r   )rU   ).0xr   r   r   	<genexpr>   s     z$ByteCode.__init__.<locals>.<genexpr>r   )rM   setr   
findlabelsrY   addr   rW   _compute_linenorc   rd   re   rf   rg   rh   ri   sortedrj   )r+   rc   rM   rj   ri   r   r   r   r-      s    
zByteCode.__init__c                 C   sb   t |D ]"\}}|t }||kr
||| _q
|t j}| D ]}|jdkrV|j}q@||_q@|S )zI
        Compute the line numbers for all bytecode instructions.
        r   )r   findlinestartsrU   r(   values)clsri   rM   r#   r(   Z
adj_offsetZknowninstr   r   r   rq      s    

zByteCode._compute_linenoc                 C   s   t | j S r   )rX   ri   rt   r/   r   r   r   rZ      s    zByteCode.__iter__c                 C   s
   | j | S r   ri   r+   r#   r   r   r   __getitem__   s    zByteCode.__getitem__c                 C   s
   || j kS r   rw   rx   r   r   r   __contains__   s    zByteCode.__contains__c                    s*   fdd d  fddj D S )Nc                    s   | d j  jkrdS dS d S )Nr:   > )r#   rj   )rP   r/   r   r   label_marker   s    z#ByteCode.dump.<locals>.label_marker
c                 3   s    | ]}d  |f|  V  qdS )z
%s %10s	%sNr   )rk   rP   )r}   r   r   rm     s   z ByteCode.dump.<locals>.<genexpr>)joinri   itemsr/   r   )r}   r+   r   dump   s    zByteCode.dumpc              	   C   s   i }|j }|dtj}t|tr(|j}| D ]R}|jdkr0||j	 }	|	|kr0z||	 }
W n t
k
rx   ||	 }
Y nX |
||	< q0|D ]4}t|trtt|}|| |||j|j q|S )za
        Compute the globals used by the function with the given
        bytecode table.
        __builtins__LOAD_GLOBAL)__globals__r   r   builtins
isinstancer   __dict__rt   r&   r'   KeyErrorr   r   rW   update_compute_used_globalsrf   rd   )ru   funcri   rf   rd   dZglobsr   rv   namevaluecoZsubtabler   r   r   r     s,    




 zByteCode._compute_used_globalsc                 C   s   |  | jj| j| j| jS )zv
        Get a {name: value} map of the globals used by this code
        object and any nested code objects.
        )r   rc   r   ri   rf   rd   r/   r   r   r   get_used_globals$  s     zByteCode.get_used_globalsN)r>   r?   r@   rA   rB   r-   classmethodrq   rZ   ry   rz   r   r   r   r   r   r   r   rb      s   


rb   c                   @   sB   e Zd ZdZedZedd Zdd Z	dd Z
ed	d
 ZdS )FunctionIdentityz
    A function's identity and metadata.

    Note this typically represents a function whose bytecode is
    being compiled, not necessarily the top-level user function
    (the two might be distinct, e.g. in the `@generated_jit` case).
    r:   c                 C   s   t |}t|}t|}|s,td| z
|j}W n tk
rP   |j}Y nX |  }||_	||_
|dd |_||_t||_|jdkrtjn|jj|_t||_||_|j|_|j|_t|j|_t|j|_t| j }d!|j
||_"||_#|S )zD
        Create the FunctionIdentity of the given function.
        z %s does not provide its bytecode.r)   Nz{}${})$r   r   r   Zpysignaturer   ZByteCodeSupportErrorr@   AttributeErrorr>   r   func_qualnamesplit	func_namerM   inspect	getmodulemoduleZ_dynamic_modnamemodnameisgeneratorfunctionZis_generatorpysigco_filenamefilenameco_firstlinenoZfirstlinenorF   
parameters	arg_countlist	arg_namesr$   _unique_idsformatZunique_nameZ	unique_id)ru   pyfuncr   rM   r   r   r+   uidr   r   r   from_function7  s>    


zFunctionIdentity.from_functionc                 C   s   |  | jS )z:Copy the object and increment the unique counter.
        )r   r   r/   r   r   r   derivea  s    zFunctionIdentity.derivec                 C   s   t | jdS )4
        NOTE: part of ReduceMixin protocol
        )r   )dictr   r/   r   r   r   _reduce_statesf  s    zFunctionIdentity._reduce_statesc                 C   s
   |  |S )r   )r   )ru   r   r   r   r   _rebuildl  s    zFunctionIdentity._rebuildN)r>   r?   r@   rA   	itertoolscountr   r   r   r   r   r   r   r   r   r   r   -  s   

)r   )+collectionsr   r   r   r   r   typesr   r   Z
numba.corer   r   r   Znumba.core.utilsr	   r
   rU   r   r   r   	frozensethasjrelr6   hasjabsr7   r.   r1   rK   rH   objectr"   rG   rJ   rL   r&   indexrT   rS   rV   rW   rb   ZReduceMixinr   r   r   r   r   <module>   s6   	

Ff