o
    8ήc                     @   sP  d Z ddlmZ ddlZddl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 dd	lmZ eeZd
ZedkrEendZedhZe	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	G dd deZ edg dZ!G dd deZ"edg dZ#dd Z$d d! Z%G d"d# d#eZ&G d$d% d%eZ'dS )&z)
Implement python 3.8+ bytecode analysis
    )pformatN)
namedtupledefaultdictdeque)total_ordering)
UniqueDict	PYVERSION)NEW_BLOCKERSCFGraph)Loc)UnsupportedError            
LOAD_CONSTc                   @   sD   e Zd ZdZeh dZdd Zdd Zdd Zd	d
 Z	dd Z
dS )	BlockKindz?Kinds of block to make related code safer than just `str`.
    >   TRYLOOPWITHEXCEPTFINALLYWITH_FINALLYc                 C   s   || j v sJ || _d S N)_members_value)selfvalue r   :/tmp/pip-target-vg8gfxp4/lib/python/numba/core/byteflow.py__init__$   s   
zBlockKind.__init__c                 C   s   t t| | jfS r   )hashtyper   r   r   r   r    __hash__(      zBlockKind.__hash__c                 C   s(   t |tr| j|jk S tdt|Nzcannot compare to {!r}
isinstancer   r   	TypeErrorformatr#   r   otherr   r   r    __lt__+      
zBlockKind.__lt__c                 C   s(   t |tr| j|jkS tdt|r'   r(   r,   r   r   r    __eq__1   r/   zBlockKind.__eq__c                 C   s   d | jS )NzBlockKind({}))r+   r   r$   r   r   r    __repr__7      zBlockKind.__repr__N)__name__
__module____qualname____doc__	frozensetr   r!   r%   r.   r0   r1   r   r   r   r    r      s    r   c                   @   s   e Zd Zdd Zdd ZdS )_lazy_pformatc                 O   s   || _ || _d S r   )argskwargs)r   r9   r:   r   r   r    r!   <   s   
z_lazy_pformat.__init__c                 C   s   t | ji | jS r   )r   r9   r:   r$   r   r   r    __str__@   r&   z_lazy_pformat.__str__N)r3   r4   r5   r!   r;   r   r   r   r    r8   ;   s    r8   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )FlowziData+Control Flow analysis.

    Simulate execution to recover dataflow and controlflow information.
    c                 C   s"   t d|  || _t | _d S )Nzbytecode dump:
%s)_loggerdebugdump	_bytecoder   block_infos)r   bytecoder   r   r    r!   I   s   zFlow.__init__c                 C   s  t | jdddd}t| jjjd}|j| t }|jrt	d|j |j
 }||jvrt	d|j |||j< 	 || | rEnj| r| jtvr|j| jd |d	}|| |j}i }||d
 krv||d
  |d< |d }tdttdti|d  |d< ||d< |jdd|d i| n|  | |r| | |  nq;t	d|j  |j!| |" }	|j#|	 |js| $|j | %| t&|jdd dD ]}t'| | j(|j< }
t	d||
 qdS )a  Run a trace over the bytecode over all reachable path.

        The trace starts at bytecode offset 0 and gathers stack and control-
        flow information by partially interpreting each bytecode.
        Each ``State`` instance in the trace corresponds to a basic-block.
        The State instances forks when a jump instruction is encountered.
        A newly forked state is then added to the list of pending states.
        The trace ends when there are no more pending states.
        r   r   rB   pcnstack
blockstack)debug_filenamezpending: %sz	stack: %sTrD   r   entry_stacknpophandlerr   r   kindnpushextra_blockrD   endzend state. edges=%sc                 S      | j S r   )
pc_initial)xr   r   r    <lambda>   s    zFlow.run.<locals>.<lambda>)keyzblock_infos %s:
%sN))Stater@   TraceRunnerfunc_idfilenamependingappendr   r=   r>   popleftfinished_stackrQ   dispatchhas_terminatedhas_active_tryget_instopname_NO_RAISE_OPSforknextget_top_blockpop_block_and_abovestack_depthr   _EXCEPT_STACK_OFFSET_FINALLY_POP
advance_pc_is_implicit_new_block_guard_with_assplit_new_blockoutgoing_edgesaddget_outgoing_statesextend
_build_cfg_prune_phissortedadapt_state_infosrA   )r   
firststaterunnerfirst_encounterstatetryblkrE   r:   rK   
out_statessir   r   r    runN   sh   









 -
zFlow.runc                 C   sd   t  }|D ]
}|j}|| q|D ]}|jD ]}||j|jd qq|d |  || _d S )Nr   )	r
   rQ   add_nodero   add_edgerD   set_entry_pointprocesscfgraph)r   
all_statesgraphrz   bedger   r   r    rs      s   


zFlow._build_cfgc           	         s   t ddd fdd} fdd} fdd	}fd
d}| \} t dt| | \}}|| ||| t ddd d S )Nz
Prune PHIs<   -c                     sR   t t} t } jD ]}t|j}t|j}| |  ||@ O  < ||O }q
| |fS r   )r   setr\   
_used_regs_phis)	used_phisphi_setrz   usedphisrx   r   r    get_used_phis_per_state   s   



z1Flow._prune_phis.<locals>.get_used_phis_per_statec                     sv   i } t t}jD ]}|j D ]\}}| vr|| |< || ||f qq	tdt|  tdt| | |fS )Nz
defmap: %szphismap: %s)	r   r   r\   _outgoing_phisitemsrp   r=   r>   r8   )defmapphismaprz   phirhsr   rx   r   r    find_use_defs   s   
z'Flow._prune_phis.<locals>.find_use_defsc                    s   t t}	 d}tt|  D ]0\}}tt|D ]\}}| v r0|| | O }|| ||f q|| }||@ r?||8 }d}qtdt|  |sLdS q)znAn iterative dataflow algorithm to find the definition
            (the source) of each PHI node.
            TFzchanging phismap: %sN)	r   r   ru   listr   rp   r=   r>   r8   )r   	blacklistchangingr   defsitesr   rz   	to_remove)r   r   r    propagate_phi_map   s$   z+Flow._prune_phis.<locals>.propagate_phi_mapc                    s   i }|   D ]\}}|D ]}|| ||< qqtdt| tt}|D ]}|| D ]
\}}||| |< q*q$tdt|  jD ]}|j  |j	||  qAd S )Nzkeep phismap: %sznew_out: %s)
r   r=   r>   r8   r   dictr\   r   clearupdate)r   r   keeprz   used_setr   new_outr   r   r   r    apply_changes   s    

z'Flow._prune_phis.<locals>.apply_changeszUsed_phis: %szDONE Prune PHIs)r=   r>   centerr8   )	r   rx   r   r   r   r   r   r   r   r   r   r    rt      s   


zFlow._prune_phisc                 C   s,   |  }|j| jjv rdS |jtv rdS dS )NTF)ra   offsetr@   labelsrb   r	   r   rz   instr   r   r    rl      s   
zFlow._is_implicit_new_blockc                 C   s<   |  }|jdkr| j|j j}|dkrd}t|dS dS )zChecks if the next instruction after a SETUP_WITH is something other
        than a POP_TOP, if it is something else it'll be some sort of store
        which is not supported (this corresponds to `with CTXMGR as VAR(S)`).
SETUP_WITHPOP_TOPzGThe 'with (context manager) as (variable):' construct is not supported.N)ra   rb   r@   re   r   )r   rz   current_instnext_opmsgr   r   r    rm      s   
zFlow._guard_with_asN)
r3   r4   r5   r6   r!   r~   rs   rt   rl   rm   r   r   r   r    r<   D   s    JM
r<   c                   @   s  e Zd 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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d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!e!Z"e!Z#d>d? Z$e$Z%e$Z&d@dA Z'dBdC Z(dDdE Z)dFdG Z*dHdI Z+dJdK Z,dLdM Z-dNdO Z.dPdQ Z/dRdS Z0dTdU Z1dVdW Z2dXdY Z3dZd[ Z4d\d] Z5d^d_ Z6d`da Z7dbdc Z8ddde Z9dfdg Z:dhdi Z;djdk Z<dldm Z=dndo Z>dpdq Z?drds Z@dtdu ZAdvdw ZBdxdy ZCdzd{ ZDd|d} ZEd~d ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUdd ZVdd ZWdd ZXdd ZYeYZZeYZ[eYZ\eYZ]dd Z^e^Z_e^Z`e^Zae^Zbe^Zce^Zde^Zee^Zfe^Zge^Zhe^Zie^Zje^Zke^Zle^Zme^Zne^Zoe^Zpe^Zqe^Zre^Zse^Zte^Zue^Zve^Zwe^Zxe^Zye^Zze^Z{e^Z|e^Z}dddZ~dd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )rV   zLTrace runner contains the states for the trace and the opcode dispatch.
    c                 C   s   || _ t | _t | _d S r   )rG   r   rY   r   r\   )r   rG   r   r   r    r!     s   zTraceRunner.__init__c                 C   s   t | j|S r   )r   rG   )r   linenor   r   r    get_debug_loc  r2   zTraceRunner.get_debug_locc                 C   sn   |  }td|j| td|j t| d|jd }|d ur(||| d S d|j }t|| 	|j
d)Nzdispatch pc=%s, inst=%szstack %szop_{}z$Use of unsupported opcode (%s) foundloc)ra   r=   r>   _pcr]   getattrr+   rb   r   r   r   )r   rz   r   fnr   r   r   r    r^     s   
zTraceRunner.dispatchc                 C      | | d S r   rZ   r   r   r   r    op_NOP     zTraceRunner.op_NOPc                 C   sZ   |j dkrd}t|| |jd| }| }| }|j||||d || dS )aF  
        FORMAT_VALUE(flags): flags argument specifies format spec which is
        not supported yet. Currently, we just call str() on the value.
        Pops a value from stack and pushes results back.
        Required for supporting f-strings.
        https://docs.python.org/3/library/dis.html#opcode-FORMAT_VALUE
        r   z*format spec in f-strings not supported yetr   )r   resstrvarN)argr   r   r   pop	make_temprZ   push)r   rz   r   r   r   r   r   r   r   r    op_FORMAT_VALUE"  s   
zTraceRunner.op_FORMAT_VALUEc                    st   |j }tt fddt|D }|dkr  g}n fddt|d D } j|||d  |d  dS )	z
        BUILD_STRING(count): Concatenates count strings from the stack and
        pushes the resulting string onto the stack.
        Required for supporting f-strings.
        https://docs.python.org/3/library/dis.html#opcode-BUILD_STRING
        c                       g | ]}   qS r   r   .0_rz   r   r    
<listcomp>;      z/TraceRunner.op_BUILD_STRING.<locals>.<listcomp>r   c                    r   r   r   r   r   r   r    r   @  r   r   )stringstmpsNr   r   reversedranger   rZ   r   )r   rz   r   countr   r   r   r   r    op_BUILD_STRING3  s   zTraceRunner.op_BUILD_STRINGc                 C   s   |   d S r   r   r   r   r   r    
op_POP_TOPD  r2   zTraceRunner.op_POP_TOPc                 C   $   |  }|j||d || d S Nr   r   rZ   r   r   rz   r   r   r   r   r    op_LOAD_GLOBALG     zTraceRunner.op_LOAD_GLOBALc                 C   r   r   r   r   r   r   r    op_LOAD_DEREFL  r   zTraceRunner.op_LOAD_DEREFc                 C   s&   | d}|| |j||d d S )Nconstr   )r   r   rZ   r   r   r   r    op_LOAD_CONSTQ  s   

zTraceRunner.op_LOAD_CONSTc                 C   .   |  }| }|j|||d || d S )N)itemr   r   r   rZ   r   )r   rz   r   r   r   r   r   r    op_LOAD_ATTRV     zTraceRunner.op_LOAD_ATTRc                 C   s0   | |}||}|j||d || d S r   )get_varnamer   rZ   r   )r   rz   r   namer   r   r   r    op_LOAD_FAST\  s   

zTraceRunner.op_LOAD_FASTc                 C   r   r   r   r   r   r   r    op_DELETE_FASTb  r   zTraceRunner.op_DELETE_FASTc                 C      |  }|j||d d S )N)targetr   rZ   )r   rz   r   r   r   r   r    op_DELETE_ATTRe     zTraceRunner.op_DELETE_ATTRc                 C   s$   |  }|  }|j|||d d S )N)r   r   r   )r   rz   r   r   r   r   r   r    op_STORE_ATTRi     zTraceRunner.op_STORE_ATTRc                 C   r   N)r   r   r   rz   r   r   r   r   r    op_STORE_DEREFn  r   zTraceRunner.op_STORE_DEREFc                 C   r   r   r   r   r   r   r    op_STORE_FASTr  r   zTraceRunner.op_STORE_FASTc           	   	   C   V   |  }|  }| }| }| }| }|j|||||||d || dS )z"
        TOS = TOS1[TOS:]
        )basestartr   slicevarindexvarnonevarNr   	r   rz   r   tostos1r   r   r   r   r   r   r    
op_SLICE_1v      	zTraceRunner.op_SLICE_1c           	   	   C   r   )z"
        TOS = TOS1[:TOS]
        )r   stopr   r   r   r   Nr   r   r   r   r    
op_SLICE_2  r   zTraceRunner.op_SLICE_2c           	   	   C   sV   |  }|  }|  }| }| }| }|j|||||||d || dS )z&
        TOS = TOS2[TOS1:TOS]
        )r   r   r   r   r   r   Nr   )	r   rz   r   r   r   tos2r   r   r   r   r   r    
op_SLICE_3  r   zTraceRunner.op_SLICE_3c                 C   sB   |  }|  }| }| }| }|j||||||d dS )z
        TOS[:] = TOS1
        )r   r   r   r   r   Nr   r   rZ   )r   rz   r   r   r   r   r   r   r   r   r    op_STORE_SLICE_0     
zTraceRunner.op_STORE_SLICE_0c           	   	   C   sL   |  }|  }|  }| }| }| }|j|||||||d dS )z#
        TOS1[TOS:] = TOS2
        )r   r   r   r   r   r   Nr  	r   rz   r   r   r   r   r   r   r   r   r   r    op_STORE_SLICE_1     
zTraceRunner.op_STORE_SLICE_1c           	   	   C   sL   |  }|  }|  }| }| }| }|j|||||||d dS )z#
        TOS1[:TOS] = TOS2
        )r   r   r   r   r   r   Nr  r  r   r   r    op_STORE_SLICE_2  r  zTraceRunner.op_STORE_SLICE_2c           	   	   C   sL   |  }|  }|  }|  }| }| }|j|||||||d dS )z'
        TOS2[TOS1:TOS] = TOS3
        )r   r   r   r   r   r   Nr  )	r   rz   r   r   r   r  r   r   r   r   r   r    op_STORE_SLICE_3  r  zTraceRunner.op_STORE_SLICE_3c                 C   s8   |  }| }| }| }|j|||||d dS )z
        del TOS[:]
        )r   r   r   r   Nr  )r   rz   r   r   r   r   r   r   r   r    op_DELETE_SLICE_0  s   
zTraceRunner.op_DELETE_SLICE_0c                 C   B   |  }|  }| }| }| }|j||||||d dS )z 
        del TOS1[TOS:]
        )r   r   r   r   r   Nr  r   rz   r   r   r   r   r   r   r   r   r    op_DELETE_SLICE_1  r  zTraceRunner.op_DELETE_SLICE_1c                 C   r  )z 
        del TOS1[:TOS]
        )r   r   r   r   r   Nr  r  r   r   r    op_DELETE_SLICE_2"  r  zTraceRunner.op_DELETE_SLICE_2c                 C   sB   |  }|  }|  }| }| }|j||||||d dS )z$
        del TOS2[TOS1:TOS]
        )r   r   r   r   r   Nr  )r   rz   r   r   r   r  r   r   r   r   r    op_DELETE_SLICE_34  s   

zTraceRunner.op_DELETE_SLICE_3c                 C   s   |j }|dkr| }| }|}|}d}n|dkr-| }| }| }	|	}|}|}ntd| }
| }|j||||||
d || dS )z<
        slice(TOS1, TOS) or slice(TOS2, TOS1, TOS)
           Nr   unreachable)r   r   stepr   r   )r   r   	Exceptionr   rZ   r   )r   rz   r   argcr   r   r   r   r  r  r   r   r   r   r    op_BUILD_SLICEB  s*   zTraceRunner.op_BUILD_SLICEc                 C   sL   |  }|j||d | }|j}|j|d ||kr$|j|d d S d S )NpredrH   )r   rZ   get_jump_targetre   rd   )r   rz   r   r  target_inst	next_instr   r   r    _op_POP_JUMP_IF]  s   zTraceRunner._op_POP_JUMP_IFc                 C   s:   |  }|j||d |j|jdd |j| d d S )Nr  r   rD   rJ   rH   )get_tosrZ   rd   re   r  )r   rz   r   r  r   r   r    _op_JUMP_IF_OR_POPl  s   zTraceRunner._op_JUMP_IF_OR_POPc                 C      | | |j| d d S NrH   rZ   rd   r  r   r   r   r    op_JUMP_FORWARDu     
zTraceRunner.op_JUMP_FORWARDc                 C   r   r!  r"  r   r   r   r    op_JUMP_ABSOLUTEy  r$  zTraceRunner.op_JUMP_ABSOLUTEc                 C   s4   | dd }|j||d |  |j|d d S )Nr   rO   )rO   rH   )rf   rZ   	pop_blockrd   )r   rz   r   rO   r   r   r    op_BREAK_LOOP}  s   zTraceRunner.op_BREAK_LOOPc                 C   s$   |j || | d |  d S )N)retvalcastval)rZ   r   r   	terminater   r   r   r    op_RETURN_VALUE  s   zTraceRunner.op_RETURN_VALUEc                 C   r   N)r   r   r   r   rz   r   valr   r   r   r    op_YIELD_VALUE  r   zTraceRunner.op_YIELD_VALUEc                 C   s~   t |dd u|dd ug}|jdkr$d }|r#td| |jdn|jdkr.| }ntd|j||d |	  d S )	Nr   r   r   z4The re-raising of an exception is not yet supported.r   r   z)Multiple argument raise is not supported.exc)
anyrf   r   r   r   r   r   
ValueErrorrZ   r*  )r   rz   r   in_exc_blockr1  r   r   r    op_RAISE_VARARGS  s"   



zTraceRunner.op_RAISE_VARARGSc                 C   s@   g }t tD ]}| }|| || q|j||d d S )N)temps)r   ri   r   rZ   r   )r   rz   r   r6  itmpr   r   r    op_BEGIN_FINALLY  s   
zTraceRunner.op_BEGIN_FINALLYc                 C   s   |  }||d  d S )NrI   )r&  reset_stackr   rz   r   blkr   r   r    op_END_FINALLY  r   zTraceRunner.op_END_FINALLYc                 C   s&   |j dkrd}t|| |jdd S )Nr   zGUnsupported use of a bytecode related to try..finally or a with-contextr   )r   r   r   r   )r   rz   r   r   r   r   r    op_POP_FINALLY  s   
zTraceRunner.op_POP_FINALLYc                 C   s   d S r   r   r   r   r   r    op_CALL_FINALLY  s   zTraceRunner.op_CALL_FINALLYc                 C   r   r   r   r   r   r   r    op_WITH_CLEANUP_START     z!TraceRunner.op_WITH_CLEANUP_STARTc                 C   r   r   r   r   r   r   r    op_WITH_CLEANUP_FINISH  rA  z"TraceRunner.op_WITH_CLEANUP_FINISHc                 C   s   | |jd| d d S )Nr   rL   rO   )
push_block
make_blockr  r   r   r   r    op_SETUP_LOOP  s   zTraceRunner.op_SETUP_LOOPc                 C   s   |  }| }|jdd}|j|||d tdk r&||jd| d || || ||jd| d |j|j	d d S )	Nsetup_with_exitfn)prefix)contextmanagerexitfn)r   	   r   rC  r   rH   )
r   r   rZ   r   rD  rE  r  r   rd   re   )r   rz   r   cmyieldedrJ  r   r   r    op_SETUP_WITH  s(   

zTraceRunner.op_SETUP_WITHc                 C   s0   |j |d dd}|j||j d|d|dd d S )NF)rL   rO   r:  r   )rL   rO   r:  rK   )rD   rN   )rE  rd   )r   rL   rz   re   rO   handler_blockr   r   r    
_setup_try  s   
zTraceRunner._setup_tryc                 C   &   | | | jd||j| d d S )Nr   re   rO   rZ   rP  re   r  r   r   r   r    op_SETUP_EXCEPT  s   

zTraceRunner.op_SETUP_EXCEPTc                 C   rQ  )Nr   rR  rS  r   r   r   r    op_SETUP_FINALLY  s   

zTraceRunner.op_SETUP_FINALLYc                 C   sh   |  }|d tdtdhvrtd|d | |jd|  |  |  |j|jd d S )NrL   r   r   z&POP_EXCEPT got an unexpected block: {}r   rH   )	r&  r   r   r+   r   r   r   rd   re   r;  r   r   r    op_POP_EXCEPT  s   
zTraceRunner.op_POP_EXCEPTc                 C   sX   |  }|d tdkr|j|dd n|d tdkr#|j|dd |j|jd d S )NrL   r   try)rL   r   withrH   )r&  r   rZ   rd   re   r;  r   r   r    op_POP_BLOCK  s   zTraceRunner.op_POP_BLOCKc                 C   s8   |  }|  }| }|j||||d || d S )N)indexr   r   r   )r   rz   r   rZ  r   r   r   r   r    op_BINARY_SUBSCR  
   zTraceRunner.op_BINARY_SUBSCRc                 C   s.   |  }|  }|  }|j||||d d S )N)r   rZ  r   r   )r   rz   r   rZ  r   r   r   r   r    op_STORE_SUBSCR  s   zTraceRunner.op_STORE_SUBSCRc                 C   s$   |  }|  }|j|||d d S )N)r   rZ  r   )r   rz   r   rZ  r   r   r   r    op_DELETE_SUBSCR%  r   zTraceRunner.op_DELETE_SUBSCRc                    sT   |j }tt fddt|D }  }  } j||||d  | d S )Nc                    r   r   r   r   r   r   r    r   ,  r   z0TraceRunner.op_CALL_FUNCTION.<locals>.<listcomp>)funcr9   r   )r   r   r   r   r   r   rZ   r   )r   rz   r   nargr9   r_  r   r   r   r    op_CALL_FUNCTION*  s   zTraceRunner.op_CALL_FUNCTIONc                    s^   |j }  }tt fddt|D }  }  } j|||||d  | d S )Nc                    r   r   r   r   r   r   r    r   6  r   z3TraceRunner.op_CALL_FUNCTION_KW.<locals>.<listcomp>)r_  r9   namesr   )r   r   r   r   r   r   rZ   r   )r   rz   r   r`  rb  r9   r_  r   r   r   r    op_CALL_FUNCTION_KW3  s   zTraceRunner.op_CALL_FUNCTION_KWc                 C   sp   |j d@ rtdkrd}t||j d@ r| }nd }| }| }| }|j|||||d || d S )Nr   )r   
   z,CALL_FUNCTION_EX with **kwargs not supported)r_  varargvarkwargr   )r   r   r   r   r   rZ   r   )r   rz   r   errmsgrf  re  r_  r   r   r   r    op_CALL_FUNCTION_EX=  s   

zTraceRunner.op_CALL_FUNCTION_EXc                    sp    fddt |D }|   fddt |D } j|||d |D ]} | q$|D ]} | q.d S )Nc                    r   r   r   r   r   r   r    r   L  r   z)TraceRunner._dup_topx.<locals>.<listcomp>c                    r   r   r   r   r   r   r    r   P  r   )origduped)r   reverserZ   r   )r   rz   r   r   ri  rj  r.  r   r   r    	_dup_topxK  s   zTraceRunner._dup_topxc                 C   s<   |j }d|  krdksJ d J d| ||| d S )Nr      zInvalid DUP_TOPX count)r   rl  )r   rz   r   r   r   r   r    op_DUP_TOPXW  s   $zTraceRunner.op_DUP_TOPXc                 C      | j ||dd d S )Nr   r   rl  r   r   r   r    
op_DUP_TOP\     zTraceRunner.op_DUP_TOPc                 C   ro  )Nr  rp  rq  r   r   r   r    op_DUP_TOP_TWO_  rs  zTraceRunner.op_DUP_TOP_TWOc                 C   s(   |  }|  }|| || d S r   r   r   )r   rz   r   firstsecondr   r   r    
op_ROT_TWOb  s   
zTraceRunner.op_ROT_TWOc                 C   s:   |  }|  }|  }|| || || d S r   ru  )r   rz   r   rv  rw  thirdr   r   r    op_ROT_THREEh  s   

zTraceRunner.op_ROT_THREEc                 C   sL   |  }|  }|  }|  }|| || || || d S r   ru  )r   rz   r   rv  rw  ry  forthr   r   r    op_ROT_FOURp  s   


zTraceRunner.op_ROT_FOURc                    sZ   |j }  } fddt|D }  } j||||d t|D ]} | q#d S )Nc                    r   r   r   r   r   r   r    r   }  r   z2TraceRunner.op_UNPACK_SEQUENCE.<locals>.<listcomp>)iterablestorestupleobj)r   r   r   r   rZ   r   r   )r   rz   r   r   r}  r~  r  str   r   r    op_UNPACK_SEQUENCEz  s   zTraceRunner.op_UNPACK_SEQUENCEc                    J   |j }tt fddt|D }  } j|||d  | d S )Nc                    r   r   r   r   r   r   r    r     r   z.TraceRunner.op_BUILD_TUPLE.<locals>.<listcomp>r   r   r   )r   rz   r   r   r   tupr   r   r    op_BUILD_TUPLE  
   zTraceRunner.op_BUILD_TUPLEc                    s|   t t fddt|jD } fddtt|d D }t|dk}|r,  g} j||||d  |d  d S )Nc                    r   r   r   r   r   r   r    r     r   z3TraceRunner._build_tuple_unpack.<locals>.<listcomp>c                    r   r   r   r   r   r   r    r     r   r   )tuplesr6  	is_assignr   )r   r   r   r   lenr   rZ   r   )r   rz   r   r  r6  r  r   r   r    _build_tuple_unpack  s    
zTraceRunner._build_tuple_unpackc                 C      |  || d S r   r  r   r   r   r    op_BUILD_TUPLE_UNPACK_WITH_CALL     z+TraceRunner.op_BUILD_TUPLE_UNPACK_WITH_CALLc                 C   r  r   r  r   r   r   r    op_BUILD_TUPLE_UNPACK     z!TraceRunner.op_BUILD_TUPLE_UNPACKc                 C   r   )N)
const_listr   r   )r   rz   r   r   r   r   r   r    op_LIST_TO_TUPLE  s   zTraceRunner.op_LIST_TO_TUPLEc                    sj      }tt fddt|jD } fddt|jD }  } j|||||d  | d S )Nc                    r   r   r   r   r   r   r    r     r   z6TraceRunner.op_BUILD_CONST_KEY_MAP.<locals>.<listcomp>c                    r   r   r   r   r   r   r    r     r   )keyskeytmpsvaluesr   )r   r   r   r   r   r   rZ   r   )r   rz   r   r  valsr  r   r   r   r    op_BUILD_CONST_KEY_MAP  s    z"TraceRunner.op_BUILD_CONST_KEY_MAPc                    r  )Nc                    r   r   r   r   r   r   r    r     r   z-TraceRunner.op_BUILD_LIST.<locals>.<listcomp>r  r   )r   rz   r   r   r   lstr   r   r    op_BUILD_LIST  r  zTraceRunner.op_BUILD_LISTc                 C   @   |  }|j}||}| }| }|j|||||d d S )N)r   r   	appendvarr   r   r   peekr   rZ   )r   rz   r   r   rZ  r   r  r   r   r   r    op_LIST_APPEND     

zTraceRunner.op_LIST_APPENDc                 C   r  )N)r   r   	extendvarr   r  )r   rz   r   r   rZ  r   r  r   r   r   r    op_LIST_EXTEND  r  zTraceRunner.op_LIST_EXTENDc           	      C   sj   |  }|j}g }t|D ]}| | }}|||f q|j||d d d ||d || d S )Nr   )r   sizer   )r   r   r   r   rZ   r   )	r   rz   r   dctr   r   r7  vkr   r   r    op_BUILD_MAP  s   zTraceRunner.op_BUILD_MAPc                 C   sf   |  }|  }tdk r||fn||f\}}|j}||}| }	| }
|j|||||	|
d d S )Nr   )r   rT   r   
setitemvarr   )r   r   r   r  r   rZ   )r   rz   r   TOSTOS1rT   r   rZ  r   r  r   r   r   r    
op_MAP_ADD  s   

zTraceRunner.op_MAP_ADDc                    r  )Nc                    r   r   r   r   r   r   r    r     r   z,TraceRunner.op_BUILD_SET.<locals>.<listcomp>r  r   )r   rz   r   r   r   r   r   r   r    op_BUILD_SET  s
   zTraceRunner.op_BUILD_SETc                 C   r  N)r   r   	updatevarr   r  r   rz   r   r   rZ  r   r  r   r   r   r    op_SET_UPDATE  r  zTraceRunner.op_SET_UPDATEc                 C   r  r  r  r  r   r   r    op_DICT_UPDATE  r  zTraceRunner.op_DICT_UPDATEc                 C   r   r,  r   )r   rz   r   r   r   r   r   r    op_GET_ITER  r   zTraceRunner.op_GET_ITERc                 C   sf   |  }| }| }| }|j|||||d || | }|j|dd |j|jd d S )N)iteratorpairindvalr  r  r  rH   )r  r   rZ   r   r  rd   re   )r   rz   r   r  r  r  r  rO   r   r   r    op_FOR_ITER  s   
zTraceRunner.op_FOR_ITERc                 C   s   dS )a(  Pops TOS. If TOS was not None, raises an exception. The kind
        operand corresponds to the type of generator or coroutine and
        determines the error message. The legal kinds are 0 for generator,
        1 for coroutine, and 2 for async generator.

        New in version 3.10.
        Nr   r   r   r   r    op_GEN_START  s   	zTraceRunner.op_GEN_STARTc                 C   r   r,  r   r-  r   r   r    _unaryop  r   zTraceRunner._unaryopc                 C   s8   |  }|  }| }|j||||d || d S )N)lhsr   r   r   )r   rz   r   r   r  r   r   r   r    	_binaryop$  r\  zTraceRunner._binaryopFc              
   C   sP  |  }|  }d  } } }}	tdk rl|jd@ }
|jd? d@ }|jd? d@ }|r-|  }|dkr5|  }|dkrUg }t|D ]}|  }|  }|||f q?t|}|
rkg }	t|
D ]	}|	|   q]t|	}	n$|jd@ ru|  }|jd@ r~|  }|jd@ r|  }|jd	@ r|  }	| }|j|||||||	|d
 || d S )N)r   r      r      i  r      r  r   )r   codeclosureannotations
kwdefaultsdefaultsr   )r   r   r   r   rZ   tupler   r   )r   rz   r   MAKE_CLOSUREr   r  r  r  r  r  num_posdefaultsnum_kwdefaultsnum_annotationsr7  r  r  r   r   r   r    op_MAKE_FUNCTIONO  sX   





zTraceRunner.op_MAKE_FUNCTIONc                 C   ro  )NT)r  )r  r   r   r   r    op_MAKE_CLOSURE}  rs  zTraceRunner.op_MAKE_CLOSUREc                 C   r   r   r   r   r   r   r    op_LOAD_CLOSURE  r   zTraceRunner.op_LOAD_CLOSUREc                 C   s&   | d}|j||d || d S )Nassertion_errorr   r   r   r   r   r    op_LOAD_ASSERTION_ERROR  s   
z#TraceRunner.op_LOAD_ASSERTION_ERRORc                 C   sN   | d}| }| }|j||||d |j|jd |j| d d S )N	predicate)r  r   r   rH   )r   r   rZ   rd   re   r  )r   rz   r   r  r   r   r   r   r    op_JUMP_IF_NOT_EXC_MATCH  s   
z$TraceRunner.op_JUMP_IF_NOT_EXC_MATCHc                 C   s"   |  }|j||d |  d S )Nr0  )r   rZ   r*  )r   rz   r   r1  r   r   r    
op_RERAISE  s   zTraceRunner.op_RERAISEc                 C   r  r   )r   r   r   r   r    op_LOAD_METHOD  r  zTraceRunner.op_LOAD_METHODc                 C   r  r   )ra  r   r   r   r    op_CALL_METHOD  r  zTraceRunner.op_CALL_METHODN)F)r3   r4   r5   r6   r!   r   r^   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r	  r
  r  r  r  r  r  r  op_POP_JUMP_IF_TRUEop_POP_JUMP_IF_FALSEr  op_JUMP_IF_FALSE_OR_POPop_JUMP_IF_TRUE_OR_POPr#  r%  r'  r+  r/  r5  r9  r=  r>  r?  r@  rB  rF  rN  rP  rT  rU  rV  rY  r[  r]  r^  ra  rc  rh  rl  rn  rr  rt  rx  rz  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  op_UNARY_NEGATIVEop_UNARY_POSITIVEop_UNARY_NOTop_UNARY_INVERTr  op_COMPARE_OPop_IS_OPop_CONTAINS_OPop_INPLACE_ADDop_INPLACE_SUBTRACTop_INPLACE_MULTIPLYop_INPLACE_DIVIDEop_INPLACE_TRUE_DIVIDEop_INPLACE_FLOOR_DIVIDEop_INPLACE_MODULOop_INPLACE_POWERop_INPLACE_MATRIX_MULTIPLYop_INPLACE_LSHIFTop_INPLACE_RSHIFTop_INPLACE_ANDop_INPLACE_ORop_INPLACE_XORop_BINARY_ADDop_BINARY_SUBTRACTop_BINARY_MULTIPLYop_BINARY_DIVIDEop_BINARY_TRUE_DIVIDEop_BINARY_FLOOR_DIVIDEop_BINARY_MODULOop_BINARY_POWERop_BINARY_MATRIX_MULTIPLYop_BINARY_LSHIFTop_BINARY_RSHIFTop_BINARY_ANDop_BINARY_ORop_BINARY_XORr  r  r  r  r  r  r  r  r   r   r   r    rV   	  s   		

					
.
	rV   c                   @   sF  e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	e
dd Ze
dd Ze
dd Ze
dd Ze
dd Ze
dd Zdd Zdd Zdd Zd d! ZdLd#d$Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 ZdMd5d6Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z#dNdDdEZ$dFdG Z%dHdI Z&dJdK Z'd4S )OrU   zState of the trace
    c                 C   s   || _ || _|| _|| _g | _t|| _t|| _g | _	g | _
g | _d| _i | _t | _t | _t|D ]}| d}|| j|< | | q4dS )aG  
        Parameters
        ----------
        bytecode : numba.bytecode.ByteCode
            function bytecode
        pc : int
            program counter
        nstack : int
            stackdepth at entry
        blockstack : Sequence[Dict]
            A sequence of dictionary denoting entries on the blockstack.
        Fr   N)r@   _pc_initialr   _nstack_initialr]   r  _blockstack_initialr   _blockstack_temp_registers_insts	_outedges_terminatedr   r   r   r   r   r   r   r   )r   rB   rD   rE   rF   r7  r   r   r   r    r!     s&   



zState.__init__c                 C   s   d | j| jS )Nz&State(pc_initial={} nstack_initial={}))r+   r  r  r$   r   r   r    r1     s   zState.__repr__c                 C   s   | j | jfS r   )r  r  r$   r   r   r    get_identity  r2   zState.get_identityc                 C   s   t |  S r   )r"   r   r$   r   r   r    r%     r2   zState.__hash__c                 C   s   |   |  k S r   r   r,   r   r   r    r.     r  zState.__lt__c                 C   s   |   |  kS r   r  r,   r   r   r    r0     r  zState.__eq__c                 C   rP   )z]The starting bytecode offset of this State.
        The PC given to the constructor.
        )r  r$   r   r   r    rQ        zState.pc_initialc                 C   rP   )ziThe list of instructions information as a 2-tuple of
        ``(pc : int, register_map : Dict)``
        )r  r$   r   r   r    instructions  r  zState.instructionsc                 C   rP   )zaThe list of outgoing edges.

        Returns
        -------
        edges : List[State]
        r  r$   r   r   r    ro     s   zState.outgoing_edgesc                 C   rP   )zThe dictionary of outgoing phi nodes.

        The keys are the name of the PHI nodes.
        The values are the outgoing states.
        )r   r$   r   r   r    outgoing_phis  s   zState.outgoing_phisc                 C   rP   )z6A copy of the initial state of the blockstack
        )r  r$   r   r   r    blockstack_initial  s   zState.blockstack_initialc                 C   s
   t | jS )zYThe current size of the stack

        Returns
        -------
        res : int
        )r  r]   r$   r   r   r    rh      s   
zState.stack_depthc                 C   s,   t | jD ]}|d tdkr|  S qdS )z&Find the initial *try* block.
        rL   r   N)r   r  r   )r   r<  r   r   r    find_initial_try_block
  s
   zState.find_initial_try_blockc                 C   rP   r   r  r$   r   r   r    r_     s   zState.has_terminatedc                 C   s   | j | j S r   )r@   r   r$   r   r   r    ra     r2   zState.get_instc                 C   s   |   }|j| _d S r   )ra   re   r   r   r   r   r   r    rk     s   zState.advance_pc c                 C   sR   |sdj || j|  j t| jd}ndj || jt| jd}| j| |S )Nz"${prefix}{offset}{opname}.{tempct})rH  r   rb   tempctz${prefix}{offset}.{tempct})rH  r   r  )r+   r   ra   rb   lowerr  r  rZ   )r   rH  r   r   r   r    r     s   zState.make_tempc                 K   s0   | j |j|f |  jtt| O  _dS )zAppend new instN)r  rZ   r   r   r   _flatten_inst_regsr  )r   r   r:   r   r   r    rZ   -  s   zState.appendc                 C   s
   |  dS )Nr   )r  r$   r   r   r    r  2     
zState.get_tosc                 C   s   | j |  S )z-Return the k'th element on the stack
        r]   )r   r  r   r   r    r  5  s   z
State.peekc                 C   s   | j | dS )zPush to stackN)r]   rZ   )r   r   r   r   r    r   :  r  z
State.pushc                 C   s
   | j  S )zPop the stack)r]   r   r$   r   r   r    r   >  s   
z	State.popc                 C   s   d|v sJ | j | dS )z#Push a block to blockstack
        rh   N)r  rZ   )r   synblkr   r   r    rD  B  s   zState.push_blockc                 C   s$   | j d| | j |d | _ }|S )zVReset the stack to the given stack depth.
        Returning the popped items.
        Nr  )r   depthpoppedr   r   r    r:  H  s    zState.reset_stackTNc                 C   s>   t ||t| jd}|rt| j|d< nd|d< ||d< |S )zMake a new block
        )rL   rO   rI   rh   NrK   )r   r  r]   )r   rL   rO   r:  rK   dr   r   r    rE  O  s   zState.make_blockc                 C   s   | j  }| |d  |S )z)Pop a block and unwind the stack
        rh   )r  r   r:  r   r   r   r   r    r&  ^  s   
zState.pop_blockc                 C   sB   | j |}d|  krt| j k sJ  J | j d| | _ dS )zcFind *blk* in the blockstack and remove it and all blocks above it
        from the stack.
        r   N)r  rZ  r  )r   r<  idxr   r   r    rg   e  s   "zState.pop_block_and_abovec                 C   s0   t |}t| jD ]}|d |kr|  S q	dS )z1Find the first block that matches *kind*
        rL   N)r   r   r  )r   rL   bsr   r   r    rf   m  s   zState.get_top_blockc                 C   s   |  dduS )zGReturns a boolean indicating if the top-block is a *try* block
        r   N)rf   r$   r   r   r    r`   u     zState.has_active_tryc                 C   s   | j j|j S )z4Get referenced variable name from the oparg
        )r@   co_varnamesr   r	  r   r   r    r   z  r  zState.get_varnamec                 C   s
   d| _ dS )z!Mark block as terminated
        TNr  r$   r   r   r    r*    s   
zState.terminater   c           	      C   s   t | j}|r%d|  krt| jksJ  J t| j| }|d| }|r;d|ks-J t|D ]	}||   q1t | j}|rG|| | jt|t	||t	|d | 
  dS )zFork the state
        r   N)rD   stackrM   rF   )r   r]   r  r   rZ   r   r  r  Edger  r*  )	r   rD   rJ   rM   rN   r  rE   r7  rF   r   r   r    rd     s"   
"


z
State.forkc                 C   s   | j | jd dS )zSplit the state
        rH   N)rd   r   r$   r   r   r    rn     s   zState.split_new_blockc                 C   sh   | j rJ g }| jD ]'}t| j|jt|j|jd}|| |j	
 D ]\}}|j| | j |< q$q
|S )z+Get states for each outgoing edges
        rC   )r   r  rU   r@   rD   r  r  rF   rZ   r   r   )r   retr   rz   r   r7  r   r   r    rq     s   



zState.get_outgoing_statesc                 C   s   dd | j D S )z
        Returns
        -------
        Dict[int, int]
            where keys are the PC
            values are the edge-pushed stack values
        c                 S   s&   i | ]}|j t|j|j d  qS r   )rD   r  r  rM   )r   r   r   r   r    
<dictcomp>  s    z1State.get_outgoing_edgepushed.<locals>.<dictcomp>r  r$   r   r   r    get_outgoing_edgepushed  s   	zState.get_outgoing_edgepushed)r
  )TN)r   r   N)(r3   r4   r5   r6   r!   r1   r   r%   r.   r0   propertyrQ   r  ro   r  r  rh   r  r_   ra   rk   r   rZ   r  r  r   r   rD  r:  rE  r&  rg   rf   r`   r   r*  rd   rn   rq   r  r   r   r   r    rU     sV     


	


	


rU   r  )rD   r  rF   rM   c                   @   s$   e Zd ZdZdd Zedd ZdS )AdaptDFAz<Adapt Flow to the old DFA class expected by Interpreter
    c                 C   s
   || _ d S r   )_flow)r   flowr   r   r    r!     r  zAdaptDFA.__init__c                 C      | j jS r   )r   rA   r$   r   r   r    infos     zAdaptDFA.infosN)r3   r4   r5   r6   r!   r  r#  r   r   r   r    r    s
    r  AdaptBlockInfoinstsr  rF   active_try_blockoutgoing_edgepushedc                 C   s$   t t| j| j| j|  |  dS )Nr&  )r%  r  r  r  r  r  r  r   r   r   r    rv     s   rv   c                 c   sD    | D ]}t |tr|V  qt |ttfrt|D ]}|V  qqdS )z<Flatten an iterable of registers used in an instruction
    N)r)   strr  r   r  )r}  r   rR   r   r   r    r    s   
r  c                   @   sL   e Zd ZdZdd Zedd Zedd Zedd	 Zd
d Z	dd Z
dS )AdaptCFAz<Adapt Flow to the old CFA class expected by Interpreter
    c                 C   s   || _ i | _|j D ]\}}t||| j|< q| j j }|j}| }t }| j	 D ]}|
|r9|| q-|| | _d S r   )r   _blocksrA   r   AdaptCFBlockr   backboner   blocksr  in_loopsrp   	_backbone)r   r!  r   	blockinfor.  r   inloopblocksr   r   r   r    r!     s   

zAdaptCFA.__init__c                 C   r"  r   )r   r   r$   r   r   r    r     r$  zAdaptCFA.graphc                 C   rP   r   )r1  r$   r   r   r    r.        zAdaptCFA.backbonec                 C   rP   r   )r,  r$   r   r   r    r/    r4  zAdaptCFA.blocksc                 c   s"    t | jD ]}| j| V  qd S r   )ru   r/  r  r   r   r    iterliveblocks  s   zAdaptCFA.iterliveblocksc                 C   s   | j j  d S r   )r   r   r?   r$   r   r   r    r?     r  zAdaptCFA.dumpN)r3   r4   r5   r6   r!   r  r   r.  r/  r5  r?   r   r   r   r    r+    s    


r+  c                   @   s   e Zd Zdd ZdS )r-  c                 C   s    || _ tdd |jD | _d S )Nc                 s   s    | ]\}}|V  qd S r   r   )r   r7  r   r   r   r    	<genexpr>  s    z(AdaptCFBlock.__init__.<locals>.<genexpr>)r   r  r'  body)r   r2  r   r   r   r    r!     s   zAdaptCFBlock.__init__N)r3   r4   r5   r!   r   r   r   r    r-    s    r-  )(r6   pprintr   loggingcollectionsr   r   r   	functoolsr   numba.core.utilsr   r   numba.core.controlflowr	   r
   numba.core.irr   numba.core.errorsr   	getLoggerr3   r=   ri   rj   r7   rc   objectr   r8   r<   rV   rU   r  r  r%  rv   r  r+  r-  r   r   r   r    <module>   sT    
 	 F       "  
*