U
    ^#                     @   s  d dl Z d dlZd dlZddlmZmZ ddlmZ ddlT dZ	dZ
dZG d	d
 d
ZG dd dZG dd dZG dd dZG dd dZG dd dZejdkrejZnG dd dejZdd Zd.ddZd/ddZdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd0d,d-ZdS )1    N   )ffiplatformmodel)VerificationError)*i&  i'  i(  c                   @   s&   e Zd Zd	ddZdd Zdd ZdS )

GlobalExprr   c                 C   s"   || _ || _|| _|| _|| _d S N)nameaddresstype_opsizecheck_value)selfr	   r
   r   r   r    r   1/tmp/pip-install-v5gamh74/cffi/cffi/recompiler.py__init__   s
    zGlobalExpr.__init__c                 C   s   d| j | j| j | jf S )Nz'  { "%s", (void *)%s, %s, (void *)%s },)r	   r
   r   	as_c_exprr   r   r   r   r   r      s       zGlobalExpr.as_c_exprc                 C   s   d| j  | j| jf S )Nz
b'%s%s',%d)r   as_python_bytesr	   r   r   r   r   r   as_python_expr   s    zGlobalExpr.as_python_exprN)r   r   __name__
__module____qualname__r   r   r   r   r   r   r   r      s   
r   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
	FieldExprc                 C   s"   || _ || _|| _|| _|| _d S r   )r	   field_offset
field_sizefbitsizefield_type_op)r   r	   r   r   r   r   r   r   r   r      s
    zFieldExpr.__init__c                 C   s>   dt | j }d| j| jf d|| jf  d|| j f  S )N z  { "%s", %s,
z     %s   %s,
z     %s   %s },)lenr	   r   r   r   r   )r   spacesr   r   r   r   #   s    zFieldExpr.as_c_exprc                 C   s   t d S r   )NotImplementedErrorr   r   r   r   r   )   s    zFieldExpr.as_python_exprc                 C   sD   | j jtkrd}n| j jtkr*t| j}ntd| j  || jf S )N z	b'%s%s%s')	r   opOP_NOOPOP_BITFIELDformat_four_bytesr   r"   r   r	   )r   Z	size_exprr   r   r   as_field_python_expr,   s    
zFieldExpr.as_field_python_exprN)r   r   r   r   r   r   r(   r   r   r   r   r      s   r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )StructUnionExprc	           	      C   s4   || _ || _|| _|| _|| _|| _|| _|| _d S r   )r	   
type_indexflagsr   	alignmentcommentfirst_field_indexc_fields)	r   r	   r*   r+   r   r,   r-   r.   r/   r   r   r   r   8   s    zStructUnionExpr.__init__c                 C   sP   d| j | j| jf d| j| jf  d| jt| jf  | jrFd| j nd d S )Nz  { "%s", %d, %s,z
    %s, %s, z%d, %d z	/* %s */ r#   z},)	r	   r*   r+   r   r,   r.   r    r/   r-   r   r   r   r   r   C   s    zStructUnionExpr.as_c_exprc                 C   s>   t | jt}dd | jD }dt| jt|| jd|f S )Nc                 S   s   g | ]}|  qS r   )r(   ).0Zc_fieldr   r   r   
<listcomp>L   s   z2StructUnionExpr.as_python_expr.<locals>.<listcomp>z(b'%s%s%s',%s),)evalr+   ZG_FLAGSr/   r'   r*   r	   join)r   r+   Zfields_exprr   r   r   r   J   s    zStructUnionExpr.as_python_exprNr   r   r   r   r   r)   7   s   r)   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )EnumExprc                 C   s"   || _ || _|| _|| _|| _d S r   r	   r*   r   signedallenums)r   r	   r*   r   r7   r8   r   r   r   r   U   s
    zEnumExpr.__init__c                 C   s   d| j | j| j| j| jf S )Nz1  { "%s", %d, _cffi_prim_int(%s, %s),
    "%s" },r6   r   r   r   r   r   \   s      zEnumExpr.as_c_exprc              	   C   s@   t tttttttd| j| j	f }dt
| jt
|| j| jf S )N))r   r   )r   r   )   r   )r9   r   )   r   )r:   r   )   r   )r;   r   zb'%s%s%s\x00%s')Z
PRIM_UINT8Z	PRIM_INT8ZPRIM_UINT16Z
PRIM_INT16ZPRIM_UINT32Z
PRIM_INT32ZPRIM_UINT64Z
PRIM_INT64r   r7   r'   r*   r	   r8   )r   
prim_indexr   r   r   r   a   s         

 zEnumExpr.as_python_exprNr   r   r   r   r   r5   T   s   r5   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )TypenameExprc                 C   s   || _ || _d S r   r	   r*   )r   r	   r*   r   r   r   r   m   s    zTypenameExpr.__init__c                 C   s   d| j | jf S )Nz  { "%s", %d },r>   r   r   r   r   r   q   s    zTypenameExpr.as_c_exprc                 C   s   dt | j| jf S )Nzb'%s%s')r'   r*   r	   r   r   r   r   r   t   s    zTypenameExpr.as_python_exprNr   r   r   r   r   r=   l   s   r=   c                   @   s  e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdddddgZ	dd Z
dd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+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Zd=d> Zd?d@ Z ddBdCZ!dDdE Z"dFdG Z#dHdI Z$e$Z%dJdK Z&dLdM Z'e'Z(dNdO Z)e)Z*dPdQ Z+dRdS Z,dTdU Z-ddWdXZ.dYdZ Z/d[d\ Z0d]d^ Z1d_d` Z2ddadbZ3dcdd Z4dedf Z5dgdh Z6didj Z7dkdl Z8dmdn Z9dodp Z:dqdr Z;dsdt Z<dudv Z=e= Z>Z?dwdx Z@dydz ZAd{d| ZBd}d~ ZCdd ZDeD ZEZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMeMZNeMZOdd ZPdd ZQdd ZReRZSdd ZTdAS )
Recompilerr   Fc                 C   s   || _ || _|| _t| _d S r   )ffimodule_nametarget_is_pythonVERSION_BASE_version)r   r@   rA   rB   r   r   r   r   ~   s    zRecompiler.__init__c                 C   s   t | j|| _d S r   )maxrD   )r   verr   r   r   needs_version   s    zRecompiler.needs_versionc              	   C   s.  i | _ | d t| j td}g | _|D ]}|jr(| j | d ksDtt| j| j |< | j| |j	D ]P}t
|tjtjtjtjtjfst| j | d krt| j| j |< | j| qf| jd q(|D ]P}|js| j | d krt| j| j |< | j| |jr|jd k	r| jd qd | j  ks0ti | _i | _|D ]8}t
|tjr^d | j|< nt
|tjr@d | j|< q@tt| jdd dD ]\}}|| j|< qtt| jdd dD ]\}}|| j|< q|D ](}t| d|jj }||| j |  q| jD ]}t
|tstqt| j| _d S )	NZcollecttypekeyZENDLENc                 S   s   | j S r   r	   tpr   r   r   <lambda>       z/Recompiler.collect_type_table.<locals>.<lambda>c                 S   s   | j S r   rK   rL   r   r   r   rN      rO   Z_emit_bytecode_)
_typesdict	_generatesortedstr
cffi_typesZis_raw_functionAssertionErrorr    appendargs
isinstancer   VoidTypeBasePrimitiveTypePointerTypeStructOrUnionOrEnumFunctionPtrTypeZis_array_typelengthvalues_struct_unions_enumsStructOrUnionEnumType	enumerategetattr	__class__r   CffiOptuple)r   Z	all_declsrM   tp1imethodr$   r   r   r   collect_type_table   s`    



zRecompiler.collect_type_tablec                 C   s   t |tjs.t |tr*|D ]}| | qd S || jkrd | j|< t |tjr^| |  nlt |tjr|j	d k	r|| j
jjkr| D ] \}}}}| | ||| qn| D ]\}}| | qd S r   )rX   r   ZBaseTypeByIdentityrh   _do_collect_typerP   r]   as_raw_functionrb   fldtypesr@   _parser_included_declarations
enumfields_field_typeZ
_get_items)r   rM   xZname1ri   _r   r   r   rm      s"    



zRecompiler._do_collect_typec           
      C   s   | j jj }t|D ]\}\}}|dd\}}zt| d||f }W n  tk
rh   td| Y nX z|| _	||| W q t
k
r }	 zt|	|  W 5 d }	~	X Y qX qd S )Nr   r   z_generate_cpy_%s_%sz"not implemented in recompile(): %r)r@   rp   Z_declarationsitemsrR   splitre   AttributeErrorr   _current_quals	Exceptionr   Zattach_exception_info)
r   	step_namelstr	   rM   qualskindZrealnamerk   er   r   r   rQ      s"    
zRecompiler._generateglobalfieldstruct_unionenumtypenamec                 C   s(  i | _ | jD ]}g | j |< qt | _| d |   | jD ]4}| j | }|dkrb|jdd d t|| j |< q<| j d }| j	 D ],\}}|t
|k st|| j|jkstqt
|t
| jkst| j d }| j	 D ],\}}|t
|k st|| j|jkstqt
|t
| jks$td S )Nctxr   c                 S   s   | j S r   rK   )entryr   r   r   rN      rO   z0Recompiler.collect_step_tables.<locals>.<lambda>rH   r   r   )_lsts	ALL_STEPSset_seen_struct_unionsrQ   _add_missing_struct_unionssortrh   r`   rv   r    rU   r	   ra   )r   r{   r|   rM   rj   r   r   r   collect_step_tables   s*    





zRecompiler.collect_step_tablesr#   c                 C   s   | j |d  d S )N
)_fwrite)r   whatr   r   r   _prnt  s    zRecompiler._prntc                 C   s:   | j r|d kst| | n|d k	s*t| || d S r   )rB   rU   write_py_source_to_fwrite_c_source_to_f)r   fpreambler   r   r   write_source_to_f  s
    zRecompiler.write_source_to_fc                 C   s0   t tjtjt|d}| }|  |S )Nr)openospathr4   dirname__file__	readlinesclose)r   filenameglinesr   r   r   _rel_readlines  s    zRecompiler._rel_readlinesc              	   C   sb  || _ | j}| jjd k	r |d | d}|d}| d|||d < |d| | jdd }| jjd k	r0|d	| jf  |d
 | 	| jj |d |d |d|f  |d |d|f  |d |d|f  |d | d}|d}| d|||d < |d| | 
t |d |  || |  |d |  |d tdd | j D }t| jD ]>\}}d}	||krd||   }	|d|| |	f  q| js|d |d |  t | _| d i }
| jD ]`}| j| }t||
|< |
| dkr|d ||f  |D ]}||  q:|d |  q| jjr|d! | jjD ]f}z|jd d" \}}W n( tk
r   td#| j|f Y nX |d krtd$|d%|f  qz|d& |d |  |d' |d( | jD ].}|
| dkr.|d)|  n|d*|  q| jD ]$}|d+krD|d,|
| |f  qD| jjr~|d- n|d. |d/t| jf  d}| jr|dO }|d0|  |d |  |d1 |d2 |d |  |d |d3 |d4|f  |d5 | jr,|d6 |d7 |d8 |d9| j  |d: |d; |d< |d |d= |d> |d? |d@ |dA|f  |dB |dC|f  |dD |dD |d |d3 |dE|f  |d5 |dF| j| jf  |d= |d |d3 |dG|f  |d5 |dH| j| jf  |d= |d |  |d1 |dI |d d | _d S )JNz#define _CFFI_USE_EMBEDDINGz_cffi_include.hz#include "parse_c_type.h"
zparse_c_type.hr   r#   .z#define _CFFI_MODULE_NAME  "%s"z1static const char _CFFI_PYTHON_STARTUP_CODE[] = {z0 };z#ifdef PYPY_VERSIONz5# define _CFFI_PYTHON_STARTUP_FUNC  _cffi_pypyinit_%sz#elif PY_MAJOR_VERSION >= 3z-# define _CFFI_PYTHON_STARTUP_FUNC  PyInit_%s#elsez*# define _CFFI_PYTHON_STARTUP_FUNC  init%s#endifz_embedding.hz#include "_cffi_errors.h"
z_cffi_errors.hz>/************************************************************/zstatic void *_cffi_types[] = {c                 S   s   g | ]\}}||fqS r   r   r0   rM   rj   r   r   r   r1   G  s     z2Recompiler.write_c_source_to_f.<locals>.<listcomp>z // z/* %2d */ %s,%sz  0z};declr   z.static const struct _cffi_%s_s _cffi_%ss[] = {z.static const char * const _cffi_includes[] = {r9   Qffi object %r includes %r, but the latter has not been prepared with set_source()zMnot implemented yet: ffi.include() of a Python-based ffi inside a C-based ffiz  "%s",z  NULLz?static const struct _cffi_type_context_s _cffi_type_context = {z  _cffi_types,z  _cffi_%ss,z  NULL,  /* no %ss */r   z  %d,  /* num_%ss */z  _cffi_includes,z  NULL,  /* no includes */z  %d,  /* num_types */z  %d,  /* flags */z#ifdef __GNUC__z?#  pragma GCC visibility push(default)  /* for -fvisibility= */ZPyMODINIT_FUNCz"_cffi_pypyinit_%s(const void *p[]){z%    if (((intptr_t)p[0]) >= 0x0A03) {zQ        _cffi_call_python_org = (void(*)(struct _cffi_externpy_s *, char *))p[1];z    }z    p[0] = (const void *)0x%x;z    p[1] = &_cffi_type_context;z#if PY_MAJOR_VERSION >= 3    return NULL;}z#  ifdef _MSC_VERz     PyMODINIT_FUNCz#  if PY_MAJOR_VERSION >= 3z%     PyInit_%s(void) { return NULL; }z#  elsez     init%s(void) { }z#  endifzPyInit_%s(void)z5  return _cffi_init("%s", 0x%x, &_cffi_type_context);zinit%s(void)z.  _cffi_init("%s", 0x%x, &_cffi_type_context);z#  pragma GCC visibility pop)r   r   r@   
_embeddingr   indexr4   rA   rw   _print_string_literal_in_arrayrG   VERSION_EMBEDDEDdictrP   rv   rd   rT   _get_c_namer   r   _seen_constantsrQ   r   r   r    _included_ffis_assigned_sourcerx   r   _num_externpyrD   )r   r   r   prntr   rj   Zbase_module_nametypeindex2typer$   r-   numsr{   r|   r   ffi_to_includeincluded_module_nameincluded_sourcer+   r   r   r   r     s6   








 


 






  zRecompiler.write_c_source_to_fc                    sb   t |trd|f S t |ttfrZ fdd|D }t|dkrJ|d dd|f S | S )Nzb'%s'c                    s   g | ]}  |qS r   )_to_py)r0   itemr   r   r   r1     s     z%Recompiler._to_py.<locals>.<listcomp>r   r#   z(%s)r2   )rX   rS   listrh   r    rV   r4   r   )r   rt   repr   r   r   r     s    


zRecompiler._to_pyc              	   C   s  || _ | j}|d |d t| jjp(d}t|D ]n}| jj| }z|jd d \}}W n& tk
r   td| j|f Y nX |d k	rtd|d||f  q4|  |d| j	f  |d	| j
f  d | _
t| j| _d
d | jD }|d| d|f  tdd | j D }	| jD ]>}
| j|
 }t|dkr$|
dkr$|d|
| |f  q$|dkr|dddd t|D f  |d d S )Nz# auto-generated filezimport _cffi_backendr   r9   r   zMnot implemented yet: ffi.include() of a C-based ffi inside a Python-based ffizfrom %s import ffi as _ffi%dzffi = _cffi_backend.FFI('%s',z    _version = 0x%x,c                 S   s   g | ]}|  qS r   )r   )r0   r$   r   r   r   r1     s     z3Recompiler.write_py_source_to_f.<locals>.<listcomp>z    _types = %s,r#   c                 S   s   g | ]\}}||fqS r   r   r   r   r   r   r1     s     r   r   z    _%ss = %s,z    _includes = (%s,),, c                 S   s   g | ]}d | qS )z_ffi%dr   r0   rj   r   r   r   r1     s     ))r   r   r    r@   r   ranger   rx   r   rA   rD   rh   rT   r   r4   r   rP   rv   r   r   )r   r   r   Znum_includesrj   r   r   r   Z	types_lstr   r{   r|   r   r   r   r     sP    
 



zRecompiler.write_py_source_to_fc                 C   s
   | j | S r   )rP   )r   typer   r   r   _gettypenum  s    zRecompiler._gettypenumc           	      C   sn  d}t |tjr| s| r:|jdkr:d}d|j }nPt |tjrXd|df }n2|d}d||jddf }|d	kr| 	t
 d
}nt |tjr| |||| d S t |tjst |tjr| d|| ||f  | d|  d S t |tjr$d|d }d| | }d}nt|| d||||f  | d||d|f  | d|  d S )Nr#   _BoolZ_cffi_to_c_intz, %sz(%s)_cffi_to_c_doublez(%s)_cffi_to_c_%sr   ru   Zchar16_tZchar32_tz-1z6  if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)z    %s;z(%s)_cffi_to_c_pointerz, _cffi_type(%d)ZNULLz  %s = %s(%s%s);z'  if (%s == (%s)%s && PyErr_Occurred()))rX   r   rZ   is_complex_typeis_integer_typer	   UnknownFloatType
get_c_namereplacerG   VERSION_CHAR16CHAR32r[   "_convert_funcarg_to_c_ptr_or_arrayr\   r   r   r]   r"   )	r   rM   fromvartovarerrcodeZextraarg	convertercnameZerrvaluer   r   r   _convert_funcarg_to_c  sP    

 
  z Recompiler._convert_funcarg_to_cc                 C   s   t |tjr|d d S )NzPy_ssize_t datasize)rX   r   r[   add)r   rM   	localvarsr   r   r   _extra_local_variables3  s    z!Recompiler._extra_local_variablesc                 C   s   |  d |  d| |||f  |  d |  d |  d|  |  d||df  |  d|f  |  d	|| ||f  |  d|  |  d
 d S )Nz1  datasize = _cffi_prepare_pointer_call_argument(z(      _cffi_type(%d), %s, (char **)&%s);z  if (datasize != 0) {z    if (datasize < 0)z	      %s;z&    %s = (%s)alloca((size_t)datasize);r#   z,    memset((void *)%s, 0, (size_t)datasize);zL    if (_cffi_convert_array_from_object((char *)%s, _cffi_type(%d), %s) < 0)z  })r   r   r   )r   rM   r   r   r   r   r   r   r   7  s,    
  

   z-Recompiler._convert_funcarg_to_c_ptr_or_arrayc                 C   sJ  t |tjr| r,|jdkr,d||jf S t |tjrBd|f S |jdkr| s|jdd}|dkrt| t	 d||f S d	|| 
|f S nt |tjtjfrd
|| 
|f S t |tjrd
|| 
t|jf S t |tjr|jd krtd| |f d|| 
|f S t |tjr>d	|| 
|f S t|d S )Nr   z_cffi_from_c_int(%s, %s)z_cffi_from_c_double(%s)long doubler   ru   r   z_cffi_from_c_%s(%s)z/_cffi_from_c_deref((char *)&%s, _cffi_type(%d))z0_cffi_from_c_pointer((char *)%s, _cffi_type(%d))z!'%s' is used as %s, but is opaquez0_cffi_from_c_struct((char *)&%s, _cffi_type(%d)))rX   r   rZ   r   r	   r   r   r   rG   r   r   r[   r]   	ArrayTyper   rb   Zfldnames	TypeErrorr   rc   r"   )r   rM   varcontextr   r   r   r   _convert_expr_from_cG  sP    

      zRecompiler._convert_expr_from_cc                 C   s   |  |d|f S )Nz
(*(%s *)0))_global_typer   rM   r	   r   r   r   _typedef_typej  s    zRecompiler._typedef_typec                 C   s   |  | || d S r   )rm   r   r   r   r   r   !_generate_cpy_typedef_collecttypem  s    z,Recompiler._generate_cpy_typedef_collecttypec                 C   s   d S r   r   r   r   r   r   _generate_cpy_typedef_declp  s    z%Recompiler._generate_cpy_typedef_declc                 C   s$   | j | }| jd t|| d S )Nr   )rP   r   rV   r=   )r   rM   r	   r*   r   r   r   _typedef_ctxs  s    
zRecompiler._typedef_ctxc                 C   sf   |  ||}| || t|dd dkr<| j||jd d n&t|tjrb| j|j|jj|j|d d S )NoriginZunknown_type)
approxname)r   	named_ptr)	r   r   re   _struct_ctxr	   rX   r   ZNamedPointerTypetotyper   r   r   r   _generate_cpy_typedef_ctxw  s    z$Recompiler._generate_cpy_typedef_ctxc                 C   s(   |  |  |jr$| js$|  | d S r   )rm   rn   ellipsisrB   r   r   r   r   "_generate_cpy_function_collecttype  s    z-Recompiler._generate_cpy_function_collecttypec              	   C   s  | j r
tt|tjst|jr0| || d S | j}t|j	}|dkrNd}n|dkr\d}nd}g }g }d| }t
|j	D ],\}	}
||
d|	 | |d|	  qzd	|}|pd
}|jr|jd }nd}d|||f }|d|j|f  |d d	|}d}t|jtjrd}|d|||f  |d |d |d |d||f  |d d| }t
|j	D ]&\}	}
|
d|	 |}|d|  qrt }|j	D ]}
| |
| q|D ]}|d|f  qt|jtjsd}d| }d|jd| }|| nd }d}t|j	dkrtt|j	}|D ]}	|d|	  q6|  |d|t|t|d	dd |D f  |d |  t
|j	D ](\}	}
| |
d|	 d|	 d  |  q|d! |d" d#d tt|j	D }d	|}|d$|||f  |d% |d& |  |d' |dkr2|d( |rR|d)| |jd*d+  n|d, |d- |d |d. d/d0 }d1}g }g }d| }t
|j	D ]P\}	}
d}||
rd2}d3}|
d4||	f |}|| |d5||	f  q|j}||r,d| }|d6|}|d| tj}d }d7}d3}|rd	|}|pDd
}d8|||f }|d||f  |d |r~|| d	|}|d$|||f  |r|d9 |d n|d:||f  |d; |  d S )<Nr   Znoargr   Zarg0rW   argument of %sz x%dx%dr   voidr   r#   z%s_cffi_d_%s(%s)z	static %sr   zreturn z  %s%s(%s);r   z#ifndef PYPY_VERSIONzstatic PyObject *z(_cffi_f_%s(PyObject *self, PyObject *%s)z  %s;z	result = result of %sz resultz  PyObject *arg%d;z1  if (!PyArg_UnpackTuple(args, "%s", %d, %d, %s))c                 S   s   g | ]}d | qS )z&arg%dr   r   r   r   r   r1     s     z:Recompiler._generate_cpy_function_decl.<locals>.<listcomp>r   zarg%dzreturn NULLz  Py_BEGIN_ALLOW_THREADSz  _cffi_restore_errno();c                 S   s   g | ]}d | qS )r   r   r   r   r   r   r1     s     z  { %s%s(%s); }z  _cffi_save_errno();z  Py_END_ALLOW_THREADSz  (void)self; /* unused */z  (void)noarg; /* unused */z  return %s;resultzresult typez  Py_INCREF(Py_None);z  return Py_None;r   c                 S   s    t | tjpt | tjo|  S r   )rX   r   rb   PrimitiveTyper   )r   r   r   r   need_indirection  s    z@Recompiler._generate_cpy_function_decl.<locals>.need_indirectionFr   Tz %sx%dz%sx%dz *resultz
*result = z%s_cffi_f_%s(%s)z  return result;z#  define _cffi_f_%s _cffi_d_%sr   )rB   rU   rX   r   r]   r   _generate_cpy_constant_declr   r    rW   rd   rV   r   r4   abir   rY   r   r   r   r   r   insertZ	void_type)r   rM   r	   r   numargsargname	argumentsZcall_argumentsr   rj   r   repr_argumentsr   name_and_argumentsZresult_codeargr   r   Zresult_declrngr   
differenceZindirectionZ	tp_resultr   r   r   _generate_cpy_function_decl  s   





  









z&Recompiler._generate_cpy_function_declc                 C   s   |j r| js| || d S | j|  }t|j}| jr@t}n |dkrNt}n|dkr\t	}nt
}| jd t|d| t||d| d d S )Nr   r   r   z
_cffi_f_%sz
_cffi_d_%s)r   )r   rB   _generate_cpy_constant_ctxrP   rn   r    rW   ZOP_DLOPEN_FUNCZOP_CPYTHON_BLTN_NZOP_CPYTHON_BLTN_OZOP_CPYTHON_BLTN_Vr   rV   r   rg   )r   rM   r	   r*   r   Z	meth_kindr   r   r   _generate_cpy_function_ctx#  s$    


z%Recompiler._generate_cpy_function_ctxc                 C   sT   t |tjrP|j}|dkr0|d}d||f }| |d| |j}t||}|S )N...r   z_cffi_array_len(((%s)0)->%s)%s[0])rX   r   r   r^   r   rs   r   )r   Z	tp_struct
field_nameZtp_fieldactual_lengthZptr_struct_nametp_itemr   r   r   rs   9  s    
 zRecompiler._field_typec                 C   s,   |  | | jr(| D ]}| | qd S r   )rm   rB   anonymous_struct_fields_struct_collecttype)r   rM   fldtyper   r   r   r	  E  s    
zRecompiler._struct_collecttypec                 C   s>  |j d krd S | j}d|f }|d |d||f  |d |d |d | D ]\}}}}	z| st|dkr|dkr|d	|||f  W qVt|tjr|jd ks|jd
kr|j}|d }q|d|j	dd| |	d|f  W qV t
k
r }
 z|dt|
  W 5 d }
~
X Y qVX qV|d |d||f  |  d S )Nz_cffi_checkfld_%sZ_CFFI_UNUSED_FNzstatic void %s(%s *p)r   z8  /* only to generate compile-time warnings or errors */z
  (void)p;r   r#   z>  (void)((p->%s) | 0);  /* check that '%s.%s' is an integer */r  z[0]z  { %s = &p->%s; (void)tmp; }z*tmpzfield %rr}   z
  /* %s */r   z(struct _cffi_align_%s { char x; %s y; };)ro   r   rr   r   rX   r   r   r^   r   r   r   rS   )r   rM   r   r   r   ZcheckfuncnamefnameZftyper   fqualr   r   r   r   _struct_declL  sB    


$zRecompiler._struct_declNc                 C   s  | j | }d }g }t|tjr(|d |jd kr@|d d}|| jjjkr|d ksd|| jjjkr|jd krpn|j	st
| rn
|d |jr|jdkrtd||jf |d n|d d	}d
|pd}g }|d krr| j }	t||	}
|
D ]\}}}}| |||}| |d|j|f  t}|dkrNt}d| }nL|d ksrt|tjrx|jd krxd}n"d|d kr|dn|j|f }|d ks|dkrd}n,|d k	rd|j|f }nd|d|f }|t||||t|| j |  q t| jd }| jd | |d kr<d}d}d}n4|d k	rXd|jf }d}nd|f }d|f }d }nd}d}d}|}| jd t|j||||||| | j !| d S )NZ_CFFI_F_UNIONZ_CFFI_F_OPAQUEopaqueZ_CFFI_F_CHECK_FIELDSr   z%r is declared with 'pack=%r'; only 0 or 1 are supported in API mode (try to use "...;", which does not require a 'pack' declaration)Z_CFFI_F_PACKEDZ_CFFI_F_EXTERNALZexternal|0zfield '%s.%s'r   z%d /* bits */z
(size_t)-1zsizeof(((%s)0)->%s)r   z"((char *)&((%s)0)->%s) - (char *)0zoffsetof(%s, %s)r#   r   z
(size_t)-2Zunnamedzsizeof(*(%s)0)z-1 /* unknown alignment */
sizeof(%s)z"offsetof(struct _cffi_align_%s, y)r   r   )"rP   rX   r   Z	UnionTyperV   ro   r@   rp   rq   partialanyr  packedr"   r4   rB   r   rr   rs   _check_not_opaquer	   r%   r&   r   r^   r   r   rg   r    r   extendr)   r   r   )r   rM   r   r   r   r*   Zreason_for_not_expandingr+   r/   Zexpand_anonymous_struct_unionrr   Zfldnamer
  r   r  r$   r   offsetr.   Zalignr-   r   r   r   r   n  s    













 





 zRecompiler._struct_ctxc                 C   s:   t |tjr|j}q t |tjr6|jd kr6td| d S )Nz0%s is of an opaque type (not declared in cdef()))rX   r   r   r   rb   ro   r   )r   rM   locationr   r   r   r    s    zRecompiler._check_not_opaquec                 C   s   t | j }|jdd d |D ]\}}|| jkr"|jrHtd|f |jdrv|jdd  	 rv|jdd  }n4|jdkr|j
dkrd}| |d ntd	|f | |d | q"d S )
Nc                 S   s   | d S )Nr   r   )Ztp_orderr   r   r   rN     rO   z7Recompiler._add_missing_struct_unions.<locals>.<lambda>rH   zDinternal inconsistency: %r is partial but was not seen at this point$r   Z_IO_FILEFILEzinternal inconsistency: %r)r   r`   rv   r   r   r  r"   r	   
startswithisdigitZ	forcenamer   r   )r   r|   rM   orderr   r   r   r   r     s"    
z%Recompiler._add_missing_struct_unionsc                 C   s   |  | d S r   )r	  r   r   r   r    _generate_cpy_struct_collecttype  s    z+Recompiler._generate_cpy_struct_collecttypec                 C   s2   | d}d|kr"||ddfS |d| fS d S )Nr#   r   ru   )r   r   )r   rM   r   r   r   r   _struct_names  s    
zRecompiler._struct_namesc                 C   s   | j |f| |  d S r   )r  r!  r   r   r   r   _generate_cpy_struct_decl  s    z$Recompiler._generate_cpy_struct_declc                 C   s   | j |f| |  d S r   )r   r!  r   r   r   r   _generate_cpy_struct_ctx  s    z#Recompiler._generate_cpy_struct_ctxc                 C   s(   t |tjr| || n
| | d S r   )rX   r   rc   _generate_cpy_enum_collecttyper	  r   r   r   r   #_generate_cpy_anonymous_collecttype  s    z.Recompiler._generate_cpy_anonymous_collecttypec                 C   s.   t |tjr| | n| ||d|  d S NZtypedef_)rX   r   rc   _generate_cpy_enum_declr  r   r   r   r   _generate_cpy_anonymous_decl   s    z'Recompiler._generate_cpy_anonymous_declc                 C   s0   t |tjr| || n| ||d|  d S r&  )rX   r   rc   	_enum_ctxr   r   r   r   r   _generate_cpy_anonymous_ctx  s    z&Recompiler._generate_cpy_anonymous_ctxconstc                 C   s   ||f| j krtd||f | j ||f | j}d||f }|r|d|  |d |d|f  |d||f  |d k	r|dkrd|f }|d	|f  |d
 |d |d n>|d kst|d|  |d |d|d|f  |d |  d S )Nz duplicate declaration of %s '%s'z_cffi_%s_%sz$static int %s(unsigned long long *o)r   z  int n = (%s) <= 0;zI  *o = (unsigned long long)((%s) | 0);  /* check that %s is an integer */r   z%dUz"  if (!_cffi_check_int(*o, n, %s))z    n |= 2;z  return n;r   zstatic void %s(char *o)z  *(%s)o = %s;r   )r   r   r   r   rU   r   )r   is_intr	   rM   categoryr   r   funcnamer   r   r   _generate_cpy_const  s6    


zRecompiler._generate_cpy_constc                 C   s    |  }|r| jr| | d S r   )r   rB   rm   r   rM   r	   r,  r   r   r   "_generate_cpy_constant_collecttype-  s    
z-Recompiler._generate_cpy_constant_collecttypec                 C   s   |  }| ||| d S r   )r   r/  r0  r   r   r   r   2  s    z&Recompiler._generate_cpy_constant_declc                 C   s^   | j s| rttd}n$| j r&t}nt}| j| }t||}| jd t	|d| | d S )Nr   r   _cffi_const_%s)
rB   r   rg   OP_CONSTANT_INTZOP_DLOPEN_CONSTZOP_CONSTANTrP   r   rV   r   )r   rM   r	   r   Z
const_kindr*   r   r   r   r  6  s    


z%Recompiler._generate_cpy_constant_ctxc                 C   s   |  | d S r   )rm   r   r   r   r   r$  F  s    z)Recompiler._generate_cpy_enum_collecttypec                 C   s   |j D ]}| d| qd S )NT)enumeratorsr/  )r   rM   r	   
enumeratorr   r   r   r'  I  s    
z"Recompiler._generate_cpy_enum_declc              	   C   s   | j | }ttd}| jr"|  t|j|jD ](\}}| jd 	t
|d| ||d q0|d k	rd|kr| jsd| }d| }n4|| jg }	| j|	}tt| j|	ddk }d	|j}
| jd
 	t|j||||
 d S )Nr   r   r2  r   r  r  z((%s)-1) <= 0r   r2   r   )rP   rg   OP_ENUMrB   Zcheck_not_partialzipr4  Z
enumvaluesr   rV   r   Zbuild_baseinttyper@   sizeofintcastr4   r5   r	   )r   rM   r   r*   r   r5  Z	enumvaluer   r7   Zbasetpr8   r   r   r   r)  M  s(    




zRecompiler._enum_ctxc                 C   s   |  ||  d S r   )r)  r   r   r   r   r   _generate_cpy_enum_ctxb  s    z!Recompiler._generate_cpy_enum_ctxc                 C   s   d S r   r   r   r   r   r   _generate_cpy_macro_collecttypeh  s    z*Recompiler._generate_cpy_macro_collecttypec                 C   s&   |dkrd }n|}| j d||d d S )Nr  Tr6  )r/  )r   rM   r	   r   r   r   r   _generate_cpy_macro_declk  s    z#Recompiler._generate_cpy_macro_declc                 C   sT   |dkr"| j rtd|f d }n|}ttd}| jd t|d| ||d d S )Nr  zGcannot use the syntax '...' in '#define %s ...' when using the ABI moder   r   r2  r6  )rB   r   rg   r3  r   rV   r   )r   rM   r	   r   r   r   r   r   _generate_cpy_macro_ctxr  s    

z"Recompiler._generate_cpy_macro_ctxc                 C   sF   t |tjrB|j}|dkr$d|f }| |jd| }t||}|S )Nr  z_cffi_array_len(%s)r  )rX   r   r   r^   r   r   )r   rM   Zglobal_namer  r  r   r   r   r     s    
zRecompiler._global_typec                 C   s   |  | || d S r   )rm   r   r   r   r   r   "_generate_cpy_variable_collecttype  s    z-Recompiler._generate_cpy_variable_collecttypec                 C   s   | j }| ||}t|tjr4|jd kr4|j}d}nd}d|f }|d|j|| jd  |d |d||f  |d |  d S )	Nr#   &z*_cffi_var_%s(void)static r  r   z  return %s(%s);r   )	r   r   rX   r   r   r^   r   r   ry   )r   rM   r	   r   Z	ampersandr   r   r   r   _generate_cpy_variable_decl  s    	
z&Recompiler._generate_cpy_variable_declc                 C   sL   |  ||}| j| }| jr"t}nt}| jd t|d| t|| d S )Nr   z_cffi_var_%s)	r   rP   rB   ZOP_GLOBAL_VARZOP_GLOBAL_VAR_Fr   rV   r   rg   )r   rM   r	   r*   r$   r   r   r   _generate_cpy_variable_ctx  s    

z%Recompiler._generate_cpy_variable_ctxc                 C   s   t |tjst| | d S r   )rX   r   r]   rU   rm   r   r   r   r   '_generate_cpy_extern_python_collecttype  s    z2Recompiler._generate_cpy_extern_python_collecttypec                 C   s  | j }t|jtjrd}nd| }d|jd|f }|d|  |d| j||f  |  g }d| }t|jD ]"\}}	|	d| |}
|	|
 qrd	
|}|pd
}d||f }|jdkrd| }dd }tt|jd d}||jrt|d}t|jtjr&d|jd||jd|f }|d||j|f  |d |d|  |d t|jD ]X\}}	d| }
t|	tjs||	rd|
 }
t|	}	|d|	d|d |
f  qd|d|  t|jtjs|d|jdf  |d |  |  jd7  _d S )Nr  r   z(int)sizeof(%s)r#   z3static struct _cffi_externpy_s _cffi_externpy__%s =z  { "%s.%s", %s };r   z a%dr   r   z%s(%s)	__stdcallz_cffi_stdcall c                 S   s   t | tjo| jdkS )Nr   )rX   r   r   r	   rL   r   r   r   may_need_128_bits  s    z9Recompiler._extern_python_decl.<locals>.may_need_128_bitsr;      z!sizeof(%s) > %d ? sizeof(%s) : %dz%s%sr   z  char a[%s];z  char *p = a;za%drA  z  *(%s)(p + %d) = %s;r   z,  _cffi_call_python(&_cffi_externpy__%s, p);z  return *(%s)p;r   r   )r   rX   r   r   rY   r   rA   rd   rW   rV   r4   r   rE   r    rb   r[   r   )r   rM   r	   Ztag_and_spacer   Zsize_of_resultr   r   rj   r   r   r   r   rG  Z	size_of_ar   r   r   _extern_python_decl  sb    




 
 
 zRecompiler._extern_python_declc                 C   s   |  ||d d S )NrB  rI  r   r   r   r    _generate_cpy_extern_python_decl  s    z+Recompiler._generate_cpy_extern_python_declc                 C   s   |  ||d d S )NzCFFI_DLLEXPORT rJ  r   r   r   r   #_generate_cpy_dllexport_python_decl  s    z.Recompiler._generate_cpy_dllexport_python_declc                 C   s   |  ||d d S )Nr#   rJ  r   r   r   r   '_generate_cpy_extern_python_plus_c_decl  s    z2Recompiler._generate_cpy_extern_python_plus_c_declc                 C   sR   | j rtd|jrtd| j| }tt|}| jd t	|d| || d S )Nz,cannot use 'extern "Python"' in the ABI modez$a vararg function is extern "Python"r   z&_cffi_externpy__%s)
rB   r   r   r"   rP   rg   ZOP_EXTERN_PYTHONr   rV   r   )r   rM   r	   r*   r   r   r   r   _generate_cpy_extern_python_ctx  s    


z*Recompiler._generate_cpy_extern_python_ctxc                 C   sr   | j }|d |dD ]T}|d|   d}|D ].}t|dkrP|| d}|dt|f 7 }q4|| qd S )Nz=// # NB. this is not a string because of a size limit in MSVCTz// r#   L   z%d,)r   
splitlinesrstripr    ord)r   sr   lineZprinted_linecr   r   r   r     s    z)Recompiler._print_string_literal_in_arrayc                 C   s   t tt| j|< d S r   )rg   OP_PRIMITIVEZ	PRIM_VOIDrT   r   rM   r   r   r   r   _emit_bytecode_VoidType  s    z"Recompiler._emit_bytecode_VoidTypec                 C   s   t |j }tt|| j|< d S r   )ZPRIMITIVE_TO_INDEXr	   rg   rV  rT   )r   rM   r   r<   r   r   r   _emit_bytecode_PrimitiveType  s    
z'Recompiler._emit_bytecode_PrimitiveTypec                 C   s(   d|j |j |j f }tt|| j|< d S )Nzl_cffi_prim_int(sizeof(%s), (
           ((%s)-1) | 0 /* check that %s is an integer type */
         ) <= 0)r	   rg   rV  rT   r   rM   r   rS  r   r   r   !_emit_bytecode_UnknownIntegerType  s    z,Recompiler._emit_bytecode_UnknownIntegerTypec                 C   s$   d|j |j f }tt|| j|< d S )Nzd_cffi_prim_float(sizeof(%s) *
           (((%s)1) / 2) * 2 /* integer => 0, float => 1 */
         )rZ  r[  r   r   r   _emit_bytecode_UnknownFloatType$  s    
z*Recompiler._emit_bytecode_UnknownFloatTypec                 C   s   t t| j|j | j|< |d7 }|jD ]H}| j| }||krft|tjrV| 	|| nt t
|| j|< |d7 }q&t|j}|jd k	r|jdkr|dO }ntd|jf t t|| j|< d S )Nr   rF  r9   zabi=%r)rg   ZOP_FUNCTIONrP   r   rT   rW   rX   r   r   rY  r%   r:  r   r   r"   ZOP_FUNCTION_END)r   rM   r   ri   Z	realindexr+   r   r   r   _emit_bytecode_RawFunctionType*  s    






z)Recompiler._emit_bytecode_RawFunctionTypec                 C   s   t t| j|j | j|< d S r   )rg   
OP_POINTERrP   r   rT   rW  r   r   r   _emit_bytecode_PointerType=  s    z%Recompiler._emit_bytecode_PointerTypec                 C   s"   |  }tt| j| | j|< d S r   )rn   rg   r_  rP   rT   )r   rM   r   rawr   r   r   _emit_bytecode_FunctionPtrTypeC  s    z)Recompiler._emit_bytecode_FunctionPtrTypec                 C   s   | j |j }|jd kr(tt|| j|< nf|jdkrNtdt|ddf n@| j|d  dksdt	tt
|| j|< td t|j| j|d < d S )Nr  zitype %s badly placed: the '...' array length can only be used on global arrays or on fields of structuresz/*...*/r   rJ   )rP   r   r^   rg   ZOP_OPEN_ARRAYrT   r   rS   r   rU   ZOP_ARRAY)r   rM   r   Z
item_indexr   r   r   _emit_bytecode_ArrayTypeG  s    

z#Recompiler._emit_bytecode_ArrayTypec                 C   s   | j | }tt|| j|< d S r   )r`   rg   ZOP_STRUCT_UNIONrT   )r   rM   r   Zstruct_indexr   r   r   _emit_bytecode_StructTypeU  s    
z$Recompiler._emit_bytecode_StructTypec                 C   s   | j | }tt|| j|< d S r   )ra   rg   r7  rT   )r   rM   r   Z
enum_indexr   r   r   _emit_bytecode_EnumTypeZ  s    
z"Recompiler._emit_bytecode_EnumType)F)r#   )N)Nr+  N)N)Ur   r   r   r   r   rG   rl   rm   rQ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  rs   r	  r  r   r  r   r   Z_generate_cpy_union_collecttyper!  r"  Z_generate_cpy_union_declr#  Z_generate_cpy_union_ctxr%  r(  r*  r/  r1  r   r  r$  r'  r)  r<  r=  r>  r?  r   r@  rC  rD  rE  Z*_generate_cpy_dllexport_python_collecttypeZ._generate_cpy_extern_python_plus_c_collecttyperI  rK  rL  rM  rN  Z"_generate_cpy_dllexport_python_ctxZ&_generate_cpy_extern_python_plus_c_ctxr   rX  rY  r\  r]  r^  r`  Z_emit_bytecode_ConstPointerTypeZ_emit_bytecode_NamedPointerTyperb  rc  rd  Z_emit_bytecode_UnionTypere  r   r   r   r   r?   {   s   
:
 ,
4-# "
W	  

	5r?   )   c                       s   e Zd Z fddZ  ZS )NativeIOc                    s(   t |tr|d}tt| | d S )Nascii)rX   unicodeencodesuperrg  r   )r   rS  rf   r   r   r   c  s    

zNativeIO.write)r   r   r   r   __classcell__r   r   rl  r   rg  b  s   rg  c           
      C   s  |rt d|f  t| ||d kd}|  |  t }||| | }zBt|d }|t	|d |krvt
W 5 Q R X |rt d W dS  t
k
r   d|t f }	t|	d}|| W 5 Q R X zt|	| W n, tk
r   t| t|	| Y nX Y d	S X d S )
Nzgenerating %s)rB   r   r   z(already up-to-date)Fz%s.~%dwT)printr?   rl   r   rg  r   getvaluer   readr    IOErrorr   getpidr   renameOSErrorunlink)
r@   rA   r   Ztarget_fileverboseZ
recompilerr   outputf1Ztmp_filer   r   r   _make_c_or_py_sourceh  s6    
rz  Fc                 C   s   |d k	st t| ||||S r   )rU   rz  )r@   rA   r   Ztarget_c_filerw  r   r   r   make_c_source  s    
r{  c                 C   s   t | |d ||S r   )rz  )r@   rA   Ztarget_py_filerw  r   r   r   make_py_source  s    
r|  c                 C   sj   | d}z$ttjj| f|d d   W n tk
rB   Y nX |d  |7  < tjj| f| |fS )Nr   r   )rw   r   makedirsr   r4   ru  )Z	outputdirmodname	extensionpartsr   r   r   _modname_to_file  s    
$r  c                 C   s*   t ||}| |||f t||| |S r   )re   rV   setattr)	patchlistclsr	   Znew_metholdr   r   r   _patch_meth  s    
r  c                 C   s$   t | D ]\}}}t||| qd S r   )reversedr  )r  r  r	   Zold_methr   r   r   _unpatch_meths  s    r  c                    s\   t jdkr(ddlm} t| |ddd  t jdkrXddlm}  fd	d
}t| |d| d S )Nwin32r   )MSVCCompilerZ_remove_visual_c_refc                 S   s   |S r   r   )r   Zmanifest_filer   r   r   rN     rO   z&_patch_for_embedding.<locals>.<lambda>darwin)	CCompilerc                    s<   d| j kr,t| j | _ | j d}d| j |<  | f||S )Nz-bundlez-dynamiclib)	linker_sor   r   )r   rW   kwdsrj   Zold_link_shared_objectr   r   my_link_shared_object  s
    

z3_patch_for_embedding.<locals>.my_link_shared_objectZlink_shared_object)sysplatformZdistutils.msvc9compilerr  r  distutils.ccompilerr  )r  r  r  r  r   r  r   _patch_for_embedding  s    

r  c                    sl   ddl m}  drR d d  tjdkr6 d7  ntjdkrJ d7  n d	7  t| |d
 fdd d S )Nr   )	build_extz.*r  r  z.dllr  z.dylibz.soZget_ext_filenamec                    s    S r   r   )r   Zext_nametargetr   r   rN     rO   z#_patch_for_target.<locals>.<lambda>)Zdistutils.command.build_extr  endswithr  r  r  )r  r  r  r   r  r   _patch_for_target  s    





r  r   T.cc              	   K   s  t |ts|d}| jr$| | |d k	r^| jd k	}|rF| | |d krzt|||\}}|rl|g| }tj	j
| }n|}|	d kr|rd| }	nd}	tj||f|}t| ||||d}|rTg }t }zn|rt| |	dkrt||	 |r|dkrd}nd}td|tj	|f  t| td|||
}W 5 t| t| X |S ||fS n<|d krxt||d	\}}t| |||d}|r|S d |fS d S )
Nrh  z%s.*r   )rw  r   zthe current directory isz setting the current directory toz%s %rz.py)rX   rS   rj  Z_windows_unicodeZ_apply_windows_unicoder   Z_apply_embedding_fixr  r   r   r4   r   get_extensionr{  getcwdchdirr  r  r  ro  abspathcompiler|  )r@   rA   r   ZtmpdirZcall_c_compilerZc_fileZsource_extensionZextradirZcompiler_verboser  debugr  Z	embeddingr  Z
ext_c_fileextupdatedr  cwdmsgZoutputfilenameru   r   r   r   	recompile  sl    











 



r  )F)F)r   TNr  Nr   NN)r   r  ior#   r   r   errorr   Zcffi_opcoderC   r   r   r   r   r)   r5   r=   r?   version_infoStringIOrg  BytesIOrz  r{  r|  r  r  r  r  r  r  r   r   r   r   <module>   sP            m


           