o
    8ήc+                     @   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_info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.
    	__numba__Ngetattr)objattr r   :/tmp/pip-target-vg8gfxp4/lib/python/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 u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   
   | j tv S r   )r'   JUMP_OPSr-   r   r   r   is_jumpK      
zByteCodeInst.is_jumpc                 C   r0   r   )r'   TERM_OPSr2   r   r   r   is_terminatorO   r4   zByteCodeInst.is_terminatorc                 C   sr   | j sJ tdkr$| jtv r| j| jd  S | jtv sJ | jd d S | jtv r/| j| j S | jtv s6J | jS )N)   
   r   )r3   r	   r'   JREL_OPSr&   r)   JABS_OPSr2   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*   r2   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 )zREffect of the block stack
        Returns +1 (push), 0 (none) or -1 (pop)
        SETUP_   	POP_BLOCKr+   r   )r(   
startswithr2   r   r   r   block_effectm   s
   
zByteCodeInst.block_effectN)__name__
__module____qualname____doc__	__slots__r/   propertyr3   r6   r;   r<   rA   r   r   r   r   r$   4   s    

r$   r>   NOPc                 c   s    d}t | }d }}||k r[| | }|t7 }|tkrD| | |B }ttD ]}|| ||  d| > O }q%|t7 }|tkrC|dt > }qnd}|t7 }d}||||fV  |}||k sdS 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,   rW   c                 c   sL    dt dtfV  | D ]\}}}}|tv 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_OFFSETr:   )	bc_streamr%   r'   r)   r.   r   r   r   _patched_opargs   s   r[   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   )rQ   iterr[   rW   co_code)r-   rQ   r   r   r   r/      s   zByteCodeIter.__init__c                 C   s   | S r   r   r2   r   r   r   __iter__   s   zByteCodeIter.__iter__c                 C   s
   t | jS r   )r&   r]   r2   r   r   r   _fetch_opcode      
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   rI   )rM   r&   r]   )r-   sizebufrT   _offsetbyter   r   r   read_arg   s
   zByteCodeIter.read_argN)	rB   rC   rD   r/   r_   r`   r&   __next__rf   r   r   r   r   r\      s    r\   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   )rY   ).0xr   r   r   	<genexpr>   s    z$ByteCode.__init__.<locals>.<genexpr>r   )rQ   setr   
findlabelsr^   addr   r\   _compute_linenori   rj   rk   rl   rm   rn   ro   sortedrp   )r-   ri   rQ   rp   ro   r   r   r   r/      s   
zByteCode.__init__c                 C   sb   t |D ]\}}|t }||v r||| _q|t j}| D ]}|jdkr+|j}q ||_q |S )zI
        Compute the line numbers for all bytecode instructions.
        r   )r   findlinestartsrY   r*   values)clsro   rQ   r%   r*   
adj_offsetknowninstr   r   r   rw      s   


zByteCode._compute_linenoc                 C   s   t | j S r   )r]   ro   rz   r2   r   r   r   r_      s   zByteCode.__iter__c                 C   s
   | j | S r   ro   r-   r%   r   r   r   __getitem__   ra   zByteCode.__getitem__c                 C   s
   || j v S r   r   r   r   r   r   __contains__   ra   zByteCode.__contains__c                    s*   fdd d  fddj D S )Nc                    s   | d j  jv r
dS dS )Nr>   > )r%   rp   )rT   r2   r   r   label_marker   s   z#ByteCode.dump.<locals>.label_marker
c                 3   s"    | ]}d  |f|  V  qdS )z
%s %10s	%sNr   )rq   rT   )r   r   r   rs     s    z ByteCode.dump.<locals>.<genexpr>)joinro   itemsr2   r   )r   r-   r   dump   s   zByteCode.dumpc              	   C   s   i }|j }|dtj}t|tr|j}| D ](}|jdkr@||j	 }	|	|vr@z||	 }
W n t
y;   ||	 }
Y nw |
||	< q|D ]}t|tr]tt|}|| |||j|j qC|S )za
        Compute the globals used by the function with the given
        bytecode table.
        __builtins__LOAD_GLOBAL)__globals__r   r   builtins
isinstancer   __dict__rz   r(   r)   KeyErrorr   r   r\   update_compute_used_globalsrl   rj   )r{   funcro   rl   rj   dglobsr   r~   namevaluecosubtabler   r   r   r     s0   



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   ri   r   ro   rl   rj   r2   r   r   r   get_used_globals$  s   zByteCode.get_used_globalsN)rB   rC   rD   rE   rF   r/   classmethodrw   r_   r   r   r   r   r   r   r   r   r   rh      s    


rh   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y'   |j}Y nw |  }||_	||_
|dd |_||_t||_|jdu rJt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   pysignaturer   ByteCodeSupportErrorrD   AttributeErrorrB   r   func_qualnamesplit	func_namerQ   inspect	getmodulemodule_dynamic_modnamemodnameisgeneratorfunctionis_generatorpysigco_filenamefilenameco_firstlinenofirstlinenorJ   
parameters	arg_countlist	arg_namesr&   _unique_idsformatunique_name	unique_id)r{   pyfuncr   rQ   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   r2   r   r   r   derivea  s   zFunctionIdentity.derivec                 C   s   t | jdS )4
        NOTE: part of ReduceMixin protocol
        )r   )dictr   r2   r   r   r   _reduce_statesf  s   zFunctionIdentity._reduce_statesc                 C   s
   |  |S )r   )r   )r{   r   r   r   r   _rebuildl  s   
zFunctionIdentity._rebuildN)rB   rC   rD   rE   	itertoolscountr   r   r   r   r   r   r   r   r   r   r   -  s    

)r   )+collectionsr   r   r   r   r   typesr   r   
numba.corer   r   r   numba.core.utilsr	   r
   rY   r   r   r!   	frozensethasjrelr9   hasjabsr:   r1   r5   rO   rL   objectr$   rK   rN   rP   r(   indexrX   rW   r[   r\   rh   ReduceMixinr   r   r   r   r   <module>   s8    
	
Ff