B
     \$                 @   s<  d Z ddlmZmZmZ ddlmZmZ ddl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 eddg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 e
j!dd dkrdZ"dZ#dZ$ndZ"dZ#dZ$dd Z%G dd deZ&G dd deZ'G dd deZ(dS )z
From NumbaPro

    )print_functiondivisionabsolute_import)
namedtupleOrderedDictN)CodeType
ModuleType)errorsutilsopcode_infoZargsizec             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   -lib/python3.7/site-packages/numba/bytecode.pyget_function_object   s    
r   c             C   s   t | dt | ddS )z"Shamelessly borrowed from llpython__code__Z	func_codeN)r   )r   r   r   r   get_code_object    s    r   c             C   s4   g }x*| D ]"}t j|}|d k	r
|| q
W |S )N)disZopmapgetappend)seqZlstscr   r   r   _as_opcodes%   s    
r   ZRETURN_VALUEZ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__E   s    zByteCodeInst.__init__c             C   s
   | j tkS )N)r   JUMP_OPS)r#   r   r   r   is_jumpM   s    zByteCodeInst.is_jumpc             C   s
   | j tkS )N)r   TERM_OPS)r#   r   r   r   is_terminatorQ   s    zByteCodeInst.is_terminatorc             C   s8   | j s
t| jtkr | j| j S | jtks.t| jS d S )N)r'   AssertionErrorr   JREL_OPSr   r    JABS_OPS)r#   r   r   r   get_jump_targetU   s
    

zByteCodeInst.get_jump_targetc             C   s   d| j | j| jf S )Nz%s(arg=%s, lineno=%d))r   r    r!   )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 dS )zREffect of the block stack
        Returns +1 (push), 0 (none) or -1 (pop)
        ZSETUP_   Z	POP_BLOCKr"   r   N)r   
startswith)r#   r   r   r   block_effect`   s
    
zByteCodeInst.block_effectN)__name__
__module____qualname____doc__	__slots__r%   propertyr'   r)   r-   r.   r1   r   r   r   r   r   6   s   r      )      r/   c             c   s   t jd dk rttt| } d}t| }d }}x||k r| | }|t7 }|tkr| | |B }x(tt	D ]}|| ||  d| > O }qhW |t	7 }|t
kr|dt	 > }q2nd}|t7 }d}||||fV  |}q2W dS )zd
    Returns a 4-int-tuple of
    (bytecode offset, opcode, argument, offset of next bytecode).
    r   r9      N)sysversion_infolistmapordlenCODE_LENHAVE_ARGUMENTrangeARG_LENEXTENDED_ARG
NO_ARG_LEN)codeZextended_argnr   iopr    jr   r   r   _unpack_opargsx   s*    
rM   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| j j| _d S )N)rH   iterrM   co_code)r#   rH   r   r   r   r%      s    zByteCodeIter.__init__c             C   s   | S )Nr   )r#   r   r   r   __iter__   s    zByteCodeIter.__iter__c             C   s
   t | jS )N)r   rO   )r#   r   r   r   _fetch_opcode   s    zByteCodeIter._fetch_opcodec             C   s$   |   \}}}}|t||||dfS )N)r   r   r    r$   )rR   r   )r#   r   r   r    r$   r   r   r   r      s    
zByteCodeIter.nextc             C   s8   d}x.t |D ]"}t| j\}}||d| > O }qW |S )Nr   r;   )rD   r   rO   )r#   sizeZbufrJ   Z_offsetZbyter   r   r   read_arg   s
    zByteCodeIter.read_argN)	r2   r3   r4   r%   rQ   rR   r   __next__rT   r   r   r   r   rN      s   rN   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   sz   |j }tt|j}|d tt|}| || || _	|j
| _
|j| _|j| _|j| _|j| _|| _t|| _d S )Nr   )rH   setr   Z
findlabelsrP   addr   rN   _compute_linenorW   rX   rY   rZ   r[   r\   r]   sortedr^   )r#   rW   rH   r^   r]   r   r   r   r%      s    
zByteCode.__init__c             C   s\   x(t |D ]\}}||kr||| _qW d}x(| D ]}|jdkrN|j}q8||_q8W |S )zI
        Compute the line numbers for all bytecode instructions.
        r"   r   )r   Zfindlinestartsr!   values)clsr]   rH   r   r!   Zknowninstr   r   r   ra      s    

zByteCode._compute_linenoc             C   s   t | jS )N)r
   Z
itervaluesr]   )r#   r   r   r   rQ      s    zByteCode.__iter__c             C   s
   | j | S )N)r]   )r#   r   r   r   r   __getitem__   s    zByteCode.__getitem__c             C   s
   || j kS )N)r]   )r#   r   r   r   r   __contains__   s    zByteCode.__contains__c                s,   fdd d  fddtjD S )Nc                s   | d j  jkrdS dS d S )Nr/   > )r   r^   )rJ   )r#   r   r   label_marker   s    z#ByteCode.dump.<locals>.label_marker
c             3   s    | ]}d  |f|  V  qdS )z
%s %10s	%sNr   ).0rJ   )rj   r   r   	<genexpr>   s   z ByteCode.dump.<locals>.<genexpr>)joinr
   Z	iteritemsr]   )r#   r   )rj   r#   r   dump   s    zByteCode.dumpc          	   C   s   i }|j }|dtj}t|tr(|j}x^| D ]R}|jdkr2||j	 }	|	|kr2y||	 }
W n t
k
rz   ||	 }
Y nX |
||	< q2W x<|D ]4}t|trtt|}|| |||j|j qW |S )za
        Compute the globals used by the function with the given
        bytecode table.
        __builtins__ZLOAD_GLOBAL)__globals__r   r
   builtins
isinstancer   __dict__rc   r   r    KeyErrorr   r   rN   update_compute_used_globalsrZ   rX   )rd   funcr]   rZ   rX   dZglobsrr   re   namevaluecoZsubtabler   r   r   rw      s(    




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.
        )rw   rW   rx   r]   rZ   rX   )r#   r   r   r   get_used_globals  s    zByteCode.get_used_globalsN)r2   r3   r4   r5   r6   r%   classmethodra   rQ   rf   rg   ro   rw   r}   r   r   r   r   rV      s   
rV   c               @   s.   e Zd ZdZedZedd Z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| y
|j}W n tk
rP   |j}Y nX |  }||_	||_
|dd |_||_t||_|jdkrt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
   Zpysignaturer	   ZByteCodeSupportErrorr4   AttributeErrorr2   rx   func_qualnamesplitZ	func_namerH   inspectZ	getmodulemoduleZ_dynamic_modnamemodnameZisgeneratorfunctionZis_generatorpysigco_filenamefilenameco_firstlinenoZfirstlinenorA   Z
parametersZ	arg_countr>   Z	arg_namesr   _unique_idsformatZunique_name)rd   Zpyfuncrx   rH   r   r   r#   Zuidr   r   r   from_function  s6    




zFunctionIdentity.from_functionc             C   s   |  | jS )z:Copy the object and increment the unique counter.
        )r   rx   )r#   r   r   r   deriveG  s    zFunctionIdentity.deriveN)
r2   r3   r4   r5   	itertoolscountr   r~   r   r   r   r   r   r   r     s   
)r   ))r5   Z
__future__r   r   r   collectionsr   r   r   r   r<   r   typesr   r   Znumbar	   r
   r   r   r   r   	frozensetZhasjrelr+   Zhasjabsr,   r&   r(   rF   rC   objectr   r=   rB   rE   rG   rM   rN   rV   r   r   r   r   r   <module>   s<   	

7c