o
    1&ic                     @   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      )_inline_cache_entries   r   
   r      opcode_infoZ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.
    Z	__numba__Ngetattr)objattr r   >C:\wamp64\www\opt\env\Lib\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)r/   r0   r1   r#   r2   r3   r4   selfr/   r1   r3   
nextoffsetr   r   r   __init__R   s   
zByteCodeInst.__init__c                 C   
   | j tv S r"   )r1   JUMP_OPSr7   r   r   r   is_jumpZ      
zByteCodeInst.is_jumpc                 C   r:   r"   )r1   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>m       z/ByteCodeInst.get_jump_target.<locals>.<genexpr>)JUMP_BACKWARDZJUMP_BACKWARD_NO_INTERRUPTr   r
   c                 s   rB   r"   rC   rD   r   r   r   rG   r   rH   )rI      )r   c                 s   rB   r"   rC   rD   r   r   r   rG   v   rH   )rI   ZPOP_JUMP_BACKWARD_IF_TRUEZPOP_JUMP_BACKWARD_IF_FALSEZPOP_JUMP_BACKWARD_IF_NONEZPOP_JUMP_BACKWARD_IF_NOT_NONEr   )r   r   r
   r   )	r=   r	   r1   r0   r3   r/   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))r2   r3   r4   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)
        ZSETUP_rK   	POP_BLOCKr5   r   )r2   
startswithr<   r   r   r   block_effect   s
   
zByteCodeInst.block_effectN)__name__
__module____qualname____doc__	__slots__r9   propertyr=   r@   rP   rQ   rT   r   r   r   r   r.   C   s    

)r.   rK   NOPrA   c                 c   s    g }t | D ]\}}}}||||f qt|D ]#\}\}}}|d t|k r3||d  d }nt| }||||fV  qd S )NrK   r   )r#   _unpack_opargsr&   	enumeratelen)codebufiZstart_offsetopr3   next_offsetr   r   r   r\      s   r\   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      rJ   r   N)r^   CODE_LENHAVE_ARGUMENTrangeARG_LENr	   r   	INSTR_LENrM   EXTENDED_ARG
OPCODE_NOP
NO_ARG_LEN)r_   extended_argnr/   ra   rb   r3   jr   r   r   r\      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)rl   _FIXED_OFFSETrO   )Z	bc_streamr/   r1   r3   r8   r   r   r   _patched_opargs   s   rr   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"   )r_   iterrr   r\   co_code)r7   r_   r   r   r   r9      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"   )r0   rt   r<   r   r   r   _fetch_opcode     
zByteCodeIter._fetch_opcodec                 C   s$   |   \}}}}|t||||dfS )N)r/   r1   r3   r8   )rw   r.   r6   r   r   r   r0   	  s   
zByteCodeIter.nextc                 C   s4   d}t |D ]}t| j\}}||d| > O }q|S )Nr   re   )rh   r0   rt   )r7   sizer`   ra   _offsetbyter   r   r   read_arg  s
   zByteCodeIter.read_argN)	rU   rV   rW   r9   rv   rw   r0   __next__r|   r   r   r   r   rs      s    rs   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"   )rq   )rE   xr   r   r   rG   #  s    z%_ByteCode.__init__.<locals>.<genexpr>r   )r_   setr#   
findlabelsru   addr   rs   _compute_linenor   r   r   r   r   r   r   sortedr   )r7   r   r_   r   r   r   r   r   r9      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#   findlinestartsrq   r4   co_firstlinenovalues)clsr   r_   r/   r4   Z
adj_offsetZknowninstr   r   r   r   4  s   
z_ByteCode._compute_linenoc                 C   s   t | j S r"   )rt   r   r   r<   r   r   r   rv   G  s   z_ByteCode.__iter__c                 C   s
   | j | S r"   r   r7   r/   r   r   r   __getitem__J  rx   z_ByteCode.__getitem__c                 C   s
   || j v S r"   r   r   r   r   r   __contains__M  rx   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 )NrK   > )r/   r   )ra   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 )rK   ZCACHEz
%s %10s	%sN)r2   )rE   ra   )r   r   r   rG   W  s    z!_ByteCode.dump.<locals>.<genexpr>)joinr   itemsr<   r   )r   r7   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   r2   _fix_LOAD_GLOBAL_argr3   KeyErrorr   r   rs   update_compute_used_globalsr   r   )r   funcr   r   r   dZglobsr   r   namevaluecoZ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)rU   rV   rW   rX   rY   r9   classmethodr   rv   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   rK   rL   )r	   rM   )r3   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"   )	superr9   r#   Bytecoder_   r   tuplemapfixup_ehr7   r   entries	__class__r   r   r9     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   rq   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
        rK   N)r   r   r   r&   r   max)r7   r/   
candidatesr   r   r   r   find_exception_entry  s   
z"ByteCodePy311.find_exception_entry)rU   rV   rW   r9   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   rE   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   r9   _ordered_offsetsr#   r   r_   r   remove_build_list_swap_patternis_generatorr   r   r   r   )r   r7   r   r9     s   

zByteCodePy312.__init__c                 C   s   | j sdd | jD | _ | j S )Nc                 S   s   g | ]}|qS r   r   )rE   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rlt
jdd dkrb||	 | j| j|d   }	|	jdksrq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 )NrK   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>)	indexr^   r   r   r   r   r   r   remove)r   r   Zlower_entry_idxZupper_entry_idxZlower_entryZ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_SETrK   ZSWAPr   GET_ITERNr   )r   r      FOR_ITERrA   ZEND_FORPOP_TOPrd   r[   )listr   r   copyr   r   r   r   r2   r3   sysversion_infor   r	   r   rM   r.   r/   r#   r$   r0   )r7   r   r   Zchange_to_nopZwork_remainingZcurrent_nop_fixesentryr   Z	curr_instZ	next_instr   r   r   r   r     sp   









Qz,ByteCodePy312.remove_build_list_swap_pattern)rU   rV   rW   r9   rZ   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).
    rK   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.r5   Nz{}${})$r   r!   r   Zpysignaturer   ZByteCodeSupportErrorrW   AttributeErrorrU   r   func_qualnamesplit	func_namer_   inspect	getmodulemoduleZ_dynamic_modnamemodnameisgeneratorfunctionr   pysigco_filenamefilenamer   Zfirstlinenor^   
parametersZ	arg_countr   	arg_namesr0   _unique_idsformatZunique_name	unique_id)r   pyfuncr   r_   r   r   r7   uidr   r   r   from_functionp  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)rU   rV   rW   rX   	itertoolscountr   r   r   r   r   r   r   r   r   r   r   f  s    

)r   )5r   collectionsr   r   r#   r   r   typesr   r   Z
numba.corer   r   r   Znumba.core.utilsr	   r1   r   rj   rM   r   r   rq   r   r!   r+   	frozensethasjrelrN   hasjabsrO   r;   r?   rk   rg   objectr.   rf   ri   rm   r2   r   rl   r\   rr   rs   r~   r   r   r   ZByteCodeZReduceMixinr   r   r   r   r   <module>   sj    
	
X

:i	 4