Home | History | Annotate | Download | only in php
      1 /* -----------------------------------------------------------------------------
      2  * phprun.swg
      3  *
      4  * PHP runtime library
      5  * ----------------------------------------------------------------------------- */
      6 
      7 #ifdef __cplusplus
      8 extern "C" {
      9 #endif
     10 #include "zend.h"
     11 #include "zend_API.h"
     12 #include "zend_exceptions.h"
     13 #include "php.h"
     14 #include "ext/standard/php_string.h"
     15 #include <stdlib.h> /* for abort(), used in generated code. */
     16 
     17 #ifdef ZEND_RAW_FENTRY
     18 /* ZEND_RAW_FENTRY was added somewhere between 5.2.0 and 5.2.3 */
     19 # define SWIG_ZEND_NAMED_FE(ZN, N, A) ZEND_RAW_FENTRY((char*)#ZN, N, A, 0)
     20 #else
     21 /* This causes warnings from GCC >= 4.2 (assigning a string literal to char*).
     22  * But this seems to be unavoidable without directly assuming knowledge of
     23  * the structure, which changed between PHP4 and PHP5. */
     24 # define SWIG_ZEND_NAMED_FE(ZN, N, A) ZEND_NAMED_FE(ZN, N, A)
     25 #endif
     26 
     27 #ifndef Z_SET_ISREF_P
     28 /* For PHP < 5.3 */
     29 # define Z_SET_ISREF_P(z) (z)->is_ref = 1
     30 #endif
     31 #ifndef Z_SET_REFCOUNT_P
     32 /* For PHP < 5.3 */
     33 # define Z_SET_REFCOUNT_P(z, rc) (z)->refcount = (rc)
     34 #endif
     35 
     36 #define SWIG_LONG_CONSTANT(N, V) zend_register_long_constant((char*)#N, sizeof(#N), V, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC)
     37 #define SWIG_DOUBLE_CONSTANT(N, V) zend_register_double_constant((char*)#N, sizeof(#N), V, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC)
     38 #define SWIG_STRING_CONSTANT(N, V) zend_register_stringl_constant((char*)#N, sizeof(#N), (char*)(V), strlen(V), CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC)
     39 #define SWIG_CHAR_CONSTANT(N, V) do {\
     40     static char swig_char = (V);\
     41     zend_register_stringl_constant((char*)#N, sizeof(#N), &swig_char, 1, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);\
     42 } while (0)
     43 
     44 /* These TSRMLS_ stuff should already be defined now, but with older php under
     45    redhat are not... */
     46 #ifndef TSRMLS_D
     47 #define TSRMLS_D
     48 #endif
     49 #ifndef TSRMLS_DC
     50 #define TSRMLS_DC
     51 #endif
     52 #ifndef TSRMLS_C
     53 #define TSRMLS_C
     54 #endif
     55 #ifndef TSRMLS_CC
     56 #define TSRMLS_CC
     57 #endif
     58 
     59 #ifdef __cplusplus
     60 }
     61 #endif
     62 
     63 /* But in fact SWIG_ConvertPtr is the native interface for getting typed
     64    pointer values out of zvals.  We need the TSRMLS_ macros for when we
     65    make PHP type calls later as we handle php resources */
     66 #define SWIG_ConvertPtr(obj,pp,type,flags) SWIG_ZTS_ConvertPtr(obj,pp,type,flags TSRMLS_CC)
     67 
     68 
     69 #define SWIG_fail goto fail
     70 
     71 static const char *default_error_msg = "Unknown error occurred";
     72 static int default_error_code = E_ERROR;
     73 
     74 #define SWIG_PHP_Arg_Error_Msg(argnum,extramsg) "Error in argument " #argnum " "#extramsg
     75 
     76 #define SWIG_PHP_Error(code,msg) do { SWIG_ErrorCode() = code; SWIG_ErrorMsg() = msg; SWIG_fail; } while (0)
     77 
     78 #define SWIG_contract_assert(expr,msg) \
     79   if (!(expr) ) { zend_printf("Contract Assert Failed %s\n",msg ); } else
     80 
     81 /* Standard SWIG API */
     82 #define SWIG_GetModule(clientdata) SWIG_Php_GetModule(clientdata)
     83 #define SWIG_SetModule(clientdata, pointer) SWIG_Php_SetModule(pointer)
     84 
     85 /* used to wrap returned objects in so we know whether they are newobject
     86    and need freeing, or not */
     87 typedef struct {
     88   void * ptr;
     89   int newobject;
     90 } swig_object_wrapper;
     91 
     92 /* empty zend destructor for types without one */
     93 static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) { (void)rsrc; }
     94 
     95 #define SWIG_SetPointerZval(a,b,c,d) SWIG_ZTS_SetPointerZval(a,b,c,d TSRMLS_CC)
     96 #define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a))
     97 
     98 static void
     99 SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject TSRMLS_DC) {
    100   /*
    101    * First test for Null pointers.  Return those as PHP native NULL
    102    */
    103   if (!ptr ) {
    104     ZVAL_NULL(z);
    105     return;
    106   }
    107   if (type->clientdata) {
    108     swig_object_wrapper *value;
    109     if (! (*(int *)(type->clientdata)))
    110       zend_error(E_ERROR, "Type: %s failed to register with zend",type->name);
    111     value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper));
    112     value->ptr=ptr;
    113     value->newobject=(newobject & 1);
    114     if ((newobject & 2) == 0) {
    115       /* Just register the pointer as a resource. */
    116       ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata));
    117     } else {
    118       /*
    119        * Wrap the resource in an object, the resource will be accessible
    120        * via the "_cPtr" member. This is currently only used by
    121        * directorin typemaps.
    122        */
    123       zval *resource;
    124       zend_class_entry **ce = NULL;
    125       const char *type_name = type->name+3; /* +3 so: _p_Foo -> Foo */
    126       size_t type_name_len;
    127       int result;
    128       const char * p;
    129 
    130       /* Namespace__Foo -> Foo */
    131       /* FIXME: ugly and goes wrong for classes with __ in their names. */
    132       while ((p = strstr(type_name, "__")) != NULL) {
    133         type_name = p + 2;
    134       }
    135       type_name_len = strlen(type_name);
    136 
    137       MAKE_STD_ZVAL(resource);
    138       ZEND_REGISTER_RESOURCE(resource, value, *(int *)(type->clientdata));
    139       if (SWIG_PREFIX_LEN > 0) {
    140         char * classname = (char*)emalloc(SWIG_PREFIX_LEN + type_name_len + 1);
    141         strcpy(classname, SWIG_PREFIX);
    142         strcpy(classname + SWIG_PREFIX_LEN, type_name);
    143         result = zend_lookup_class(classname, SWIG_PREFIX_LEN + type_name_len, &ce TSRMLS_CC);
    144         efree(classname);
    145       } else {
    146         result = zend_lookup_class((char *)type_name, type_name_len, &ce TSRMLS_CC);
    147       }
    148       if (result != SUCCESS) {
    149         /* class does not exist */
    150         object_init(z);
    151       } else {
    152         object_init_ex(z, *ce);
    153       }
    154       Z_SET_REFCOUNT_P(z, 1);
    155       Z_SET_ISREF_P(z);
    156       zend_hash_update(HASH_OF(z), (char*)"_cPtr", sizeof("_cPtr"), (void*)&resource, sizeof(zval), NULL);
    157     }
    158     return;
    159   }
    160   zend_error(E_ERROR, "Type: %s not registered with zend",type->name);
    161 }
    162 
    163 /* This pointer conversion routine takes the native pointer p (along with
    164    its type name) and converts it by calling appropriate casting functions
    165    according to ty.  The resultant pointer is returned, or NULL is returned
    166    if the pointer can't be cast.
    167 
    168    Sadly PHP has no API to find a type name from a type id, only from an
    169    instance of a resource of the type id, so we have to pass type_name as well.
    170 
    171    The two functions which might call this are:
    172    SWIG_ZTS_ConvertResourcePtr which gets the type name from the resource
    173    and the registered zend destructors for which we have one per type each
    174    with the type name hard wired in. */
    175 static void *
    176 SWIG_ZTS_ConvertResourceData(void * p, const char *type_name, swig_type_info *ty TSRMLS_DC) {
    177   swig_cast_info *tc;
    178   void *result = 0;
    179 
    180   if (!ty) {
    181     /* They don't care about the target type, so just pass on the pointer! */
    182     return p;
    183   }
    184 
    185   if (! type_name) {
    186     /* can't convert p to ptr type ty if we don't know what type p is */
    187     return NULL;
    188   }
    189 
    190   /* convert and cast p from type_name to ptr as ty. */
    191   tc = SWIG_TypeCheck(type_name, ty);
    192   if (tc) {
    193     int newmemory = 0;
    194     result = SWIG_TypeCast(tc, p, &newmemory);
    195     assert(!newmemory); /* newmemory handling not yet implemented */
    196   }
    197   return result;
    198 }
    199 
    200 /* This function returns a pointer of type ty by extracting the pointer
    201    and type info from the resource in z.  z must be a resource.
    202    If it fails, NULL is returned.
    203    It uses SWIG_ZTS_ConvertResourceData to do the real work. */
    204 static void *
    205 SWIG_ZTS_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags TSRMLS_DC) {
    206   swig_object_wrapper *value;
    207   void *p;
    208   int type;
    209   const char *type_name;
    210 
    211   value = (swig_object_wrapper *) zend_list_find(z->value.lval, &type);
    212   if (type==-1) return NULL;
    213   if (flags & SWIG_POINTER_DISOWN) {
    214     value->newobject = 0;
    215   }
    216   p = value->ptr;
    217 
    218   type_name=zend_rsrc_list_get_rsrc_type(z->value.lval TSRMLS_CC);
    219 
    220   return SWIG_ZTS_ConvertResourceData(p, type_name, ty TSRMLS_CC);
    221 }
    222 
    223 /* We allow passing of a RESOURCE pointing to the object or an OBJECT whose
    224    _cPtr is a resource pointing to the object */
    225 static int
    226 SWIG_ZTS_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags TSRMLS_DC) {
    227   if (z == NULL) {
    228     *ptr = 0;
    229     return 0;
    230   }
    231 
    232   switch (z->type) {
    233     case IS_OBJECT: {
    234       zval ** _cPtr;
    235       if (zend_hash_find(HASH_OF(z),(char*)"_cPtr",sizeof("_cPtr"),(void**)&_cPtr)==SUCCESS) {
    236 	if ((*_cPtr)->type==IS_RESOURCE) {
    237 	  *ptr = SWIG_ZTS_ConvertResourcePtr(*_cPtr, ty, flags TSRMLS_CC);
    238 	  return (*ptr == NULL ? -1 : 0);
    239 	}
    240       }
    241       break;
    242     }
    243     case IS_RESOURCE:
    244       *ptr = SWIG_ZTS_ConvertResourcePtr(z, ty, flags TSRMLS_CC);
    245       return (*ptr == NULL ? -1 : 0);
    246     case IS_NULL:
    247       *ptr = 0;
    248       return 0;
    249   }
    250 
    251   return -1;
    252 }
    253 
    254 static char const_name[] = "swig_runtime_data_type_pointer";
    255 static swig_module_info *SWIG_Php_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
    256   zval *pointer;
    257   swig_module_info *ret = 0;
    258 
    259   MAKE_STD_ZVAL(pointer);
    260 
    261   TSRMLS_FETCH();
    262 
    263   if (zend_get_constant(const_name, sizeof(const_name) - 1, pointer TSRMLS_CC)) {
    264     if (pointer->type == IS_LONG) {
    265       ret = (swig_module_info *) pointer->value.lval;
    266     }
    267   }
    268   FREE_ZVAL(pointer);
    269   return ret;
    270 }
    271 
    272 static void SWIG_Php_SetModule(swig_module_info *pointer) {
    273   TSRMLS_FETCH();
    274   REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, 0);
    275 }
    276