U
    ?h`7                     @   s   d 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
 G dd de
ZG dd	 d	eZG d
d deZG dd deZG dd deZdS )z"
Support for lowering generators.
    N)Constant	IRBuilder)typesconfigcgutils)FunctionDescriptorc                   @   s,   e Zd ZdZdZedd Zedd ZdS )GeneratorDescriptorz9
    The descriptor for a generator's next function.
     c                 C   sl   t |tjst|j}dg}|f}|jd }|jd }	| |j|j||	|j	|j
||j||j||d|jd}
|
S )a  
        Build a GeneratorDescriptor for the generator returned by the
        function described by *fndesc*, with type *gentype*.

        The generator inherits the env_name from the *fndesc*.
        All emitted functions for the generator shares the same Env.
        genz.nextF)argtypesmanglerinlineenv_name)
isinstancer   	GeneratorAssertionError
yield_typequalnameunique_namenativemodnamedoctypemapZ	calltypeskwsr   )clsfunc_irfndescgentyper   restypeargsr   r   r   selfr	   r	   G/var/www/html/venv/lib/python3.8/site-packages/numba/core/generators.pyfrom_generator_fndesc   s&    	

       z)GeneratorDescriptor.from_generator_fndescc                 C   s
   d| j  S )zz
        The LLVM name of the generator's finalizer function
        (if <generator type>.has_finalizer is true).
        Z	finalize_)Zmangled_namer    r	   r	   r!   llvm_finalizer_name'   s    z'GeneratorDescriptor.llvm_finalizer_nameN)	__name__
__module____qualname____doc__	__slots__classmethodr"   propertyr$   r	   r	   r	   r!   r      s   
r   c                   @   sl   e Zd ZdZdd Ze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S )BaseGeneratorLowerz5
    Base support class for lowering generators.
    c                 C   sp   |j | _ |j| _|j| _|j| _|| _|j| _|  | _t	
|j| j| j| j j| _| j | jj| _i | _d S N)contextr   libraryr   lowergenerator_infogeninfoget_generator_typer   r   r"   r   gendescZget_data_packerr   
arg_packerresume_blocksr    r0   r	   r	   r!   __init__5   s    
   zBaseGeneratorLower.__init__c                 C   s   | j jS r-   )r0   	call_convr#   r	   r	   r!   r9   E   s    zBaseGeneratorLower.call_convc                 C   s   t ||ddS )Nr      r   gep_inboundsr    buildergenptrr	   r	   r!   get_args_ptrI   s    zBaseGeneratorLower.get_args_ptrc                 C   s   t j||ddddS )Nr   zgen.resume_indexnamer;   r=   r	   r	   r!   get_resume_index_ptrL   s    z'BaseGeneratorLower.get_resume_index_ptrc                 C   s   t j||ddddS )Nr      z	gen.staterA   r;   r=   r	   r	   r!   get_state_ptrP   s    z BaseGeneratorLower.get_state_ptrc                 C   s  | | j |j}|j| j| j| jg |  |	  | j
| j}| jtjd}|jd }|jd }|d | jjrt| jj|jD ]\}}| jj||| q| j||j}	t|d}
t|||	|
g|}| ||}|d | j|| |  dS )z
        Lower the generator's initialization function (which will fill up
        the passed-by-reference generator structure).
        r   r:   rD   z# low_init_func increfNz# low_init_func before return)setup_functionr   r>   r.   Zinsert_generatorr   r4   r/   Zextract_function_argumentsZ	pre_lowerZget_return_typeZget_constantr   Zint32elementsdebug_print
enable_nrtzipr   fnargsnrtincrefr5   Zas_datar   r   Zmake_anonymous_structbox_generator_structr9   Zreturn_valueZ
post_lower)r    r0   r>   Zrettyresume_indexZargstyZstatestyZargtyargvalZargsvalZ	statesval
gen_structretvalr	   r	   r!   lower_init_funcT   s6    




z"BaseGeneratorLower.lower_init_funcc                 C   s$  | | j |d| jj | jjd | jks6t|j}|j	}| j
|\}| j|| |||j | ||| _| ||| _|d}| }|d}|| | j
| || |j|j  }| jd< ||| j|}	| j D ]\}
}|	|
| q|| || dS )z
        Lower the generator's next() function (which takes the
        passed-by-reference generator structure and returns the next
        yielded value).
        z# lower_next_func: {0}r   Zgenerator_prologueZstop_iterationN) rF   r4   rH   formatr   r   r   r   r>   functionr9   Zget_argumentsr5   Z	load_intor@   rK   rC   resume_index_ptrrE   gen_state_ptrappend_basic_blockZlower_function_bodyposition_at_endreturn_stop_iterationZblkmapZfirstblkr6   switchloaditemsZadd_casebranch)r    r0   r>   rU   r?   ZprologueZentry_block_tailZ
stop_blockZfirst_blockr[   indexblockr	   r	   r!   lower_next_func   s4    





z"BaseGeneratorLower.lower_next_funcc                 C   sv   t jt j | j| jg}t|j	|| j
j}|d}t|}| j| j}||jd |}| || dS )z2
        Lower the generator's finalizer.
        entryr   N)llvmliteZirFunctionTypeZVoidTyper.   Zget_value_typer   r   Zget_or_insert_functionmoduler4   r$   rX   r   Zbitcastr   lower_finalize_func_body)r    r0   ZfntyrU   Zentry_blockr>   Zgenptrtyr?   r	   r	   r!   lower_finalize_func   s      
z&BaseGeneratorLower.lower_finalize_funcc                 C   s2   t | jjjd}|j|| j | j|j dS )zY
        Emit a StopIteration at generator end and mark the generator exhausted.
        N)r   rV   typepointeer>   storer9   rZ   )r    r0   indexvalr	   r	   r!   return_from_generator   s    z(BaseGeneratorLower.return_from_generatorc                 C   s0   d|f }|j |}|j| || j|< d S )Nzgenerator_resume%d)rU   rX   r>   rY   r6   )r    r0   r_   Z
block_namer`   r	   r	   r!   create_resumption_block   s    
z*BaseGeneratorLower.create_resumption_blockc                 C   s   t jr| j|d| d S )NzDEBUGJIT: {0})r   Z	DEBUG_JITr.   rH   rT   )r    r>   msgr	   r	   r!   rH      s    zBaseGeneratorLower.debug_printN)r%   r&   r'   r(   r8   r+   r9   r@   rC   rE   rS   ra   rg   rm   rn   rH   r	   r	   r	   r!   r,   0   s   
1.r,   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	GeneratorLowerz9
    Support class for lowering nopython generators.
    c                 C   s   | j jS r-   )r   r   r#   r	   r	   r!   r3      s    z!GeneratorLower.get_generator_typec                 C   s   |S r-   r	   )r    r0   rQ   r	   r	   r!   rN      s    z#GeneratorLower.box_generator_structc                 C   sb   |  |d | jjrJ| ||}| j||D ]\}}| jj||| q.|  |d |  dS )g
        Lower the body of the generator's finalizer: decref all live
        state variables.
        z# generator: finalizez# generator: finalize endN)	rH   r.   rI   r@   r5   r\   rL   decrefret_void)r    r>   r?   Zargs_ptrtyvalr	   r	   r!   rf      s    z'GeneratorLower.lower_finalize_func_bodyN)r%   r&   r'   r(   r3   rN   rf   r	   r	   r	   r!   rp      s   rp   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )PyGeneratorLowerz<
    Support class for lowering object mode generators.
    c                 C   s8   t j| jjjt jt jf| jj t jft| jj	 ddS )zx
        Compute the actual generator type (the generator function's return
        type is simply "pyobject").
        T)Zgen_funcr   Z	arg_typesstate_typesZhas_finalizer)
r   r   r   Zfunc_idfuncZpyobject	arg_countlenr2   
state_varsr#   r	   r	   r!   r3      s    z#PyGeneratorLower.get_generator_typec                 C   s"   t |j|}|j|| j|jS )z>
        Box the raw *gen_struct* as a Python object.
        )r   Zalloca_once_valuer>   pyapiZfrom_native_generatorr   Zenvarg)r    r0   rQ   Zgen_ptrr	   r	   r!   rN     s    z%PyGeneratorLower.box_generator_structc                 C   s    |j t| jjjd| j dS )zo
        NULL-initialize all generator state variables, to avoid spurious
        decref's on cleanup.
        N)r>   rk   r   rW   ri   rj   r7   r	   r	   r!   init_generator_state	  s    z%PyGeneratorLower.init_generator_statec              	   C   s   | j |}| ||}||}|d|t|jd}t||^ | 	||}t
t| jjD ]:}t||d|}	| jj| }
| j ||
|	}|| qbW 5 Q R X |  dS )rq   >r   N)r.   Zget_python_apirC   r\   Zicmp_signedr   ri   r   Zif_unlikelyrE   rangerz   r   rw   r<   unpack_valuerr   rs   )r    r>   r?   r|   rV   rO   Zneed_cleanuprW   state_index
state_slotrt   ru   r	   r	   r!   rf     s&    
  
 z)PyGeneratorLower.lower_finalize_func_bodyN)r%   r&   r'   r(   r3   rN   r}   rf   r	   r	   r	   r!   rv      s
   rv   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	
LowerYieldz>
    Support class for lowering a particular yield point.
    c                    sj    | _  j| _ j| _ j| _| jj| _| jj| _| jj| _|| _| jj| _|| _	 fdd|D | _
d S )Nc                    s   g | ]} j j|qS r	   )r1   r{   r_   ).0vr0   r	   r!   
<listcomp>>  s   z'LowerYield.__init__.<locals>.<listcomp>)r0   r.   r>   genlowerr   rW   rV   Zypinst	live_varslive_var_indices)r    r0   Zyield_pointr   r	   r   r!   r8   2  s    




zLowerYield.__init__c                 C   s   | j d t| j| jD ]~\}}t| j| jd|}| j	j
| }| j |}| j || | j |}| jjr| jj| j|| | j| j||| qt| jjj| jj}| j|| j | j d d S )Nz# generator suspendr   z# generator suspend end)r0   rH   rJ   r   r   r   r<   r>   rW   r   rw   ZtypeofZ_alloca_varZloadvarr.   rI   rL   rM   Z
pack_valuer   rV   ri   rj   r   r_   rk   )r    r   rB   r   rt   Zfetyperu   rl   r	   r	   r!   lower_yield_suspendA  s$     
zLowerYield.lower_yield_suspendc                 C   s   | j | j| jj | jd t| j| jD ]d\}}t	
| j| jd|}| jj| }| j| j||}| j|| | jjr.| jj| j|| q.| jd d S )Nz# generator resumer   z# generator resume end)r   rn   r0   r   r_   rH   rJ   r   r   r   r<   r>   rW   r   rw   r.   r   ZstorevarrI   rL   rr   )r    r   rB   r   rt   ru   r	   r	   r!   lower_yield_resumeZ  s     zLowerYield.lower_yield_resumeN)r%   r&   r'   r(   r8   r   r   r	   r	   r	   r!   r   -  s   r   )r(   Zllvmlite.irrc   r   r   Z
numba.corer   r   r   Znumba.core.funcdescr   r   objectr,   rp   rv   r   r	   r	   r	   r!   <module>   s   $ %=