o
    8ήc"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J |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
yield_typequalnameunique_namenativemodnamedoctypemap	calltypeskwsr   )clsfunc_irfndescgentyper   restypeargsr   r   r   selfr	   r	   </tmp/pip-target-vg8gfxp4/lib/python/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).
        	finalize_)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                   @   s`   e Zd Z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d ZdS )BaseGeneratorLowerz5
    Base support class for lowering generators.
    c                 C   sr   |j | _ |j| _|j| _|j| _|j| _|j| _|  | _t	
|j| j| j| j j| _| j | jj| _i | _d S N)contextr   library	call_convr   generator_infogeninfoget_generator_typer   r   r"   r   gendescget_data_packerr   
arg_packerresume_blocksr    lowerr	   r	   r!   __init__5   s   

zBaseGeneratorLower.__init__c                 C   s   t ||ddS )Nr      r   gep_inboundsr    buildergenptrr	   r	   r!   get_args_ptrE   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_ptrH      z'BaseGeneratorLower.get_resume_index_ptrc                 C   s   t j||ddddS )Nr      z	gen.staterD   r>   r@   r	   r	   r!   get_state_ptrL   rG   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rUt| jj|jD ]\}}| jj||| qG| 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=   rH   z# low_init_func increfNz# low_init_func before return)setup_functionr   rA   r0   insert_generatorr   r6   r1   extract_function_arguments	pre_lowerget_return_typeget_constantr   int32elementsdebug_print
enable_nrtzipr   fnargsnrtincrefr8   as_datar   r   make_anonymous_structbox_generator_structr2   return_value
post_lower)r    r;   rA   rettyresume_indexargstystatestyargtyargvalargsval	statesval
gen_structretvalr	   r	   r!   lower_init_funcP   s6   




z"BaseGeneratorLower.lower_init_funcc                 C   s$  | | j |d| jj | jjd | jksJ |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   generator_prologuestop_iterationN)rJ   r6   rR   formatr   r   r   rA   functionr2   get_argumentsr8   	load_intorC   rU   rF   resume_index_ptrrI   gen_state_ptrappend_basic_blocklower_function_bodyposition_at_endreturn_stop_iterationblkmapfirstblkr9   switchloaditemsadd_casebranch)r    r;   rA   rk   rB   prologueentry_block_tail
stop_blockfirst_blockrv   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)llvmliteirFunctionTypeVoidTyper0   get_value_typer   r   get_or_insert_functionmoduler6   r&   rp   r   bitcastr   lower_finalize_func_body)r    r;   fntyrk   entry_blockrA   genptrtyrB   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   rn   typepointeerA   storer2   rs   )r    r;   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)rk   rp   rA   rr   r9   )r    r;   r   
block_namer   r	   r	   r!   create_resumption_block   s   
z*BaseGeneratorLower.create_resumption_blockc                 C   s"   t jr| j|d| d S d S )NzDEBUGJIT: {0})r   	DEBUG_JITr0   rR   rj   )r    rA   msgr	   r	   r!   rR      s   zBaseGeneratorLower.debug_printN)r'   r(   r)   r*   r<   rC   rF   rI   rg   r   r   r   r   rR   r	   r	   r	   r!   r.   0   s    1.r.   c                   @   (   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!   r5      s   z!GeneratorLower.get_generator_typec                 C   s   |S r/   r	   )r    r;   re   r	   r	   r!   rZ      s   z#GeneratorLower.box_generator_structc                 C   sb   |  |d | jjr%| ||}| 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)	rR   r0   rS   rC   r8   rw   rV   decrefret_void)r    rA   rB   args_ptrtyvalr	   r	   r!   r      s   z'GeneratorLower.lower_finalize_func_bodyN)r'   r(   r)   r*   r5   rZ   r   r	   r	   r	   r!   r      s
    r   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)gen_funcr   	arg_typesstate_typeshas_finalizer)
r   r   r   func_idfuncpyobject	arg_countlenr4   
state_varsr%   r	   r	   r!   r5      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   alloca_once_valuerA   pyapifrom_native_generatorr   envarg)r    r;   re   gen_ptrr	   r	   r!   rZ      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)rA   r   r   ro   r   r   r:   r	   r	   r!   init_generator_state  s   z%PyGeneratorLower.init_generator_statec                 C   s   | j |}| ||}||}|d|t|jd}t||4 | 	||}t
t| jjD ]}t||d|}	| jj| }
| j ||
|	}|| q1W d   n1 sYw   Y  |  dS )r   >r   N)r0   get_python_apirF   rw   icmp_signedr   r   r   if_unlikelyrI   ranger   r   r   r?   unpack_valuer   r   )r    rA   rB   r   rn   r^   need_cleanupro   state_index
state_slotr   r   r	   r	   r!   r     s$   

z)PyGeneratorLower.lower_finalize_func_bodyN)r'   r(   r)   r*   r5   rZ   r   r   r	   r	   r	   r!   r      s    r   c                   @   r   )	
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	   )r3   r   r   ).0vr;   r	   r!   
<listcomp>:  s    z'LowerYield.__init__.<locals>.<listcomp>)r;   r0   rA   genlowerr   ro   rn   ypinst	live_varslive_var_indices)r    r;   yield_pointr   r	   r   r!   r<   .  s   




zLowerYield.__init__c                 C   s   | j d t| j| jD ]?\}}t| j| jd|}| j	j
| }| j |}| j || | j |}| jjrB| 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)r;   rR   rT   r   r   r   r?   rA   ro   r   r   typeof_alloca_varloadvarr0   rS   rV   rW   
pack_valuer   rn   r   r   r   r   r   )r    r   rE   r   r   fetyper   r   r	   r	   r!   lower_yield_suspend=  s"   
zLowerYield.lower_yield_suspendc                 C   s   | j | j| jj | jd t| j| jD ]2\}}t	
| j| jd|}| jj| }| j| j||}| j|| | jjrI| jj| j|| q| jd d S )Nz# generator resumer   z# generator resume end)r   r   r;   r   r   rR   rT   r   r   r   r?   rA   ro   r   r   r0   r   storevarrS   rV   r   )r    r   rE   r   r   r   r	   r	   r!   lower_yield_resumeV  s   zLowerYield.lower_yield_resumeN)r'   r(   r)   r*   r<   r   r   r	   r	   r	   r!   r   )  s
    r   )r*   llvmlite.irr   r   r   
numba.corer   r   r   numba.core.funcdescr   r   objectr.   r   r   r   r	   r	   r	   r!   <module>   s    $ !=