ó
\K]c           @` sÜ   d  Z  d d l m Z m Z m Z d d l m Z m Z m Z d d l	 m
 Z
 m Z m Z d d l m Z d e f d „  ƒ  YZ d	 e f d
 „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   s"   
Support for lowering generators.
i    (   t   print_functiont   divisiont   absolute_import(   t   Constantt   Typet   Builderi   (   t   cgutilst   typest   config(   t   FunctionDescriptort   GeneratorDescriptorc           B` s2   e  Z d  Z d Z e d „  ƒ Z e d „  ƒ Z RS(   s9   
    The descriptor for a generator's next function.
    c         C` s¥   t  | t j ƒ s t ‚ | j } d g } | f } | j d } | j d }	 |  | j | j | |	 | j	 | j
 | | j | | j d | d | d t d | j ƒ
}
 |
 S(   s  
        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.
        t   gens   .nextt   argtypest   manglert   inlinet   env_name(   t
   isinstanceR   t	   Generatort   AssertionErrort
   yield_typet   qualnamet   unique_namet   nativet   modnamet   doct   typemapt	   calltypest   kwst   FalseR   (   t   clst   func_irt   fndesct   gentypeR   t   restypet   argsR   R   R   t   self(    (    s/   lib/python2.7/site-packages/numba/generators.pyt   from_generator_fndesc   s    				c         C` s   d |  j  S(   sz   
        The LLVM name of the generator's finalizer function
        (if <generator type>.has_finalizer is true).
        t	   finalize_(   t   mangled_name(   R#   (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   llvm_finalizer_name'   s    (    (   t   __name__t
   __module__t   __doc__t	   __slots__t   classmethodR$   t   propertyR'   (    (    (    s/   lib/python2.7/site-packages/numba/generators.pyR
      s   t   BaseGeneratorLowerc           B` sh   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z RS(   s5   
    Base support class for lowering generators.
    c         C` s©   | j  |  _  | j |  _ | j |  _ | j |  _ | j |  _ | j |  _ |  j ƒ  |  _ t	 j
 | j |  j |  j |  j  j ƒ |  _ |  j  j |  j j ƒ |  _ i  |  _ d  S(   N(   t   contextR   t   libraryt	   call_convR   t   generator_infot   geninfot   get_generator_typeR    R
   R$   R   t   gendesct   get_data_packerR   t
   arg_packert   resume_blocks(   R#   t   lower(    (    s/   lib/python2.7/site-packages/numba/generators.pyt   __init__5   s    $c         C` s   t  j | | d d ƒ S(   Ni    i   (   R   t   gep_inbounds(   R#   t   buildert   genptr(    (    s/   lib/python2.7/site-packages/numba/generators.pyt   get_args_ptrE   s    c         C` s   t  j | | d d d d ƒS(   Ni    t   names   gen.resume_index(   R   R;   (   R#   R<   R=   (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   get_resume_index_ptrH   s    c         C` s   t  j | | d d d d ƒS(   Ni    i   R?   s	   gen.state(   R   R;   (   R#   R<   R=   (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   get_state_ptrL   s    c         C` sy  | j  |  j ƒ | j } | j j |  j |  j |  j g ƒ | j ƒ  | j	 ƒ  |  j j
 |  j ƒ } |  j j t j d ƒ } | j d } | j d } | j d ƒ |  j j rô xB t |  j j | j ƒ D]% \ } } |  j j j | | | ƒ qÈ Wn  |  j j | | j ƒ }	 t j | ƒ }
 t j | | |	 |
 g | ƒ } |  j | | ƒ } | j d ƒ |  j j | | ƒ | j ƒ  d S(   s‰   
        Lower the generator's initialization function (which will fill up
        the passed-by-reference generator structure).
        i    i   i   s   # low_init_func increfs   # low_init_func before returnN(    t   setup_functionR   R<   R/   t   insert_generatorR    R5   R0   t   extract_function_argumentst	   pre_lowert   get_return_typet   get_constantR   t   int32t   elementst   debug_printt
   enable_nrtt   zipR   t   fnargst   nrtt   increfR7   t   as_dataR   t   nullR   t   make_anonymous_structt   box_generator_structR1   t   return_valuet
   post_lower(   R#   R9   R<   t   rettyt   resume_indext   argstyt   statestyt   argtyt   argvalt   argsvalt	   statesvalt
   gen_structt   retval(    (    s/   lib/python2.7/site-packages/numba/generators.pyt   lower_init_funcP   s0    	

% 		c         C` sœ  | j  |  j ƒ | j d j |  j j ƒ ƒ |  j j d |  j k sK t ‚ | j } | j	 } |  j
 j | ƒ \ } |  j j | |  j | | ƒ | j ƒ |  j | | ƒ |  _ |  j | | ƒ |  _ | j d ƒ } | j ƒ  } | j d ƒ } | j | ƒ |  j
 j | ƒ | j | ƒ | j | j } |  j d <| j | j |  j ƒ | ƒ }	 x- |  j j ƒ  D] \ }
 } |	 j |
 | ƒ q^W| j | ƒ | j | ƒ d S(   s¥   
        Lower the generator's next() function (which takes the
        passed-by-reference generator structure and returns the next
        yielded value).
        s   # lower_next_func: {0}i    t   generator_prologuet   stop_iterationN(    RB   R5   RJ   t   formatR   R   R    R   R<   t   functionR1   t   get_argumentsR7   t	   load_intoR>   RM   R@   t   resume_index_ptrRA   t   gen_state_ptrt   append_basic_blockt   lower_function_bodyt   position_at_endt   return_stop_iterationt   blkmapt   firstblkR8   t   switcht   loadt   itemst   add_caset   branch(   R#   R9   R<   Rd   R=   t   prologuet   entry_block_tailt
   stop_blockt   first_blockRo   t   indext   block(    (    s/   lib/python2.7/site-packages/numba/generators.pyt   lower_next_func   s0    		
	c         C` s¥   t  j t  j ƒ  |  j j |  j ƒ g ƒ } | j j | d |  j j	 ƒ} | j
 d ƒ } t | ƒ } |  j j |  j ƒ } | j | j d | ƒ } |  j | | ƒ d S(   s2   
        Lower the generator's finalizer.
        R?   t   entryi    N(   R   Rd   t   voidR/   t   get_value_typeR    t   modulet   get_or_insert_functionR5   R'   Ri   R   t   bitcastR"   t   lower_finalize_func_body(   R#   R9   t   fntyRd   t   entry_blockR<   t   genptrtyR=   (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   lower_finalize_func¯   s    	c         C` sH   t  j |  j j j d ƒ } | j j | |  j ƒ |  j j | j ƒ d S(   sY   
        Emit a StopIteration at generator end and mark the generator exhausted.
        iÿÿÿÿN(	   R   t   intRg   t   typet   pointeeR<   t   storeR1   Rl   (   R#   R9   t   indexval(    (    s/   lib/python2.7/site-packages/numba/generators.pyt   return_from_generator¾   s    c         C` s@   d | f } | j  j | ƒ } | j j | ƒ | |  j | <d  S(   Ns   generator_resume%d(   Rd   Ri   R<   Rk   R8   (   R#   R9   Rx   t
   block_nameRy   (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   create_resumption_blockÆ   s    c         C` s,   t  j r( |  j j | d j | ƒ ƒ n  d  S(   Ns   DEBUGJIT: {0}(   R   t	   DEBUG_JITR/   RJ   Rc   (   R#   R<   t   msg(    (    s/   lib/python2.7/site-packages/numba/generators.pyRJ   Ì   s    	(   R(   R)   R*   R:   R>   R@   RA   R`   Rz   R…   R‹   R   RJ   (    (    (    s/   lib/python2.7/site-packages/numba/generators.pyR.   0   s   					1	.			t   GeneratorLowerc           B` s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   s9   
    Support class for lowering nopython generators.
    c         C` s
   |  j  j S(   N(   R   R!   (   R#   (    (    s/   lib/python2.7/site-packages/numba/generators.pyR4   Õ   s    c         C` s   | S(   N(    (   R#   R9   R^   (    (    s/   lib/python2.7/site-packages/numba/generators.pyRS   Ø   s    c         C` sŽ   |  j  | d ƒ |  j j rp |  j | | ƒ } x? |  j j | | ƒ D]% \ } } |  j j j | | | ƒ qD Wn  |  j  | d ƒ | j ƒ  d S(   sg   
        Lower the body of the generator's finalizer: decref all live
        state variables.
        s   # generator: finalizes   # generator: finalize endN(	   RJ   R/   RK   R>   R7   Rp   RN   t   decreft   ret_void(   R#   R<   R=   t   args_ptrt   tyt   val(    (    s/   lib/python2.7/site-packages/numba/generators.pyR   Û   s    " (   R(   R)   R*   R4   RS   R   (    (    (    s/   lib/python2.7/site-packages/numba/generators.pyR   Ð   s   		t   PyGeneratorLowerc           B` s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   s<   
    Support class for lowering object mode generators.
    c         C` sZ   t  j d |  j j j d t  j d t  j f |  j j d t  j f t |  j j	 ƒ d t
 ƒ S(   sx   
        Compute the actual generator type (the generator function's return
        type is simply "pyobject").
        t   gen_funcR   t	   arg_typest   state_typest   has_finalizer(   R   R   R   t   func_idt   funct   pyobjectt	   arg_countt   lenR3   t
   state_varst   True(   R#   (    (    s/   lib/python2.7/site-packages/numba/generators.pyR4   ñ   s    		c         C` s1   t  j | j | ƒ } | j j | |  j | j ƒ S(   s>   
        Box the raw *gen_struct* as a Python object.
        (   R   t   alloca_once_valueR<   t   pyapit   from_native_generatorR    t   envarg(   R#   R9   R^   t   gen_ptr(    (    s/   lib/python2.7/site-packages/numba/generators.pyRS   þ   s    c         C` s,   | j  j t j |  j j j ƒ |  j ƒ d S(   so   
        NULL-initialize all generator state variables, to avoid spurious
        decref's on cleanup.
        N(   R<   R‰   R   RQ   Rh   R‡   Rˆ   (   R#   R9   (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   init_generator_state  s    c      
   C` s   |  j  j | ƒ } |  j | | ƒ } | j | ƒ } | j d | t j | j d ƒ ƒ } t j	 | | ƒ ‡ |  j
 | | ƒ } xm t t |  j j ƒ ƒ D]S } t j | | d | ƒ }	 |  j j | }
 |  j  j | |
 |	 ƒ } | j | ƒ q• WWd QX| j ƒ  d S(   sg   
        Lower the body of the generator's finalizer: decref all live
        state variables.
        t   >i    N(   R/   t   get_python_apiR@   Rp   t   icmp_signedR   R†   R‡   R   t   if_unlikelyRA   t   rangeRŸ   R    R™   R;   t   unpack_valueR‘   R’   (   R#   R<   R=   R£   Rg   RW   t   need_cleanupRh   t   state_indext
   state_slotR”   R•   (    (    s/   lib/python2.7/site-packages/numba/generators.pyR     s    (   R(   R)   R*   R4   RS   R§   R   (    (    (    s/   lib/python2.7/site-packages/numba/generators.pyR–   ì   s
   			t
   LowerYieldc           B` s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   s>   
    Support class for lowering a particular yield point.
    c         C` sª   | |  _  | j |  _ | j |  _ | j |  _ |  j j |  _ |  j j |  _ |  j j |  _ | |  _ |  j j |  _ | |  _	 g  | D] } | j
 j j | ƒ ^ q‚ |  _ d  S(   N(   R9   R/   R<   t   genlowerR    Rh   Rg   t   ypt   instt	   live_varsR2   R    Rx   t   live_var_indices(   R#   R9   t   yield_pointRµ   t   v(    (    s/   lib/python2.7/site-packages/numba/generators.pyR:   .  s    			c         C` s  |  j  j d ƒ xª t |  j |  j ƒ D]“ \ } } t j |  j |  j d | ƒ } |  j	 j
 | } |  j  j | ƒ } |  j j r |  j j j |  j | | ƒ n  |  j j |  j | | | ƒ q& Wt j |  j j j |  j j ƒ } |  j j | |  j ƒ |  j  j d ƒ d  S(   Ns   # generator suspendi    s   # generator suspend end(   R9   RJ   RL   R¶   Rµ   R   R;   R<   Rh   R    R™   t   loadvarR/   RK   RN   RO   t
   pack_valueR   R†   Rg   R‡   Rˆ   R´   Rx   R‰   (   R#   R¯   R?   R°   R”   R•   RŠ   (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   lower_yield_suspend=  s    " c         C` sí   |  j  j |  j |  j j ƒ |  j j d ƒ xª t |  j |  j ƒ D]“ \ } } t	 j
 |  j |  j d | ƒ } |  j j | } |  j j |  j | | ƒ } |  j j | | ƒ |  j j rB |  j j j |  j | | ƒ qB qB W|  j j d ƒ d  S(   Ns   # generator resumei    s   # generator resume end(   R²   R   R9   R´   Rx   RJ   RL   R¶   Rµ   R   R;   R<   Rh   R    R™   R/   R­   t   storevarRK   RN   R‘   (   R#   R¯   R?   R°   R”   R•   (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   lower_yield_resumeP  s    "#(   R(   R)   R*   R:   R»   R½   (    (    (    s/   lib/python2.7/site-packages/numba/generators.pyR±   )  s   		N(   R*   t
   __future__R    R   R   t   llvmlite.llvmpy.coreR   R   R   t    R   R   R   t   funcdescR	   R
   t   objectR.   R   R–   R±   (    (    (    s/   lib/python2.7/site-packages/numba/generators.pyt   <module>   s   $ =