o
    ۾il_                     @   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v r9d dlmZ dZn	ed	v r>n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-Z/G d)d* d*e/Z0ed+kre/Z1nedv re0Z1ned+k re-Z1neeG d,d- d-ej2Z3dS ).    )
namedtupleOrderedDictN)CodeType
ModuleType)errorsutils	serialize)	PYVERSION)      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   G/home/ubuntu/.local/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_opcodes1   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)r1   r2   r3   r%   r4   r5   r6   selfr1   r3   r5   
nextoffsetr   r   r   __init__Q   s   
zByteCodeInst.__init__c                 C   
   | j tv S r$   )r3   JUMP_OPSr9   r   r   r   is_jumpY      
zByteCodeInst.is_jumpc                 C   r<   r$   )r3   TERM_OPSr>   r   r   r   is_terminator]   r@   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   c                 s       | ]}t j| V  qd S r$   r%   r&   .0kr   r   r   	<genexpr>l       z/ByteCodeInst.get_jump_target.<locals>.<genexpr>)JUMP_BACKWARDJUMP_BACKWARD_NO_INTERRUPTr   r
   c                 s   rD   r$   rE   rF   r   r   r   rI   q   rJ   )rK      )r   c                 s   rD   r$   rE   rF   r   r   r   rI   u   rJ   )rK   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?   r	   r3   r2   r5   r1   NotImplementedErrorJREL_OPSJABS_OPSr>   r   r   r   get_jump_targeta   s8   
	



zByteCodeInst.get_jump_targetc                 C   s   d| j | j| jf S )Nz%s(arg=%s, lineno=%d))r4   r5   r6   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_rN   	POP_BLOCKr7   r   )r4   
startswithr>   r   r   r   block_effect   s
   
zByteCodeInst.block_effectN)__name__
__module____qualname____doc__	__slots__r;   propertyr?   rB   rW   rX   r\   r   r   r   r   r0   B   s    

)r0   rN   NOPrC   c                 c   s    g }t | D ]\}}}}||||f qt|D ]#\}\}}}|d t|k r3||d  d }nt| }||||fV  qd S )NrN   r   )r%   _unpack_opargsr(   	enumeratelen)codebufistart_offsetopr5   next_offsetr   r   r   rd      s   rd   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      rM   r   N)rf   CODE_LENHAVE_ARGUMENTrangeARG_LENr	   r   	INSTR_LENrT   EXTENDED_ARG
OPCODE_NOP
NO_ARG_LEN)rg   extended_argnr1   ri   rk   r5   jr   r   r   rd      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)ru   _FIXED_OFFSETrV   )	bc_streamr1   r3   r5   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$   )rg   iterr|   rd   co_code)r9   rg   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$   )r2   r~   r>   r   r   r   _fetch_opcode     
zByteCodeIter._fetch_opcodec                 C   s$   |   \}}}}|t||||dfS )N)r1   r3   r5   r:   )r   r0   r8   r   r   r   r2     s   
zByteCodeIter.nextc                 C   s4   d}t |D ]}t| j\}}||d| > O }q|S )Nr   rn   )rq   r2   r~   )r9   sizerh   ri   _offsetbyter   r   r   read_arg  s
   zByteCodeIter.read_argN)	r]   r^   r_   r;   r   r   r2   __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$   )rz   )rG   xr   r   r   rI   "  s    z%_ByteCode.__init__.<locals>.<genexpr>r   )rg   setr%   
findlabelsr   addr   r}   _compute_linenor   r   r   r   r   r   r   sortedr   )r9   r   rg   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%   findlinestartsrz   r6   co_firstlinenovalues)clsr   rg   r1   r6   
adj_offsetknowninstr   r   r   r   3  s   
z_ByteCode._compute_linenoc                 C   s   t | j S r$   )r~   r   r   r>   r   r   r   r   F  s   z_ByteCode.__iter__c                 C   s
   | j | S r$   r   r9   r1   r   r   r   __getitem__I  r   z_ByteCode.__getitem__c                 C   s
   || j v S r$   r   r   r   r   r   __contains__L  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 )NrN   > )r1   r   )ri   r>   r   r   label_markerP  s   z$_ByteCode.dump.<locals>.label_marker
c                 3   s0    | ]}|d  j dkrd |f|  V  qdS )rN   CACHEz
%s %10s	%sN)r4   )rG   ri   )r   r   r   rI   V  s    z!_ByteCode.dump.<locals>.<genexpr>)joinr   itemsr>   r   )r   r9   r   dumpO  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   r4   _fix_LOAD_GLOBAL_argr5   KeyErrorr   r   r}   update_compute_used_globalsr   r   )r   funcr   r   r   dglobsr   r   namevaluecosubtabler   r   r   r   Z  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_globalsw  s   z_ByteCode.get_used_globalsN)r]   r^   r_   r`   ra   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   rN   rS   )r	   rT   )r5   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%   Bytecoderg   r   tuplemapfixup_ehr9   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   rz   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
        rN   N)r   r   r   r(   r   max)r9   r1   
candidatesr   r   r   r   find_exception_entry  s   
z"ByteCodePy311.find_exception_entry)r]   r^   r_   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   rG   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   rg   r   remove_build_list_swap_patternis_generatorr   r   r   r   )r   r9   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   )rG   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}|rd}t }| D ]}| j|j}| j| j|  }|jdvr0q| j| j|d   }	|	jd	ksE|	j	d
krEq| j| j|d
   }	|	jdkrc|
|	 | j| j|d   }	|	jdksiqtdv r| j|j}| j| j|d
   }|jdksq| j| j|d   }	|	jdksq| 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 )NrN   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>)	indexrf   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_SETrN   SWAPr   GET_ITERr   FOR_ITERrC   END_FORPOP_TOPrm   rc   N)listr   r   copyr   r   r   r   r4   r5   r   r	   r   rT   r0   r1   r%   r&   r2   )r9   r   r   change_to_nopwork_remainingcurrent_nop_fixesentryr   	curr_inst	next_instr   r   r   r   r     sn   









Mz,ByteCodePy312.remove_build_list_swap_pattern)r]   r^   r_   r;   rb   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).
    rN   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.r7   Nz{}${})$r    r#   r   pysignaturer   ByteCodeSupportErrorr_   AttributeErrorr]   r   func_qualnamesplit	func_namerg   inspect	getmodulemodule_dynamic_modnamemodnameisgeneratorfunctionr   pysigco_filenamefilenamer   firstlinenorf   
parameters	arg_countr   	arg_namesr2   _unique_idsformatunique_name	unique_id)r   pyfuncr   rg   r  r   r9   uidr   r   r   from_functionk  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^   r_   r`   	itertoolscountr  r   r  r  r  r  r   r   r   r   r   a  s    

)r   )4collectionsr   r   r%   r  r  typesr   r   
numba.corer   r   r   numba.core.utilsr	   r3   r   rs   rT   r   r   rz   r    r#   r-   	frozensethasjrelrU   hasjabsrV   r=   rA   rt   rp   objectr0   ro   rr   rv   r4   r   ru   rd   r|   r}   r   r   r   r   ByteCodeReduceMixinr   r   r   r   r   <module>   sh    
	
X

:i	 0