o
    ۾i`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	   I/home/ubuntu/.local/lib/python3.10/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).
        	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                   @   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   gendescget_data_packerr   
arg_packerresume_blocksr    r2   r	   r	   r!   __init__5   s   

zBaseGeneratorLower.__init__c                 C      | j jS r/   )r2   	call_convr%   r	   r	   r!   r=   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?   rA   r	   r	   r!   get_resume_index_ptrL      z'BaseGeneratorLower.get_resume_index_ptrc                 C   s   t j||ddddS )Nr      z	gen.staterE   r?   rA   r	   r	   r!   get_state_ptrP   rH   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>   rI   z# low_init_func increfNz# low_init_func before return)setup_functionr   rB   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_structr=   return_value
post_lower)r    r2   rB   rettyresume_indexargstystatestyargtyargvalargsval	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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)rK   r6   rS   formatr   r   r   rB   functionr=   get_argumentsr8   	load_intorD   rV   rG   resume_index_ptrrJ   gen_state_ptrappend_basic_blocklower_function_bodyposition_at_endreturn_stop_iterationblkmapfirstblkr9   switchloaditemsadd_casebranch)r    r2   rB   rl   rC   prologueentry_block_tail
stop_blockfirst_blockrw   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&   rq   r   bitcastr   lower_finalize_func_body)r    r2   fntyrl   entry_blockrB   genptrtyrC   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   ro   typepointeerB   storer=   rt   )r    r2   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)rl   rq   rB   rs   r9   )r    r2   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   rS   rk   )r    rB   msgr	   r	   r!   rS      s   zBaseGeneratorLower.debug_printN)r'   r(   r)   r*   r;   r-   r=   rD   rG   rJ   rh   r   r   r   r   rS   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   r<   r/   )r   r   r%   r	   r	   r!   r5      s   z!GeneratorLower.get_generator_typec                 C   s   |S r/   r	   )r    r2   rf   r	   r	   r!   r[      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)	rS   r0   rT   rD   r8   rx   rW   decrefret_void)r    rB   rC   args_ptrtyvalr	   r	   r!   r      s   z'GeneratorLower.lower_finalize_func_bodyN)r'   r(   r)   r*   r5   r[   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_valuerB   pyapifrom_native_generatorr   envarg)r    r2   rf   gen_ptrr	   r	   r!   r[     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)rB   r   r   rp   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_apirG   rx   icmp_signedr   r   r   if_unlikelyrJ   ranger   r   r   r@   unpack_valuer   r   )r    rB   rC   r   ro   r_   need_cleanuprp   state_index
state_slotr   r   r	   r	   r!   r     s$   

z)PyGeneratorLower.lower_finalize_func_bodyN)r'   r(   r)   r*   r5   r[   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r2   r	   r!   
<listcomp>>  s    z'LowerYield.__init__.<locals>.<listcomp>)r2   r0   rB   genlowerr   rp   ro   ypinst	live_varslive_var_indices)r    r2   yield_pointr   r	   r   r!   r;   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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)r2   rS   rU   r   r   r   r@   rB   rp   r   r   typeof_alloca_varloadvarr0   rT   rW   rX   
pack_valuer   ro   r   r   r   r   r   )r    r   rF   r   r   fetyper   r   r	   r	   r!   lower_yield_suspendA  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   r2   r   r   rS   rU   r   r   r   r@   rB   rp   r   r   r0   r   storevarrT   rW   r   )r    r   rF   r   r   r   r	   r	   r!   lower_yield_resumeZ  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    $ %=