o
    ia                     @   s  d dl Z 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v r=d dlmZ dZn	ed	v rBneeed
dgZedd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*edv rdd Z+nedv rdd Z+needd  Z,G d!d" d"e#Z-G d#d$ d$e#Z.d%d& Z/G d'd( d(e.Z0G d)d* d*e0Z1ed+kre0Z2nedv re1Z2ned+k re.Z2neeG d,d- d-ej3Z4dS ).    N)
namedtupleOrderedDict)CodeType
ModuleType)errorsutils	serialize)	PYVERSION)      r      r      )_inline_cache_entries   r   
   r      opcode_infoargsize_ExceptionTableEntryzstart end target depth lastic                 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    Q/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/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_opcodes2   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)r3   r4   r5   r'   r6   r7   r8   selfr3   r5   r7   
nextoffsetr    r    r!   __init__R   s   
zByteCodeInst.__init__c                 C   
   | j tv S r&   )r5   JUMP_OPSr;   r    r    r!   is_jumpZ      
zByteCodeInst.is_jumpc                 C   r>   r&   )r5   TERM_OPSr@   r    r    r!   is_terminator^   rB   zByteCodeInst.is_terminatorc                 C   s   | j sJ tdv r| jdd dD v r| j| jd  S n;tdv r5| jdd dD v r4| j| jd	 d  S n"td
v rN| jdd dD v rM| j| jd	 d  S n	tdv rSntttdv rv| jtv rh| j| jd  S | jtv soJ | jd d S tt)Nr   r   c                 s       | ]}t j| V  qd S r&   r'   r(   .0kr    r    r!   	<genexpr>m       z/ByteCodeInst.get_jump_target.<locals>.<genexpr>)JUMP_BACKWARDJUMP_BACKWARD_NO_INTERRUPTr   r
   c                 s   rF   r&   rG   rH   r    r    r!   rK   r   rL   )rM      )r   c                 s   rF   r&   rG   rH   r    r    r!   rK   v   rL   )rM   POP_JUMP_BACKWARD_IF_TRUEPOP_JUMP_BACKWARD_IF_FALSEPOP_JUMP_BACKWARD_IF_NONEPOP_JUMP_BACKWARD_IF_NOT_NONEr   )r   r   r
   r   r   )	rA   r	   r5   r4   r7   r3   NotImplementedErrorJREL_OPSJABS_OPSr@   r    r    r!   get_jump_targetb   s8   
	



zByteCodeInst.get_jump_targetc                 C   s   d| j | j| jf S )Nz%s(arg=%s, lineno=%d))r6   r7   r8   r@   r    r    r!   __repr__   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_rP   	POP_BLOCKr9   r   )r6   
startswithr@   r    r    r!   block_effect   s
   
zByteCodeInst.block_effectN)__name__
__module____qualname____doc__	__slots__r=   propertyrA   rD   rY   rZ   r^   r    r    r    r!   r2   C   s    

)r2   rP   NOPrE   c                 c   s    g }t | D ]\}}}}||||f qt|D ]#\}\}}}|d t|k r3||d  d }nt| }||||fV  qd S )NrP   r   )r'   _unpack_opargsr*   	enumeratelen)codebufistart_offsetopr7   next_offsetr    r    r!   rf      s   rf   r   r   r
   c                 c   s$   d}t | }d }}||k r| | }|t7 }|tkrc| | |B }ttD ]}|| ||  d| > O }q%|t7 }tdv rE|t| t 7 }n	tdv rJntt|t	krb|t
||fV  |dt > }|}qnd}|t7 }tdv rv|t| t 7 }n	tdv r{nttd}||||fV  |}||k sdS dS )zp
        Returns a 4-int-tuple of
        (bytecode offset, opcode, argument, offset of next bytecode).
        r      rO   r   N)rh   CODE_LENHAVE_ARGUMENTrangeARG_LENr	   r   	INSTR_LENrV   EXTENDED_ARG
OPCODE_NOP
NO_ARG_LEN)ri   extended_argnr3   rk   rm   r7   jr    r    r!   rf      sD   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)rw   _FIXED_OFFSETrX   )	bc_streamr3   r5   r7   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&   )ri   iterr~   rf   co_code)r;   ri   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&   )r4   r   r@   r    r    r!   _fetch_opcode     
zByteCodeIter._fetch_opcodec                 C   s$   |   \}}}}|t||||dfS )N)r3   r5   r7   r<   )r   r2   r:   r    r    r!   r4   	  s   
zByteCodeIter.nextc                 C   s4   d}t |D ]}t| j\}}||d| > O }q|S )Nr   rp   )rs   r4   r   )r;   sizerj   rk   _offsetbyter    r    r!   read_arg  s
   zByteCodeIter.read_argN)	r_   r`   ra   r=   r   r   r4   __next__r   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exception_entries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&   )r|   )rI   xr    r    r!   rK   #  s    z%_ByteCode.__init__.<locals>.<genexpr>r   )ri   setr'   
findlabelsr   addr   r   _compute_linenor   r   r   r   r   r   r   sortedr   )r;   r   ri   r   r   r    r    r!   r=      s   
z_ByteCode.__init__c                 C   sh   t |D ]\}}|t }||v r||| _q|j}| D ]}|jdur.|jdkr.|j}q||_q|S )zI
        Compute the line numbers for all bytecode instructions.
        Nr   )r'   findlinestartsr|   r8   co_firstlinenovalues)clsr   ri   r3   r8   
adj_offsetknowninstr    r    r!   r   4  s   
z_ByteCode._compute_linenoc                 C   s   t | j S r&   )r   r   r   r@   r    r    r!   r   G  s   z_ByteCode.__iter__c                 C   s
   | j | S r&   r   r;   r3   r    r    r!   __getitem__J  r   z_ByteCode.__getitem__c                 C   s
   || j v S r&   r   r   r    r    r!   __contains__M  r   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 )NrP   > )r3   r   )rk   r@   r    r!   label_markerQ  s   z$_ByteCode.dump.<locals>.label_marker
c                 3   s0    | ]}|d  j dkrd |f|  V  qdS )rP   CACHEz
%s %10s	%sN)r6   )rI   rk   )r   r    r!   rK   W  s    z!_ByteCode.dump.<locals>.<genexpr>)joinr   itemsr@   r    )r   r;   r!   dumpP  s   z_ByteCode.dumpc              	   C   s   i }|j }|dtj}t|tr|j}| D ]*}|jdkrB|t	|j
 }	|	|vrBz||	 }
W n ty=   ||	 }
Y nw |
||	< q|D ]}t|tr_tt|}|| |||j|j qE|S )za
        Compute the globals used by the function with the given
        bytecode table.
        __builtins__LOAD_GLOBAL)__globals__r)   r   builtins
isinstancer   __dict__r   r6   _fix_LOAD_GLOBAL_argr7   KeyErrorr   r   r   update_compute_used_globalsr   r   )r   funcr   r   r   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   r   r   r   r   r   r@   r    r    r!   get_used_globalsx  s   z_ByteCode.get_used_globalsN)r_   r`   ra   rb   rc   r=   classmethodr   r   r   r   r   r   r   r    r    r    r!   r     s    

r   c                 C   s$   t dv r| d? S t dv r| S tt )N)r   r
   r   r   rP   rU   )r	   rV   )r7   r    r    r!   r     s
   r   c                       0   e Zd Z fddZedd Zdd Z  ZS )ByteCodePy311c                    s0   t  | t|jj}tt| j|| _d S r&   )	superr=   r'   Bytecoderi   r   tuplemapfixup_ehr;   r   entries	__class__r    r!   r=     s   zByteCodePy311.__init__c                 C   s.   t j| jt | jt | jt | j| jd}|S )N)startendtargetdepthlasti)r'   r   r   r|   r   r   r   r   )entoutr    r    r!   r     s   zByteCodePy311.fixup_ehc                 C   sT   g }| j D ]}|j|  kr|jk rn q||j|f q|r(t|d }|S dS )zN
        Returns the exception entry for the given instruction offset
        rP   N)r   r   r   r*   r   max)r;   r3   
candidatesr   r    r    r!   find_exception_entry  s   
z"ByteCodePy311.find_exception_entry)r_   r`   ra   r=   staticmethodr   r   __classcell__r    r    r   r!   r     s
    

r   c                       r   )ByteCodePy312c                    sp   t  | d _fddt|jjD }|}|jr1t	dd |D   fdd|D }t
|_d S )Nc                    s   g | ]}  |qS r    )r   rI   er@   r    r!   
<listcomp>  s    z*ByteCodePy312.__init__.<locals>.<listcomp>c                 S   s   g | ]}|j qS r    r   r   r    r    r!   r     s    c                    s   g | ]	}|j  kr|qS r    r   r   )max_exception_targetr    r!   r     s    )r   r=   _ordered_offsetsr'   r   ri   r   remove_build_list_swap_patternis_generatorr   r   r   r   )r   r;   r!   r=     s   

zByteCodePy312.__init__c                 C   s   | j sdd | jD | _ | j S )Nc                 S   s   g | ]}|qS r    r    )rI   or    r    r!   r     s    z1ByteCodePy312.ordered_offsets.<locals>.<listcomp>)r   r   r@   r    r    r!   ordered_offsets  s   zByteCodePy312.ordered_offsetsc                 C   s>  dt dtfdd}t }d}|rd}t }| D ]}| j|j}| j| j|  }|jdvr1q| j| j|d   }	|	jd	ksF|	j	d
krFq| j| j|d
   }	|	jdkrmt
jdd dkrc||	 | j| j|d   }	|	jdkssqtdv r| j|j}| j| j|d
   }|jdksq| j| j|d   }	tdv r|	jdksqntdv r|	jdksqntt| j| j|  }	|	jd	ks|	j	d
krqn3tdv r| j|j}| j| j|d   }|jdksq| j| j|  }	|	jd	ks|	j	d
krqntt|||}d}||O }q|s|D ]}
t|
jtjd d|
j| j|
j< q	|S )at   Find the following bytecode pattern:

            BUILD_{LIST, MAP, SET}
            SWAP(2)
            FOR_ITER
            ...
            END_FOR
            SWAP(2)

            This pattern indicates that a list/dict/set comprehension has
            been inlined. In this case we can skip the exception blocks
            entirely along with the dead exceptions that it points to.
            A pair of exception that sandwiches these exception will
            also be merged into a single exception.

            Update for Python 3.13, the ending of the pattern has a extra
            POP_TOP:

            ...
            END_FOR
            POP_TOP
            SWAP(2)

            Update for Python 3.13.1, there's now a GET_ITER before FOR_ITER.
            This patch the GET_ITER to NOP to minimize changes downstream
            (e.g. array-comprehension).
        r   entry_to_removec                    s   |   d }|   d }|dkr:|t| k r:| | }| | }|j|jkr:t|j|j|j|j|j| |< | | |    fdd| D } | S )NrP   r   c                    s   g | ]
}|j  jks|qS r    )r   r   r   r   r    r!   r     s    zbByteCodePy312.remove_build_list_swap_pattern.<locals>.pop_and_merge_exceptions.<locals>.<listcomp>)	indexrh   r   r   r   r   r   r   remove)r   r   lower_entry_idxupper_entry_idxlower_entryupper_entryr    r   r!   pop_and_merge_exceptions  s"   

zNByteCodePy312.remove_build_list_swap_pattern.<locals>.pop_and_merge_exceptionsTF)
BUILD_LIST	BUILD_MAP	BUILD_SETrP   SWAPr   GET_ITERNr   )r   r      FOR_ITERrE   END_FOR)r   POP_TOP)r   POP_ITERro   re   )listr   r   copyr   r   r   r   r6   r7   sysversion_infor   r	   r   rV   r2   r3   r'   r(   r4   )r;   r   r   change_to_nopwork_remainingcurrent_nop_fixesentryr   	curr_inst	next_instr   r    r    r!   r     s~   










Wz,ByteCodePy312.remove_build_list_swap_pattern)r_   r`   ra   r=   rd   r   r   r   r    r    r   r!   r     s
    
r   r   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).
    rP   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.r9   Nz{}${})$r"   r%   r   pysignaturer   ByteCodeSupportErrorra   AttributeErrorr_   r   func_qualnamesplit	func_nameri   inspect	getmodulemodule_dynamic_modnamemodnameisgeneratorfunctionr   pysigco_filenamefilenamer   firstlinenorh   
parameters	arg_countr   	arg_namesr4   _unique_idsformatunique_name	unique_id)r   pyfuncr   ri   r  r  r;   uidr    r    r!   from_functionv  s@   




zFunctionIdentity.from_functionc                 C   s   |  | jS )z:Copy the object and increment the unique counter.
        )r  r   r@   r    r    r!   derive  s   zFunctionIdentity.derivec                 C   s   t | jdS )4
        NOTE: part of ReduceMixin protocol
        )r  )dictr   r@   r    r    r!   _reduce_states  s   zFunctionIdentity._reduce_statesc                 C   s
   |  |S )r  )r  )r   r  r    r    r!   _rebuild  s   
zFunctionIdentity._rebuildN)r_   r`   ra   rb   	itertoolscountr  r   r  r  r  r  r    r    r    r!   r   l  s    

)r   )5r   collectionsr   r   r'   r  r   typesr   r   
numba.corer   r   r   numba.core.utilsr	   r5   r   ru   rV   r   r   r|   r"   r%   r/   	frozensethasjrelrW   hasjabsrX   r?   rC   rv   rr   objectr2   rq   rt   rx   r6   r   rw   rf   r~   r   r   r   r   r   ByteCodeReduceMixinr   r    r    r    r!   <module>   sj    
	
X

:i	 :