1999-04-08 02:10:10 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2012-01-01 21:15:04 +08:00
| Copyright ( c ) 1998 - 2012 Zend Technologies Ltd . ( http : //www.zend.com) |
1999-04-08 02:10:10 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 23:16:21 +08:00
| This source file is subject to version 2.00 of the Zend license , |
2006-05-13 18:37:45 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
2001-12-11 23:16:21 +08:00
| http : //www.zend.com/license/2_00.txt. |
1999-07-16 22:58:16 +08:00
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ zend . com so we can mail you a copy immediately . |
1999-04-08 02:10:10 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Andi Gutmans < andi @ zend . com > |
| Zeev Suraski < zeev @ zend . com > |
2001-07-10 02:51:29 +08:00
| Andrei Zmievski < andrei @ php . net > |
1999-04-08 02:10:10 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2003-02-01 09:49:15 +08:00
/* $Id$ */
1999-07-16 22:58:16 +08:00
1999-04-08 02:10:10 +08:00
# include "zend.h"
# include "zend_execute.h"
# include "zend_API.h"
2001-02-27 02:18:34 +08:00
# include "zend_modules.h"
1999-04-08 02:10:10 +08:00
# include "zend_constants.h"
2008-02-02 05:27:55 +08:00
# include "zend_exceptions.h"
2008-07-14 17:49:03 +08:00
# include "zend_closures.h"
1999-04-08 02:10:10 +08:00
1999-09-07 00:14:08 +08:00
# ifdef HAVE_STDARG_H
2000-06-06 10:47:43 +08:00
# include <stdarg.h>
1999-04-08 02:10:10 +08:00
# endif
/* these variables are true statics/globals, and have to be mutex'ed on every access */
static int module_count = 0 ;
2000-10-27 07:50:17 +08:00
ZEND_API HashTable module_registry ;
1999-04-08 02:10:10 +08:00
2010-07-06 19:40:17 +08:00
static zend_module_entry * * module_request_startup_handlers ;
static zend_module_entry * * module_request_shutdown_handlers ;
static zend_module_entry * * module_post_deactivate_handlers ;
static zend_class_entry * * class_cleanup_handlers ;
1999-04-08 02:10:10 +08:00
/* this function doesn't check for too many parameters */
2007-11-03 03:40:39 +08:00
ZEND_API int zend_get_parameters ( int ht , int param_count , . . . ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-04-21 11:49:09 +08:00
void * * p ;
int arg_count ;
1999-04-08 02:10:10 +08:00
va_list ptr ;
1999-04-13 02:29:09 +08:00
zval * * param , * param_ptr ;
2001-07-27 18:10:39 +08:00
TSRMLS_FETCH ( ) ;
1999-04-21 11:49:09 +08:00
2008-01-24 17:41:39 +08:00
p = zend_vm_stack_top ( TSRMLS_C ) - 1 ;
2007-04-16 16:09:56 +08:00
arg_count = ( int ) ( zend_uintptr_t ) * p ;
1999-04-13 02:29:09 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
1999-04-08 02:10:10 +08:00
va_start ( ptr , param_count ) ;
2000-06-10 09:08:55 +08:00
while ( param_count - - > 0 ) {
1999-04-08 02:10:10 +08:00
param = va_arg ( ptr , zval * * ) ;
2000-06-10 09:08:55 +08:00
param_ptr = * ( p - arg_count ) ;
2007-11-03 03:40:39 +08:00
if ( ! PZVAL_IS_REF ( param_ptr ) & & Z_REFCOUNT_P ( param_ptr ) > 1 ) {
1999-04-08 02:10:10 +08:00
zval * new_tmp ;
1999-12-27 05:21:33 +08:00
ALLOC_ZVAL ( new_tmp ) ;
1999-04-08 02:10:10 +08:00
* new_tmp = * param_ptr ;
zval_copy_ctor ( new_tmp ) ;
1999-07-10 04:43:59 +08:00
INIT_PZVAL ( new_tmp ) ;
1999-04-08 02:10:10 +08:00
param_ptr = new_tmp ;
2007-10-07 13:22:07 +08:00
Z_DELREF_P ( ( zval * ) * ( p - arg_count ) ) ;
2000-06-12 00:19:31 +08:00
* ( p - arg_count ) = param_ptr ;
1999-04-08 02:10:10 +08:00
}
* param = param_ptr ;
2000-06-10 09:08:55 +08:00
arg_count - - ;
1999-04-13 03:44:47 +08:00
}
1999-04-08 02:10:10 +08:00
va_end ( ptr ) ;
1999-04-13 02:29:09 +08:00
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int _zend_get_parameters_array ( int ht , int param_count , zval * * argument_array TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-04-21 11:49:09 +08:00
void * * p ;
int arg_count ;
1999-04-13 02:29:09 +08:00
zval * param_ptr ;
1999-04-08 02:10:10 +08:00
2008-01-24 17:41:39 +08:00
p = zend_vm_stack_top ( TSRMLS_C ) - 1 ;
2007-04-16 16:09:56 +08:00
arg_count = ( int ) ( zend_uintptr_t ) * p ;
1999-04-21 11:49:09 +08:00
1999-04-13 02:29:09 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
2000-06-10 09:08:55 +08:00
while ( param_count - - > 0 ) {
param_ptr = * ( p - arg_count ) ;
2007-11-03 03:40:39 +08:00
if ( ! PZVAL_IS_REF ( param_ptr ) & & Z_REFCOUNT_P ( param_ptr ) > 1 ) {
1999-04-08 02:10:10 +08:00
zval * new_tmp ;
1999-12-27 05:21:33 +08:00
ALLOC_ZVAL ( new_tmp ) ;
1999-04-08 02:10:10 +08:00
* new_tmp = * param_ptr ;
zval_copy_ctor ( new_tmp ) ;
1999-07-10 04:43:59 +08:00
INIT_PZVAL ( new_tmp ) ;
1999-04-08 02:10:10 +08:00
param_ptr = new_tmp ;
2007-10-07 13:22:07 +08:00
Z_DELREF_P ( ( zval * ) * ( p - arg_count ) ) ;
2000-06-10 09:08:55 +08:00
* ( p - arg_count ) = param_ptr ;
1999-04-08 02:10:10 +08:00
}
1999-04-13 02:29:09 +08:00
* ( argument_array + + ) = param_ptr ;
2000-06-10 09:08:55 +08:00
arg_count - - ;
1999-04-13 03:44:47 +08:00
}
1999-04-13 02:29:09 +08:00
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-15 03:53:33 +08:00
/* Zend-optimized Extended functions */
/* this function doesn't check for too many parameters */
2007-11-03 03:40:39 +08:00
ZEND_API int zend_get_parameters_ex ( int param_count , . . . ) /* { { { */
1999-04-15 03:53:33 +08:00
{
1999-04-21 11:49:09 +08:00
void * * p ;
int arg_count ;
1999-04-15 03:53:33 +08:00
va_list ptr ;
zval * * * param ;
2001-07-27 18:10:39 +08:00
TSRMLS_FETCH ( ) ;
1999-04-15 03:53:33 +08:00
2008-01-24 17:41:39 +08:00
p = zend_vm_stack_top ( TSRMLS_C ) - 1 ;
2007-04-16 16:09:56 +08:00
arg_count = ( int ) ( zend_uintptr_t ) * p ;
1999-04-21 11:49:09 +08:00
1999-04-15 03:53:33 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
va_start ( ptr , param_count ) ;
2000-06-10 09:08:55 +08:00
while ( param_count - - > 0 ) {
1999-04-15 03:53:33 +08:00
param = va_arg ( ptr , zval * * * ) ;
2000-06-10 09:08:55 +08:00
* param = ( zval * * ) p - ( arg_count - - ) ;
1999-04-15 03:53:33 +08:00
}
va_end ( ptr ) ;
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-15 03:53:33 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int _zend_get_parameters_array_ex ( int param_count , zval * * * argument_array TSRMLS_DC ) /* { { { */
1999-04-15 03:53:33 +08:00
{
1999-04-21 11:49:09 +08:00
void * * p ;
int arg_count ;
1999-04-15 03:53:33 +08:00
2008-01-24 17:41:39 +08:00
p = zend_vm_stack_top ( TSRMLS_C ) - 1 ;
2007-04-16 16:09:56 +08:00
arg_count = ( int ) ( zend_uintptr_t ) * p ;
1999-04-21 11:49:09 +08:00
1999-04-15 03:53:33 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
2000-06-10 09:08:55 +08:00
while ( param_count - - > 0 ) {
2005-04-29 15:59:04 +08:00
zval * * value = ( zval * * ) ( p - arg_count ) ;
* ( argument_array + + ) = value ;
arg_count - - ;
1999-04-15 03:53:33 +08:00
}
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-15 03:53:33 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int zend_copy_parameters_array ( int param_count , zval * argument_array TSRMLS_DC ) /* { { { */
2004-09-29 06:55:22 +08:00
{
void * * p ;
int arg_count ;
2008-01-24 17:41:39 +08:00
p = zend_vm_stack_top ( TSRMLS_C ) - 1 ;
2007-04-16 16:09:56 +08:00
arg_count = ( int ) ( zend_uintptr_t ) * p ;
2004-09-29 06:55:22 +08:00
if ( param_count > arg_count ) {
return FAILURE ;
}
while ( param_count - - > 0 ) {
zval * * param = ( zval * * ) p - ( arg_count - - ) ;
zval_add_ref ( param ) ;
2006-05-10 07:53:23 +08:00
add_next_index_zval ( argument_array , * param ) ;
2004-09-29 06:55:22 +08:00
}
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2004-09-29 06:55:22 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_wrong_param_count ( TSRMLS_D ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2011-09-13 21:29:35 +08:00
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
2007-11-03 03:40:39 +08:00
2005-06-17 19:25:31 +08:00
zend_error ( E_WARNING , " Wrong parameter count for %s%s%s() " , class_name , space , get_active_function_name ( TSRMLS_C ) ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
/* Argument parsing API -- andrei */
2007-11-03 03:40:39 +08:00
ZEND_API char * zend_get_type_by_const ( int type ) /* { { { */
2001-07-10 02:51:29 +08:00
{
2006-05-25 18:01:06 +08:00
switch ( type ) {
case IS_BOOL :
return " boolean " ;
2001-07-10 02:51:29 +08:00
case IS_LONG :
return " integer " ;
case IS_DOUBLE :
return " double " ;
case IS_STRING :
return " string " ;
case IS_OBJECT :
return " object " ;
case IS_RESOURCE :
return " resource " ;
2006-05-25 18:01:06 +08:00
case IS_NULL :
return " null " ;
2011-08-16 18:44:47 +08:00
case IS_CALLABLE :
return " callable " ;
2006-05-25 18:01:06 +08:00
case IS_ARRAY :
return " array " ;
2001-07-10 02:51:29 +08:00
default :
return " unknown " ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API char * zend_zval_type_name ( const zval * arg ) /* { { { */
2006-05-25 18:01:06 +08:00
{
return zend_get_type_by_const ( Z_TYPE_P ( arg ) ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2006-05-25 18:01:06 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API zend_class_entry * zend_get_class_entry ( const zval * zobject TSRMLS_DC ) /* { { { */
2002-04-22 22:22:27 +08:00
{
if ( Z_OBJ_HT_P ( zobject ) - > get_class_entry ) {
2002-04-30 17:56:48 +08:00
return Z_OBJ_HT_P ( zobject ) - > get_class_entry ( zobject TSRMLS_CC ) ;
2002-04-22 22:22:27 +08:00
} else {
2002-04-30 17:56:48 +08:00
zend_error ( E_ERROR , " Class entry requested for an object without PHP class " ) ;
return NULL ;
2002-04-22 22:22:27 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2002-04-22 22:22:27 +08:00
2005-06-29 16:43:38 +08:00
/* returns 1 if you need to copy result, 0 if it's already a copy */
2010-10-15 05:33:10 +08:00
ZEND_API int zend_get_object_classname ( const zval * object , const char * * class_name , zend_uint * class_name_len TSRMLS_DC ) /* { { { */
2005-06-28 02:13:13 +08:00
{
if ( Z_OBJ_HT_P ( object ) - > get_class_name = = NULL | |
Z_OBJ_HT_P ( object ) - > get_class_name ( object , class_name , class_name_len , 0 TSRMLS_CC ) ! = SUCCESS ) {
zend_class_entry * ce = Z_OBJCE_P ( object ) ;
2006-05-10 07:53:23 +08:00
2005-06-28 02:13:13 +08:00
* class_name = ce - > name ;
* class_name_len = ce - > name_length ;
return 1 ;
}
return 0 ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-06-28 02:13:13 +08:00
2007-11-03 03:40:39 +08:00
static int parse_arg_object_to_string ( zval * * arg , char * * p , int * pl , int type TSRMLS_DC ) /* { { { */
2006-05-13 18:37:45 +08:00
{
if ( Z_OBJ_HANDLER_PP ( arg , cast_object ) ) {
2012-03-02 10:51:57 +08:00
zval * obj ;
MAKE_STD_ZVAL ( obj ) ;
if ( Z_OBJ_HANDLER_P ( * arg , cast_object ) ( * arg , obj , type TSRMLS_CC ) = = SUCCESS ) {
zval_ptr_dtor ( arg ) ;
* arg = obj ;
2006-05-13 18:37:45 +08:00
* pl = Z_STRLEN_PP ( arg ) ;
* p = Z_STRVAL_PP ( arg ) ;
return SUCCESS ;
}
2012-03-02 10:51:57 +08:00
efree ( obj ) ;
2006-05-13 18:37:45 +08:00
}
/* Standard PHP objects */
if ( Z_OBJ_HT_PP ( arg ) = = & std_object_handlers | | ! Z_OBJ_HANDLER_PP ( arg , cast_object ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( arg ) ;
if ( zend_std_cast_object_tostring ( * arg , * arg , type TSRMLS_CC ) = = SUCCESS ) {
* pl = Z_STRLEN_PP ( arg ) ;
* p = Z_STRVAL_PP ( arg ) ;
return SUCCESS ;
}
}
if ( ! Z_OBJ_HANDLER_PP ( arg , cast_object ) & & Z_OBJ_HANDLER_PP ( arg , get ) ) {
int use_copy ;
zval * z = Z_OBJ_HANDLER_PP ( arg , get ) ( * arg TSRMLS_CC ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( z ) ;
2006-05-13 18:37:45 +08:00
if ( Z_TYPE_P ( z ) ! = IS_OBJECT ) {
zval_dtor ( * arg ) ;
Z_TYPE_P ( * arg ) = IS_NULL ;
zend_make_printable_zval ( z , * arg , & use_copy ) ;
if ( ! use_copy ) {
ZVAL_ZVAL ( * arg , z , 1 , 1 ) ;
}
* pl = Z_STRLEN_PP ( arg ) ;
* p = Z_STRVAL_PP ( arg ) ;
return SUCCESS ;
}
zval_ptr_dtor ( & z ) ;
}
return FAILURE ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2011-09-13 21:29:35 +08:00
static const char * zend_parse_arg_impl ( int arg_num , zval * * arg , va_list * va , const char * * spec , char * * error , int * severity TSRMLS_DC ) /* { { { */
2001-07-10 02:51:29 +08:00
{
2010-10-15 05:33:10 +08:00
const char * spec_walk = * spec ;
2001-07-10 02:51:29 +08:00
char c = * spec_walk + + ;
2008-11-26 06:15:22 +08:00
int return_null = 0 ;
2001-07-10 02:51:29 +08:00
2007-11-03 03:40:39 +08:00
/* scan through modifiers */
while ( 1 ) {
2001-07-10 02:51:29 +08:00
if ( * spec_walk = = ' / ' ) {
SEPARATE_ZVAL_IF_NOT_REF ( arg ) ;
2007-11-03 03:40:39 +08:00
} else if ( * spec_walk = = ' ! ' ) {
if ( Z_TYPE_PP ( arg ) = = IS_NULL ) {
return_null = 1 ;
}
} else {
break ;
2001-07-10 02:51:29 +08:00
}
spec_walk + + ;
}
switch ( c ) {
case ' l ' :
2009-06-05 02:20:45 +08:00
case ' L ' :
2001-07-10 02:51:29 +08:00
{
long * p = va_arg ( * va , long * ) ;
switch ( Z_TYPE_PP ( arg ) ) {
case IS_STRING :
{
double d ;
int type ;
2005-11-17 08:19:23 +08:00
if ( ( type = is_numeric_string ( Z_STRVAL_PP ( arg ) , Z_STRLEN_PP ( arg ) , p , & d , - 1 ) ) = = 0 ) {
2001-07-10 02:51:29 +08:00
return " long " ;
} else if ( type = = IS_DOUBLE ) {
2009-06-05 02:20:45 +08:00
if ( c = = ' L ' ) {
if ( d > LONG_MAX ) {
* p = LONG_MAX ;
break ;
} else if ( d < LONG_MIN ) {
* p = LONG_MIN ;
break ;
}
}
* p = zend_dval_to_lval ( d ) ;
2001-07-10 02:51:29 +08:00
}
}
break ;
2009-06-05 02:20:45 +08:00
case IS_DOUBLE :
if ( c = = ' L ' ) {
if ( Z_DVAL_PP ( arg ) > LONG_MAX ) {
* p = LONG_MAX ;
break ;
} else if ( Z_DVAL_PP ( arg ) < LONG_MIN ) {
* p = LONG_MIN ;
break ;
}
}
2001-07-10 02:51:29 +08:00
case IS_NULL :
case IS_LONG :
case IS_BOOL :
convert_to_long_ex ( arg ) ;
* p = Z_LVAL_PP ( arg ) ;
break ;
case IS_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
default :
return " long " ;
}
}
break ;
case ' d ' :
{
double * p = va_arg ( * va , double * ) ;
switch ( Z_TYPE_PP ( arg ) ) {
case IS_STRING :
{
long l ;
int type ;
2005-11-17 08:19:23 +08:00
if ( ( type = is_numeric_string ( Z_STRVAL_PP ( arg ) , Z_STRLEN_PP ( arg ) , & l , p , - 1 ) ) = = 0 ) {
2001-07-10 02:51:29 +08:00
return " double " ;
} else if ( type = = IS_LONG ) {
* p = ( double ) l ;
}
}
break ;
case IS_NULL :
case IS_LONG :
case IS_DOUBLE :
case IS_BOOL :
convert_to_double_ex ( arg ) ;
2001-08-26 23:14:45 +08:00
* p = Z_DVAL_PP ( arg ) ;
2001-07-10 02:51:29 +08:00
break ;
case IS_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
default :
return " double " ;
}
}
break ;
2011-06-07 05:28:16 +08:00
case ' p ' :
2001-07-10 02:51:29 +08:00
case ' s ' :
{
char * * p = va_arg ( * va , char * * ) ;
int * pl = va_arg ( * va , int * ) ;
switch ( Z_TYPE_PP ( arg ) ) {
case IS_NULL :
if ( return_null ) {
* p = NULL ;
* pl = 0 ;
break ;
}
/* break omitted intentionally */
case IS_STRING :
case IS_LONG :
case IS_DOUBLE :
case IS_BOOL :
convert_to_string_ex ( arg ) ;
2010-05-11 18:41:19 +08:00
if ( UNEXPECTED ( Z_ISREF_PP ( arg ) ! = 0 ) ) {
/* it's dangerous to return pointers to string
buffer of referenced variable , because it can
be clobbered throug magic callbacks */
SEPARATE_ZVAL ( arg ) ;
}
2001-07-10 02:51:29 +08:00
* p = Z_STRVAL_PP ( arg ) ;
* pl = Z_STRLEN_PP ( arg ) ;
2011-06-07 05:28:16 +08:00
if ( c = = ' p ' & & CHECK_ZVAL_NULL_PATH ( * arg ) ) {
2011-06-08 08:53:55 +08:00
return " a valid path " ;
2011-06-07 05:28:16 +08:00
}
2001-07-10 02:51:29 +08:00
break ;
2006-05-10 07:53:23 +08:00
2006-05-13 18:37:45 +08:00
case IS_OBJECT :
if ( parse_arg_object_to_string ( arg , p , pl , IS_STRING TSRMLS_CC ) = = SUCCESS ) {
2011-06-07 05:28:16 +08:00
if ( c = = ' p ' & & CHECK_ZVAL_NULL_PATH ( * arg ) ) {
2011-06-08 08:53:55 +08:00
return " a valid path " ;
2011-06-07 05:28:16 +08:00
}
2006-05-13 18:37:45 +08:00
break ;
2006-05-12 08:21:00 +08:00
}
2006-05-10 07:53:23 +08:00
2001-07-10 02:51:29 +08:00
case IS_ARRAY :
case IS_RESOURCE :
default :
2011-06-09 08:23:43 +08:00
return c = = ' s ' ? " string " : " a valid path " ;
2001-07-10 02:51:29 +08:00
}
}
break ;
case ' b ' :
{
zend_bool * p = va_arg ( * va , zend_bool * ) ;
switch ( Z_TYPE_PP ( arg ) ) {
case IS_NULL :
case IS_STRING :
case IS_LONG :
case IS_DOUBLE :
case IS_BOOL :
convert_to_boolean_ex ( arg ) ;
* p = Z_BVAL_PP ( arg ) ;
break ;
case IS_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
default :
return " boolean " ;
}
}
break ;
case ' r ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
2007-11-03 03:40:39 +08:00
if ( return_null ) {
* p = NULL ;
break ;
}
if ( Z_TYPE_PP ( arg ) = = IS_RESOURCE ) {
2001-07-10 02:51:29 +08:00
* p = * arg ;
2007-11-03 03:40:39 +08:00
} else {
return " resource " ;
2006-05-10 07:53:23 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
2008-11-25 02:10:36 +08:00
case ' A ' :
2001-07-10 02:51:29 +08:00
case ' a ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
2007-11-03 03:40:39 +08:00
if ( return_null ) {
* p = NULL ;
break ;
}
2008-11-26 06:15:22 +08:00
if ( Z_TYPE_PP ( arg ) = = IS_ARRAY | | ( c = = ' A ' & & Z_TYPE_PP ( arg ) = = IS_OBJECT ) ) {
2001-07-10 02:51:29 +08:00
* p = * arg ;
2007-11-03 03:40:39 +08:00
} else {
return " array " ;
2006-05-10 07:53:23 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
2008-11-25 02:10:36 +08:00
case ' H ' :
2006-01-26 06:03:18 +08:00
case ' h ' :
{
HashTable * * p = va_arg ( * va , HashTable * * ) ;
2007-11-03 03:40:39 +08:00
if ( return_null ) {
* p = NULL ;
break ;
}
if ( Z_TYPE_PP ( arg ) = = IS_ARRAY ) {
2006-01-26 06:03:18 +08:00
* p = Z_ARRVAL_PP ( arg ) ;
2008-11-26 06:15:22 +08:00
} else if ( c = = ' H ' & & Z_TYPE_PP ( arg ) = = IS_OBJECT ) {
2008-11-25 02:10:36 +08:00
* p = HASH_OF ( * arg ) ;
if ( * p = = NULL ) {
return " array " ;
}
2007-11-03 03:40:39 +08:00
} else {
return " array " ;
2006-01-26 06:03:18 +08:00
}
}
break ;
2001-07-10 02:51:29 +08:00
case ' o ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
2007-11-03 03:40:39 +08:00
if ( return_null ) {
* p = NULL ;
break ;
}
if ( Z_TYPE_PP ( arg ) = = IS_OBJECT ) {
2001-07-10 02:51:29 +08:00
* p = * arg ;
2007-11-03 03:40:39 +08:00
} else {
return " object " ;
2006-05-10 07:53:23 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
case ' O ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
zend_class_entry * ce = va_arg ( * va , zend_class_entry * ) ;
2003-08-02 01:51:56 +08:00
2007-11-03 03:40:39 +08:00
if ( return_null ) {
* p = NULL ;
break ;
}
2003-08-02 01:51:56 +08:00
if ( Z_TYPE_PP ( arg ) = = IS_OBJECT & &
2003-08-21 22:39:17 +08:00
( ! ce | | instanceof_function ( Z_OBJCE_PP ( arg ) , ce TSRMLS_CC ) ) ) {
2003-08-02 01:51:56 +08:00
* p = * arg ;
} else {
2007-11-03 03:40:39 +08:00
if ( ce ) {
2006-05-28 03:06:06 +08:00
return ce - > name ;
2001-07-10 02:51:29 +08:00
} else {
2006-05-28 03:06:06 +08:00
return " object " ;
2001-07-10 02:51:29 +08:00
}
2003-08-02 01:51:56 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
2006-02-28 06:23:21 +08:00
case ' C ' :
{
zend_class_entry * * lookup , * * pce = va_arg ( * va , zend_class_entry * * ) ;
zend_class_entry * ce_base = * pce ;
2007-11-03 03:40:39 +08:00
if ( return_null ) {
2006-05-24 06:22:11 +08:00
* pce = NULL ;
break ;
}
2006-02-28 06:23:21 +08:00
convert_to_string_ex ( arg ) ;
if ( zend_lookup_class ( Z_STRVAL_PP ( arg ) , Z_STRLEN_PP ( arg ) , & lookup TSRMLS_CC ) = = FAILURE ) {
* pce = NULL ;
} else {
* pce = * lookup ;
}
if ( ce_base ) {
2007-11-03 03:40:39 +08:00
if ( ( ! * pce | | ! instanceof_function ( * pce , ce_base TSRMLS_CC ) ) ) {
2008-02-02 05:27:55 +08:00
zend_spprintf ( error , 0 , " to be a class name derived from %s, '%s' given " ,
ce_base - > name , Z_STRVAL_PP ( arg ) ) ;
2006-02-28 06:23:21 +08:00
* pce = NULL ;
return " " ;
}
}
2006-05-24 06:22:11 +08:00
if ( ! * pce ) {
2008-02-02 05:27:55 +08:00
zend_spprintf ( error , 0 , " to be a valid class name, '%s' given " ,
Z_STRVAL_PP ( arg ) ) ;
2006-02-28 06:23:21 +08:00
return " " ;
}
break ;
}
break ;
2006-06-07 17:43:54 +08:00
case ' f ' :
{
2007-11-03 03:40:39 +08:00
zend_fcall_info * fci = va_arg ( * va , zend_fcall_info * ) ;
2006-06-07 17:43:54 +08:00
zend_fcall_info_cache * fcc = va_arg ( * va , zend_fcall_info_cache * ) ;
2008-02-02 05:27:55 +08:00
char * is_callable_error = NULL ;
2006-06-07 17:43:54 +08:00
2007-11-03 03:40:39 +08:00
if ( return_null ) {
2006-06-07 17:43:54 +08:00
fci - > size = 0 ;
fcc - > initialized = 0 ;
break ;
2007-11-03 03:40:39 +08:00
}
2008-02-02 05:27:55 +08:00
if ( zend_fcall_info_init ( * arg , 0 , fci , fcc , NULL , & is_callable_error TSRMLS_CC ) = = SUCCESS ) {
if ( is_callable_error ) {
* severity = E_STRICT ;
zend_spprintf ( error , 0 , " to be a valid callback, %s " , is_callable_error ) ;
efree ( is_callable_error ) ;
2008-02-02 23:18:30 +08:00
* spec = spec_walk ;
2008-02-02 05:27:55 +08:00
return " " ;
}
2007-11-03 03:40:39 +08:00
break ;
2006-06-07 17:43:54 +08:00
} else {
2008-02-02 05:27:55 +08:00
if ( is_callable_error ) {
* severity = E_WARNING ;
zend_spprintf ( error , 0 , " to be a valid callback, %s " , is_callable_error ) ;
efree ( is_callable_error ) ;
return " " ;
} else {
return " valid callback " ;
}
2006-06-07 17:43:54 +08:00
}
}
2001-07-10 02:51:29 +08:00
case ' z ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
2007-11-03 03:40:39 +08:00
if ( return_null ) {
2001-07-10 02:51:29 +08:00
* p = NULL ;
} else {
* p = * arg ;
}
}
break ;
2007-11-03 03:40:39 +08:00
2003-07-12 22:54:53 +08:00
case ' Z ' :
{
zval * * * p = va_arg ( * va , zval * * * ) ;
2007-11-03 03:40:39 +08:00
if ( return_null ) {
2003-07-12 22:54:53 +08:00
* p = NULL ;
} else {
* p = arg ;
}
2003-07-11 18:21:39 +08:00
}
break ;
2007-11-03 03:40:39 +08:00
2001-07-10 02:51:29 +08:00
default :
return " unknown " ;
}
* spec = spec_walk ;
return NULL ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2010-10-15 05:33:10 +08:00
static int zend_parse_arg ( int arg_num , zval * * arg , va_list * va , const char * * spec , int quiet TSRMLS_DC ) /* { { { */
2001-07-10 02:51:29 +08:00
{
2011-09-13 21:29:35 +08:00
const char * expected_type = NULL ;
char * error = NULL ;
2008-02-02 05:27:55 +08:00
int severity = E_WARNING ;
2001-07-10 02:51:29 +08:00
2008-02-02 05:27:55 +08:00
expected_type = zend_parse_arg_impl ( arg_num , arg , va , spec , & error , & severity TSRMLS_CC ) ;
2001-07-10 02:51:29 +08:00
if ( expected_type ) {
2008-02-02 05:27:55 +08:00
if ( ! quiet & & ( * expected_type | | error ) ) {
2011-09-13 21:29:35 +08:00
const char * space ;
const char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
2005-06-17 19:25:31 +08:00
2008-02-02 05:27:55 +08:00
if ( error ) {
zend_error ( severity , " %s%s%s() expects parameter %d %s " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , arg_num , error ) ;
efree ( error ) ;
} else {
zend_error ( severity , " %s%s%s() expects parameter %d to be %s, %s given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , arg_num , expected_type ,
zend_zval_type_name ( * arg ) ) ;
}
}
if ( severity ! = E_STRICT ) {
return FAILURE ;
2001-07-10 02:51:29 +08:00
}
}
2006-05-10 07:53:23 +08:00
2001-07-10 02:51:29 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2010-10-15 05:33:10 +08:00
static int zend_parse_va_args ( int num_args , const char * type_spec , va_list * va , int flags TSRMLS_DC ) /* { { { */
2001-07-10 02:51:29 +08:00
{
2010-10-15 05:33:10 +08:00
const char * spec_walk ;
2001-07-10 02:51:29 +08:00
int c , i ;
int min_num_args = - 1 ;
int max_num_args = 0 ;
2007-10-30 01:09:57 +08:00
int post_varargs = 0 ;
2001-07-10 02:51:29 +08:00
zval * * arg ;
int arg_count ;
int quiet = flags & ZEND_PARSE_PARAMS_QUIET ;
2007-10-30 01:09:57 +08:00
zend_bool have_varargs = 0 ;
2007-11-03 03:40:39 +08:00
zval * * * * varargs = NULL ;
int * n_varargs = NULL ;
2001-07-10 02:51:29 +08:00
for ( spec_walk = type_spec ; * spec_walk ; spec_walk + + ) {
c = * spec_walk ;
switch ( c ) {
case ' l ' : case ' d ' :
case ' s ' : case ' b ' :
case ' r ' : case ' a ' :
case ' o ' : case ' O ' :
2003-07-12 22:54:53 +08:00
case ' z ' : case ' Z ' :
2006-02-28 06:23:21 +08:00
case ' C ' : case ' h ' :
2008-11-25 02:10:36 +08:00
case ' f ' : case ' A ' :
2011-06-07 05:28:16 +08:00
case ' H ' : case ' p ' :
2001-07-10 02:51:29 +08:00
max_num_args + + ;
break ;
case ' | ' :
min_num_args = max_num_args ;
break ;
case ' / ' :
case ' ! ' :
/* Pass */
break ;
2007-10-30 01:09:57 +08:00
case ' * ' :
case ' + ' :
if ( have_varargs ) {
if ( ! quiet ) {
2007-11-20 17:51:12 +08:00
zend_function * active_function = EG ( current_execute_data ) - > function_state . function ;
2011-09-13 21:29:35 +08:00
const char * class_name = active_function - > common . scope ? active_function - > common . scope - > name : " " ;
2007-10-30 01:09:57 +08:00
zend_error ( E_WARNING , " %s%s%s(): only one varargs specifier (* or +) is permitted " ,
class_name ,
class_name [ 0 ] ? " :: " : " " ,
2010-05-15 07:48:03 +08:00
active_function - > common . function_name ) ;
2007-10-30 01:09:57 +08:00
}
return FAILURE ;
}
have_varargs = 1 ;
/* we expect at least one parameter in varargs */
if ( c = = ' + ' ) {
max_num_args + + ;
}
/* mark the beginning of varargs */
post_varargs = max_num_args ;
break ;
2001-07-10 02:51:29 +08:00
default :
if ( ! quiet ) {
2007-11-20 17:51:12 +08:00
zend_function * active_function = EG ( current_execute_data ) - > function_state . function ;
2011-09-13 21:29:35 +08:00
const char * class_name = active_function - > common . scope ? active_function - > common . scope - > name : " " ;
2007-11-03 03:40:39 +08:00
zend_error ( E_WARNING , " %s%s%s(): bad type specifier while parsing parameters " ,
2003-08-13 15:02:44 +08:00
class_name ,
class_name [ 0 ] ? " :: " : " " ,
2010-05-15 07:48:03 +08:00
active_function - > common . function_name ) ;
2001-07-10 02:51:29 +08:00
}
return FAILURE ;
}
}
if ( min_num_args < 0 ) {
min_num_args = max_num_args ;
}
2007-10-30 01:09:57 +08:00
if ( have_varargs ) {
/* calculate how many required args are at the end of the specifier list */
post_varargs = max_num_args - post_varargs ;
max_num_args = - 1 ;
}
if ( num_args < min_num_args | | ( num_args > max_num_args & & max_num_args > 0 ) ) {
2001-07-10 02:51:29 +08:00
if ( ! quiet ) {
2007-11-20 17:51:12 +08:00
zend_function * active_function = EG ( current_execute_data ) - > function_state . function ;
2011-09-13 21:29:35 +08:00
const char * class_name = active_function - > common . scope ? active_function - > common . scope - > name : " " ;
2003-08-13 15:02:44 +08:00
zend_error ( E_WARNING , " %s%s%s() expects %s %d parameter%s, %d given " ,
class_name ,
class_name [ 0 ] ? " :: " : " " ,
2010-05-15 07:48:03 +08:00
active_function - > common . function_name ,
2001-07-10 02:51:29 +08:00
min_num_args = = max_num_args ? " exactly " : num_args < min_num_args ? " at least " : " at most " ,
num_args < min_num_args ? min_num_args : max_num_args ,
( num_args < min_num_args ? min_num_args : max_num_args ) = = 1 ? " " : " s " ,
num_args ) ;
}
return FAILURE ;
}
2008-01-24 17:41:39 +08:00
arg_count = ( int ) ( zend_uintptr_t ) * ( zend_vm_stack_top ( TSRMLS_C ) - 1 ) ;
2001-07-10 02:51:29 +08:00
if ( num_args > arg_count ) {
2001-10-20 21:55:47 +08:00
zend_error ( E_WARNING , " %s(): could not obtain parameters for parsing " ,
2006-05-28 03:06:06 +08:00
get_active_function_name ( TSRMLS_C ) ) ;
2001-07-10 02:51:29 +08:00
return FAILURE ;
}
i = 0 ;
while ( num_args - - > 0 ) {
if ( * type_spec = = ' | ' ) {
type_spec + + ;
}
2007-10-30 01:09:57 +08:00
if ( * type_spec = = ' * ' | | * type_spec = = ' + ' ) {
int num_varargs = num_args + 1 - post_varargs ;
/* eat up the passed in storage even if it won't be filled in with varargs */
2007-11-03 03:40:39 +08:00
varargs = va_arg ( * va , zval * * * * ) ;
n_varargs = va_arg ( * va , int * ) ;
2007-10-30 01:09:57 +08:00
type_spec + + ;
if ( num_varargs > 0 ) {
int iv = 0 ;
2008-01-24 17:41:39 +08:00
zval * * p = ( zval * * ) ( zend_vm_stack_top ( TSRMLS_C ) - 1 - ( arg_count - i ) ) ;
2007-10-30 01:09:57 +08:00
* n_varargs = num_varargs ;
/* allocate space for array and store args */
* varargs = safe_emalloc ( num_varargs , sizeof ( zval * * ) , 0 ) ;
while ( num_varargs - - > 0 ) {
( * varargs ) [ iv + + ] = p + + ;
}
/* adjust how many args we have left and restart loop */
num_args = num_args + 1 - iv ;
i + = iv ;
continue ;
} else {
* varargs = NULL ;
* n_varargs = 0 ;
}
}
2008-01-24 17:41:39 +08:00
arg = ( zval * * ) ( zend_vm_stack_top ( TSRMLS_C ) - 1 - ( arg_count - i ) ) ;
2007-10-30 01:09:57 +08:00
2001-07-30 15:43:02 +08:00
if ( zend_parse_arg ( i + 1 , arg , va , & type_spec , quiet TSRMLS_CC ) = = FAILURE ) {
2007-11-03 03:40:39 +08:00
/* clean up varargs array if it was used */
if ( varargs & & * varargs ) {
efree ( * varargs ) ;
* varargs = NULL ;
}
2001-07-10 02:51:29 +08:00
return FAILURE ;
}
i + + ;
}
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2007-11-03 03:40:39 +08:00
# define RETURN_IF_ZERO_ARGS(num_args, type_spec, quiet) { \
2007-10-30 18:17:41 +08:00
int __num_args = ( num_args ) ; \
2007-11-03 03:40:39 +08:00
\
2007-10-30 18:17:41 +08:00
if ( 0 = = ( type_spec ) [ 0 ] & & 0 ! = __num_args & & ! ( quiet ) ) { \
2011-09-13 21:29:35 +08:00
const char * __space ; \
const char * __class_name = get_active_class_name ( & __space TSRMLS_CC ) ; \
2007-10-30 18:17:41 +08:00
zend_error ( E_WARNING , " %s%s%s() expects exactly 0 parameters, %d given " , \
2007-11-03 03:40:39 +08:00
__class_name , __space , \
get_active_function_name ( TSRMLS_C ) , __num_args ) ; \
2007-10-30 18:17:41 +08:00
return FAILURE ; \
} \
}
2010-10-15 05:33:10 +08:00
ZEND_API int zend_parse_parameters_ex ( int flags , int num_args TSRMLS_DC , const char * type_spec , . . . ) /* { { { */
2001-07-10 02:51:29 +08:00
{
va_list va ;
int retval ;
2006-05-10 07:53:23 +08:00
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , type_spec , flags & ZEND_PARSE_PARAMS_QUIET ) ;
2001-07-10 02:51:29 +08:00
va_start ( va , type_spec ) ;
2001-07-30 12:54:16 +08:00
retval = zend_parse_va_args ( num_args , type_spec , & va , flags TSRMLS_CC ) ;
2001-07-10 02:51:29 +08:00
va_end ( va ) ;
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2010-10-15 05:33:10 +08:00
ZEND_API int zend_parse_parameters ( int num_args TSRMLS_DC , const char * type_spec , . . . ) /* { { { */
2001-07-10 02:51:29 +08:00
{
va_list va ;
int retval ;
2006-05-10 07:53:23 +08:00
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , type_spec , 0 ) ;
2001-07-10 02:51:29 +08:00
va_start ( va , type_spec ) ;
2001-07-30 12:54:16 +08:00
retval = zend_parse_va_args ( num_args , type_spec , & va , 0 TSRMLS_CC ) ;
2001-07-10 02:51:29 +08:00
va_end ( va ) ;
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-07-10 02:51:29 +08:00
2010-10-15 05:33:10 +08:00
ZEND_API int zend_parse_method_parameters ( int num_args TSRMLS_DC , zval * this_ptr , const char * type_spec , . . . ) /* { { { */
2003-02-03 07:30:14 +08:00
{
va_list va ;
int retval ;
2010-10-15 05:33:10 +08:00
const char * p = type_spec ;
2003-02-09 04:54:02 +08:00
zval * * object ;
zend_class_entry * ce ;
2003-02-03 07:30:14 +08:00
2003-02-09 04:54:02 +08:00
if ( ! this_ptr ) {
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , p , 0 ) ;
2003-02-09 04:54:02 +08:00
va_start ( va , type_spec ) ;
retval = zend_parse_va_args ( num_args , type_spec , & va , 0 TSRMLS_CC ) ;
va_end ( va ) ;
2003-08-01 00:30:15 +08:00
} else {
2003-02-09 04:54:02 +08:00
p + + ;
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , p , 0 ) ;
2003-02-09 04:54:02 +08:00
va_start ( va , type_spec ) ;
2003-02-03 07:30:14 +08:00
2003-02-09 04:54:02 +08:00
object = va_arg ( va , zval * * ) ;
ce = va_arg ( va , zend_class_entry * ) ;
* object = this_ptr ;
2008-08-13 01:20:25 +08:00
2003-08-21 22:39:17 +08:00
if ( ce & & ! instanceof_function ( Z_OBJCE_P ( this_ptr ) , ce TSRMLS_CC ) ) {
zend_error ( E_CORE_ERROR , " %s::%s() must be derived from %s::%s " ,
ce - > name , get_active_function_name ( TSRMLS_C ) , Z_OBJCE_P ( this_ptr ) - > name , get_active_function_name ( TSRMLS_C ) ) ;
}
2003-02-03 07:30:14 +08:00
2003-02-09 04:54:02 +08:00
retval = zend_parse_va_args ( num_args , p , & va , 0 TSRMLS_CC ) ;
va_end ( va ) ;
}
2003-02-03 07:30:14 +08:00
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-02-03 07:30:14 +08:00
2010-10-15 05:33:10 +08:00
ZEND_API int zend_parse_method_parameters_ex ( int flags , int num_args TSRMLS_DC , zval * this_ptr , const char * type_spec , . . . ) /* { { { */
2003-02-03 07:30:14 +08:00
{
va_list va ;
int retval ;
2010-10-15 05:33:10 +08:00
const char * p = type_spec ;
2004-03-03 00:17:58 +08:00
zval * * object ;
zend_class_entry * ce ;
2003-02-03 07:30:14 +08:00
int quiet = flags & ZEND_PARSE_PARAMS_QUIET ;
2004-03-03 00:17:58 +08:00
if ( ! this_ptr ) {
2007-10-30 18:17:41 +08:00
RETURN_IF_ZERO_ARGS ( num_args , p , quiet ) ;
2004-03-03 00:17:58 +08:00
va_start ( va , type_spec ) ;
2009-12-24 08:15:13 +08:00
retval = zend_parse_va_args ( num_args , type_spec , & va , flags TSRMLS_CC ) ;
2004-03-03 00:17:58 +08:00
va_end ( va ) ;
} else {
p + + ;
2011-01-13 06:17:10 +08:00
RETURN_IF_ZERO_ARGS ( num_args , p , quiet ) ;
2007-10-30 18:17:41 +08:00
2004-03-03 00:17:58 +08:00
va_start ( va , type_spec ) ;
2003-02-03 07:30:14 +08:00
2004-03-03 00:17:58 +08:00
object = va_arg ( va , zval * * ) ;
ce = va_arg ( va , zend_class_entry * ) ;
* object = this_ptr ;
2008-08-13 01:20:25 +08:00
2004-03-03 00:17:58 +08:00
if ( ce & & ! instanceof_function ( Z_OBJCE_P ( this_ptr ) , ce TSRMLS_CC ) ) {
2003-02-03 07:30:14 +08:00
if ( ! quiet ) {
2004-03-03 00:17:58 +08:00
zend_error ( E_CORE_ERROR , " %s::%s() must be derived from %s::%s " ,
ce - > name , get_active_function_name ( TSRMLS_C ) , Z_OBJCE_P ( this_ptr ) - > name , get_active_function_name ( TSRMLS_C ) ) ;
2003-02-03 07:30:14 +08:00
}
2011-08-06 06:26:16 +08:00
va_end ( va ) ;
2003-02-03 07:30:14 +08:00
return FAILURE ;
}
2004-03-03 00:17:58 +08:00
retval = zend_parse_va_args ( num_args , p , & va , flags TSRMLS_CC ) ;
va_end ( va ) ;
}
2003-02-03 07:30:14 +08:00
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2004-03-03 00:17:58 +08:00
2001-07-10 02:51:29 +08:00
/* Argument parsing API -- andrei */
2008-05-27 18:29:33 +08:00
ZEND_API int _array_init ( zval * arg , uint size ZEND_FILE_LINE_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2007-11-03 03:40:39 +08:00
ALLOC_HASHTABLE_REL ( Z_ARRVAL_P ( arg ) ) ;
1999-12-28 03:07:33 +08:00
2008-05-27 18:29:33 +08:00
_zend_hash_init ( Z_ARRVAL_P ( arg ) , size , NULL , ZVAL_PTR_DTOR , 0 ZEND_FILE_LINE_RELAY_CC ) ;
2007-11-03 03:40:39 +08:00
Z_TYPE_P ( arg ) = IS_ARRAY ;
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2008-08-13 01:20:25 +08:00
static int zend_merge_property ( zval * * value TSRMLS_DC , int num_args , va_list args , const zend_hash_key * hash_key ) /* { { { */
2003-08-30 07:27:22 +08:00
{
/* which name should a numeric property have ? */
if ( hash_key - > nKeyLength ) {
zval * obj = va_arg ( args , zval * ) ;
zend_object_handlers * obj_ht = va_arg ( args , zend_object_handlers * ) ;
2005-11-23 19:15:11 +08:00
zval * member ;
2003-08-30 07:27:22 +08:00
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( member ) ;
ZVAL_STRINGL ( member , hash_key - > arKey , hash_key - > nKeyLength - 1 , 1 ) ;
2010-04-20 18:57:45 +08:00
obj_ht - > write_property ( obj , member , * value , 0 TSRMLS_CC ) ;
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & member ) ;
2003-08-30 07:27:22 +08:00
}
return ZEND_HASH_APPLY_KEEP ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-30 07:27:22 +08:00
2006-05-10 07:53:23 +08:00
/* This function should be called after the constructor has been called
2003-08-30 07:27:22 +08:00
* because it may call __set from the uninitialized object otherwise . */
2007-11-03 03:40:39 +08:00
ZEND_API void zend_merge_properties ( zval * obj , HashTable * properties , int destroy_ht TSRMLS_DC ) /* { { { */
2003-08-30 07:27:22 +08:00
{
2011-09-13 21:29:35 +08:00
const zend_object_handlers * obj_ht = Z_OBJ_HT_P ( obj ) ;
2003-08-30 07:27:22 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
EG ( scope ) = Z_OBJCE_P ( obj ) ;
2008-07-25 03:52:24 +08:00
zend_hash_apply_with_arguments ( properties TSRMLS_CC , ( apply_func_args_t ) zend_merge_property , 2 , obj , obj_ht ) ;
2003-08-30 07:27:22 +08:00
EG ( scope ) = old_scope ;
if ( destroy_ht ) {
zend_hash_destroy ( properties ) ;
FREE_HASHTABLE ( properties ) ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-30 07:27:22 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_update_class_constants ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2005-01-22 20:23:01 +08:00
{
2010-09-15 15:38:52 +08:00
if ( ( class_type - > ce_flags & ZEND_ACC_CONSTANTS_UPDATED ) = = 0 | | ( ! CE_STATIC_MEMBERS ( class_type ) & & class_type - > default_static_members_count ) ) {
2005-04-26 17:27:28 +08:00
zend_class_entry * * scope = EG ( in_execution ) ? & EG ( scope ) : & CG ( active_class_entry ) ;
zend_class_entry * old_scope = * scope ;
2010-05-24 22:11:39 +08:00
int i ;
2005-04-26 17:27:28 +08:00
* scope = class_type ;
2006-03-02 01:21:04 +08:00
zend_hash_apply_with_argument ( & class_type - > constants_table , ( apply_func_arg_t ) zval_update_constant , ( void * ) 1 TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
2010-05-24 22:11:39 +08:00
for ( i = 0 ; i < class_type - > default_properties_count ; i + + ) {
if ( class_type - > default_properties_table [ i ] ) {
zval_update_constant ( & class_type - > default_properties_table [ i ] , ( void * * ) 1 TSRMLS_CC ) ;
}
}
if ( ! CE_STATIC_MEMBERS ( class_type ) & & class_type - > default_static_members_count ) {
2005-09-01 18:05:32 +08:00
zval * * p ;
if ( class_type - > parent ) {
zend_update_class_constants ( class_type - > parent TSRMLS_CC ) ;
}
2005-12-01 19:48:17 +08:00
# if ZTS
2010-05-25 01:07:52 +08:00
CG ( static_members_table ) [ ( zend_intptr_t ) ( class_type - > static_members_table ) ] = emalloc ( sizeof ( zval * ) * class_type - > default_static_members_count ) ;
2005-12-01 19:48:17 +08:00
# else
2010-05-24 22:11:39 +08:00
class_type - > static_members_table = emalloc ( sizeof ( zval * ) * class_type - > default_static_members_count ) ;
2005-12-01 19:48:17 +08:00
# endif
2010-05-24 22:11:39 +08:00
for ( i = 0 ; i < class_type - > default_static_members_count ; i + + ) {
p = & class_type - > default_static_members_table [ i ] ;
2007-10-07 13:22:07 +08:00
if ( Z_ISREF_PP ( p ) & &
2007-11-03 03:40:39 +08:00
class_type - > parent & &
2010-08-11 16:34:54 +08:00
i < class_type - > parent - > default_static_members_count & &
* p = = class_type - > parent - > default_static_members_table [ i ] & &
CE_STATIC_MEMBERS ( class_type - > parent ) [ i ]
2007-11-03 03:40:39 +08:00
) {
2010-08-11 16:34:54 +08:00
zval * q = CE_STATIC_MEMBERS ( class_type - > parent ) [ i ] ;
Z_ADDREF_P ( q ) ;
Z_SET_ISREF_P ( q ) ;
CE_STATIC_MEMBERS ( class_type ) [ i ] = q ;
2005-09-01 18:05:32 +08:00
} else {
2009-09-06 03:00:05 +08:00
zval * r ;
2006-05-10 07:53:23 +08:00
2009-09-06 03:00:05 +08:00
ALLOC_ZVAL ( r ) ;
* r = * * p ;
INIT_PZVAL ( r ) ;
zval_copy_ctor ( r ) ;
2010-05-26 23:42:59 +08:00
CE_STATIC_MEMBERS ( class_type ) [ i ] = r ;
2005-09-01 18:05:32 +08:00
}
}
}
2010-05-24 22:11:39 +08:00
for ( i = 0 ; i < class_type - > default_static_members_count ; i + + ) {
zval_update_constant ( & CE_STATIC_MEMBERS ( class_type ) [ i ] , ( void * * ) 1 TSRMLS_CC ) ;
}
2005-09-01 18:05:32 +08:00
2005-04-26 17:27:28 +08:00
* scope = old_scope ;
2010-09-15 15:38:52 +08:00
class_type - > ce_flags | = ZEND_ACC_CONSTANTS_UPDATED ;
2005-01-22 20:23:01 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-01-22 20:23:01 +08:00
2010-05-24 22:11:39 +08:00
ZEND_API void object_properties_init ( zend_object * object , zend_class_entry * class_type ) /* { { { */
{
int i ;
if ( class_type - > default_properties_count ) {
object - > properties_table = emalloc ( sizeof ( zval * ) * class_type - > default_properties_count ) ;
for ( i = 0 ; i < class_type - > default_properties_count ; i + + ) {
object - > properties_table [ i ] = class_type - > default_properties_table [ i ] ;
if ( class_type - > default_properties_table [ i ] ) {
Z_ADDREF_P ( object - > properties_table [ i ] ) ;
}
}
object - > properties = NULL ;
}
}
/* }}} */
2003-08-30 07:27:22 +08:00
/* This function requires 'properties' to contain all props declared in the
2006-05-10 07:53:23 +08:00
* class and all props being public . If only a subset is given or the class
2003-08-30 07:27:22 +08:00
* has protected members then you need to merge the properties seperately by
* calling zend_merge_properties ( ) . */
2007-11-03 03:40:39 +08:00
ZEND_API int _object_and_properties_init ( zval * arg , zend_class_entry * class_type , HashTable * properties ZEND_FILE_LINE_DC TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2001-08-07 11:17:33 +08:00
zend_object * object ;
1999-04-08 02:10:10 +08:00
2004-06-05 22:59:21 +08:00
if ( class_type - > ce_flags & ( ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ) ) {
2011-11-01 06:59:00 +08:00
char * what = ( class_type - > ce_flags & ZEND_ACC_INTERFACE ) ? " interface "
: ( ( class_type - > ce_flags & ZEND_ACC_TRAIT ) = = ZEND_ACC_TRAIT ) ? " trait "
: " abstract class " ;
2004-06-05 22:59:21 +08:00
zend_error ( E_ERROR , " Cannot instantiate %s %s " , what , class_type - > name ) ;
}
2005-01-22 20:23:01 +08:00
zend_update_class_constants ( class_type TSRMLS_CC ) ;
2006-05-10 07:53:23 +08:00
Z_TYPE_P ( arg ) = IS_OBJECT ;
2002-09-15 15:45:26 +08:00
if ( class_type - > create_object = = NULL ) {
2006-05-10 07:53:23 +08:00
Z_OBJVAL_P ( arg ) = zend_objects_new ( & object , class_type TSRMLS_CC ) ;
2002-02-07 22:08:43 +08:00
if ( properties ) {
object - > properties = properties ;
2010-05-24 22:11:39 +08:00
object - > properties_table = NULL ;
2002-02-07 22:08:43 +08:00
} else {
2010-05-24 22:11:39 +08:00
object_properties_init ( object , class_type ) ;
2002-02-07 22:08:43 +08:00
}
2001-08-12 02:26:47 +08:00
} else {
2006-05-10 07:53:23 +08:00
Z_OBJVAL_P ( arg ) = class_type - > create_object ( class_type TSRMLS_CC ) ;
2002-02-07 22:08:43 +08:00
}
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int _object_init_ex ( zval * arg , zend_class_entry * class_type ZEND_FILE_LINE_DC TSRMLS_DC ) /* { { { */
2001-08-12 02:26:47 +08:00
{
2002-04-30 17:56:48 +08:00
return _object_and_properties_init ( arg , class_type , 0 ZEND_FILE_LINE_RELAY_CC TSRMLS_CC ) ;
2001-08-12 02:26:47 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int _object_init ( zval * arg ZEND_FILE_LINE_DC TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2002-04-30 17:56:48 +08:00
return _object_init_ex ( arg , zend_standard_class_def ZEND_FILE_LINE_RELAY_CC TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_function ( zval * arg , const char * key , void ( * function_ptr ) ( INTERNAL_FUNCTION_PARAMETERS ) ) /* { { { */
1999-10-04 19:42:46 +08:00
{
zend_error ( E_WARNING , " add_assoc_function() is no longer supported " ) ;
return FAILURE ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_long_ex ( zval * arg , const char * key , uint key_len , long n ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_LONG ( tmp , n ) ;
2006-05-10 07:53:23 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_null_ex ( zval * arg , const char * key , uint key_len ) /* { { { */
1999-12-31 21:56:59 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_NULL ( tmp ) ;
2006-05-10 07:53:23 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-12-31 21:56:59 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-12-31 21:56:59 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_bool_ex ( zval * arg , const char * key , uint key_len , int b ) /* { { { */
1999-10-04 19:42:46 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_BOOL ( tmp , b ) ;
1999-10-04 19:42:46 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_resource_ex ( zval * arg , const char * key , uint key_len , int r ) /* { { { */
1999-10-04 19:42:46 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_RESOURCE ( tmp , r ) ;
2006-05-10 07:53:23 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_double_ex ( zval * arg , const char * key , uint key_len , double d ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_DOUBLE ( tmp , d ) ;
1999-04-08 02:10:10 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_string_ex ( zval * arg , const char * key , uint key_len , char * str , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRING ( tmp , str , duplicate ) ;
1999-04-08 02:10:10 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_stringl_ex ( zval * arg , const char * key , uint key_len , char * str , uint length , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRINGL ( tmp , str , length , duplicate ) ;
1999-04-08 02:10:10 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_assoc_zval_ex ( zval * arg , const char * key , uint key_len , zval * value ) /* { { { */
2001-01-19 16:40:49 +08:00
{
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & value , sizeof ( zval * ) , NULL ) ;
2001-01-19 16:40:49 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-01-19 16:40:49 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_index_long ( zval * arg , ulong index , long n ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
1999-10-04 19:42:46 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_LONG ( tmp , n ) ;
2001-08-11 23:56:40 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_index_null ( zval * arg , ulong index ) /* { { { */
1999-12-31 21:56:59 +08:00
{
zval * tmp ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_NULL ( tmp ) ;
1999-12-31 21:56:59 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-12-31 21:56:59 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_index_bool ( zval * arg , ulong index , int b ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
2001-01-23 23:30:18 +08:00
ZVAL_BOOL ( tmp , b ) ;
2006-05-10 07:53:23 +08:00
2001-08-11 23:56:40 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_index_resource ( zval * arg , ulong index , int r ) /* { { { */
1999-10-04 19:42:46 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_RESOURCE ( tmp , r ) ;
2006-05-10 07:53:23 +08:00
2001-08-11 23:56:40 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_index_double ( zval * arg , ulong index , double d ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_DOUBLE ( tmp , d ) ;
2006-05-10 07:53:23 +08:00
2001-08-11 23:56:40 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_index_string ( zval * arg , ulong index , const char * str , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRING ( tmp , str , duplicate ) ;
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_index_stringl ( zval * arg , ulong index , const char * str , uint length , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRINGL ( tmp , str , length , duplicate ) ;
2007-11-03 03:40:39 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_index_zval ( zval * arg , ulong index , zval * value ) /* { { { */
2001-01-21 03:16:38 +08:00
{
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & value , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_long ( zval * arg , long n ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_LONG ( tmp , n ) ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_null ( zval * arg ) /* { { { */
1999-12-31 21:56:59 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_NULL ( tmp ) ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp , sizeof ( zval * ) , NULL ) ;
1999-12-31 21:56:59 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-12-31 21:56:59 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_bool ( zval * arg , int b ) /* { { { */
1999-10-04 19:42:46 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_BOOL ( tmp , b ) ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp , sizeof ( zval * ) , NULL ) ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_resource ( zval * arg , int r ) /* { { { */
1999-10-04 19:42:46 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_RESOURCE ( tmp , r ) ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp , sizeof ( zval * ) , NULL ) ;
1999-10-04 19:42:46 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-10-04 19:42:46 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_double ( zval * arg , double d ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_DOUBLE ( tmp , d ) ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_string ( zval * arg , const char * str , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRING ( tmp , str , duplicate ) ;
2001-08-11 23:56:40 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_stringl ( zval * arg , const char * str , uint length , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRINGL ( tmp , str , length , duplicate ) ;
2001-08-11 23:56:40 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & tmp , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_next_index_zval ( zval * arg , zval * value ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2001-01-21 03:16:38 +08:00
return zend_hash_next_index_insert ( Z_ARRVAL_P ( arg ) , & value , sizeof ( zval * ) , NULL ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_get_assoc_string_ex ( zval * arg , const char * key , uint key_len , const char * str , void * * dest , int duplicate ) /* { { { */
2001-01-21 03:16:38 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRING ( tmp , str , duplicate ) ;
2006-05-10 07:53:23 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , dest ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_get_assoc_stringl_ex ( zval * arg , const char * key , uint key_len , const char * str , uint length , void * * dest , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRINGL ( tmp , str , length , duplicate ) ;
1999-04-08 02:10:10 +08:00
2003-10-04 06:41:43 +08:00
return zend_symtable_update ( Z_ARRVAL_P ( arg ) , key , key_len , ( void * ) & tmp , sizeof ( zval * ) , dest ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_get_index_long ( zval * arg , ulong index , long l , void * * dest ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_LONG ( tmp , l ) ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , dest ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_get_index_double ( zval * arg , ulong index , double d , void * * dest ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_DOUBLE ( tmp , d ) ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , dest ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_get_index_string ( zval * arg , ulong index , const char * str , void * * dest , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2006-05-10 07:53:23 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRING ( tmp , str , duplicate ) ;
2007-11-03 03:40:39 +08:00
2001-08-11 23:56:40 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , dest ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int add_get_index_stringl ( zval * arg , ulong index , const char * str , uint length , void * * dest , int duplicate ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2007-11-03 03:40:39 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRINGL ( tmp , str , length , duplicate ) ;
2007-11-03 03:40:39 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , dest ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_long_ex ( zval * arg , const char * key , uint key_len , long n TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2005-11-23 19:15:11 +08:00
zval * z_key ;
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_LONG ( tmp , n ) ;
2007-11-03 03:40:39 +08:00
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( z_key ) ;
ZVAL_STRINGL ( z_key , key , key_len - 1 , 1 ) ;
2001-01-21 03:16:38 +08:00
2010-04-20 18:57:45 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp , 0 TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_bool_ex ( zval * arg , const char * key , uint key_len , int b TSRMLS_DC ) /* { { { */
2000-02-02 07:12:48 +08:00
{
zval * tmp ;
2005-11-23 19:15:11 +08:00
zval * z_key ;
2000-02-02 07:12:48 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_BOOL ( tmp , b ) ;
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( z_key ) ;
ZVAL_STRINGL ( z_key , key , key_len - 1 , 1 ) ;
2003-01-14 20:15:09 +08:00
2010-04-20 18:57:45 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp , 0 TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2000-02-02 07:12:48 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-02-02 07:12:48 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_null_ex ( zval * arg , const char * key , uint key_len TSRMLS_DC ) /* { { { */
2000-02-02 07:12:48 +08:00
{
zval * tmp ;
2005-11-23 19:15:11 +08:00
zval * z_key ;
2007-11-03 03:40:39 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_NULL ( tmp ) ;
2007-11-03 03:40:39 +08:00
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( z_key ) ;
ZVAL_STRINGL ( z_key , key , key_len - 1 , 1 ) ;
2003-01-14 20:15:09 +08:00
2010-04-20 18:57:45 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp , 0 TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2000-02-02 07:12:48 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-02-02 07:12:48 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_resource_ex ( zval * arg , const char * key , uint key_len , long n TSRMLS_DC ) /* { { { */
1999-09-29 23:25:06 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2005-11-23 19:15:11 +08:00
zval * z_key ;
2007-11-03 03:40:39 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_RESOURCE ( tmp , n ) ;
2001-08-07 11:17:33 +08:00
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( z_key ) ;
ZVAL_STRINGL ( z_key , key , key_len - 1 , 1 ) ;
2010-04-20 18:57:45 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp , 0 TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
1999-09-29 23:25:06 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-09-29 23:25:06 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_double_ex ( zval * arg , const char * key , uint key_len , double d TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2005-11-23 19:15:11 +08:00
zval * z_key ;
2003-01-01 20:38:55 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_DOUBLE ( tmp , d ) ;
2007-11-03 03:40:39 +08:00
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( z_key ) ;
ZVAL_STRINGL ( z_key , key , key_len - 1 , 1 ) ;
2001-08-07 11:17:33 +08:00
2010-04-20 18:57:45 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp , 0 TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2010-04-28 18:11:50 +08:00
ZEND_API int add_property_string_ex ( zval * arg , const char * key , uint key_len , const char * str , int duplicate TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2005-11-23 19:15:11 +08:00
zval * z_key ;
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRING ( tmp , str , duplicate ) ;
1999-04-08 02:10:10 +08:00
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( z_key ) ;
ZVAL_STRINGL ( z_key , key , key_len - 1 , 1 ) ;
2003-01-14 20:15:09 +08:00
2010-04-20 18:57:45 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp , 0 TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2001-01-21 03:16:38 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2010-04-28 18:11:50 +08:00
ZEND_API int add_property_stringl_ex ( zval * arg , const char * key , uint key_len , const char * str , uint length , int duplicate TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
1999-12-27 05:21:33 +08:00
zval * tmp ;
2005-11-23 19:15:11 +08:00
zval * z_key ;
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRINGL ( tmp , str , length , duplicate ) ;
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( z_key ) ;
ZVAL_STRINGL ( z_key , key , key_len - 1 , 1 ) ;
2003-01-14 20:15:09 +08:00
2010-04-20 18:57:45 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp , 0 TSRMLS_CC ) ;
2003-01-14 23:12:35 +08:00
zval_ptr_dtor ( & tmp ) ; /* write_property will add 1 to refcount */
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int add_property_zval_ex ( zval * arg , const char * key , uint key_len , zval * value TSRMLS_DC ) /* { { { */
2001-01-21 03:16:38 +08:00
{
2005-11-23 19:15:11 +08:00
zval * z_key ;
2003-01-01 20:38:55 +08:00
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( z_key ) ;
ZVAL_STRINGL ( z_key , key , key_len - 1 , 1 ) ;
2003-01-14 20:15:09 +08:00
2010-04-20 18:57:45 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , value , 0 TSRMLS_CC ) ;
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2001-01-21 03:16:38 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int zend_startup_module_ex ( zend_module_entry * module TSRMLS_DC ) /* { { { */
2005-06-17 17:36:26 +08:00
{
int name_len ;
char * lcname ;
if ( module - > module_started ) {
return SUCCESS ;
}
module - > module_started = 1 ;
/* Check module dependencies */
if ( module - > deps ) {
2007-09-28 02:00:48 +08:00
const zend_module_dep * dep = module - > deps ;
2005-06-17 17:36:26 +08:00
while ( dep - > name ) {
if ( dep - > type = = MODULE_DEP_REQUIRED ) {
zend_module_entry * req_mod ;
name_len = strlen ( dep - > name ) ;
lcname = zend_str_tolower_dup ( dep - > name , name_len ) ;
2007-11-03 03:40:39 +08:00
if ( zend_hash_find ( & module_registry , lcname , name_len + 1 , ( void * * ) & req_mod ) = = FAILURE | | ! req_mod - > module_started ) {
2005-06-17 17:36:26 +08:00
efree ( lcname ) ;
/* TODO: Check version relationship */
2005-08-08 22:25:05 +08:00
zend_error ( E_CORE_WARNING , " Cannot load module '%s' because required module '%s' is not loaded " , module - > name , dep - > name ) ;
2005-06-17 17:36:26 +08:00
module - > module_started = 0 ;
return FAILURE ;
2006-05-10 07:53:23 +08:00
}
2005-06-17 17:36:26 +08:00
efree ( lcname ) ;
}
+ + dep ;
}
}
2006-06-15 22:03:21 +08:00
/* Initialize module globals */
if ( module - > globals_size ) {
# ifdef ZTS
ts_allocate_id ( module - > globals_id_ptr , module - > globals_size , ( ts_allocate_ctor ) module - > globals_ctor , ( ts_allocate_dtor ) module - > globals_dtor ) ;
# else
if ( module - > globals_ctor ) {
module - > globals_ctor ( module - > globals_ptr TSRMLS_CC ) ;
}
# endif
}
2005-06-17 17:36:26 +08:00
if ( module - > module_startup_func ) {
EG ( current_module ) = module ;
if ( module - > module_startup_func ( module - > type , module - > module_number TSRMLS_CC ) = = FAILURE ) {
zend_error ( E_CORE_ERROR , " Unable to start %s module " , module - > name ) ;
EG ( current_module ) = NULL ;
return FAILURE ;
}
EG ( current_module ) = NULL ;
}
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-06-17 17:36:26 +08:00
2007-11-03 03:40:39 +08:00
static void zend_sort_modules ( void * base , size_t count , size_t siz , compare_func_t compare TSRMLS_DC ) /* { { { */
2005-06-17 17:36:26 +08:00
{
Bucket * * b1 = base ;
Bucket * * b2 ;
Bucket * * end = b1 + count ;
2006-05-10 07:53:23 +08:00
Bucket * tmp ;
2005-06-17 17:36:26 +08:00
zend_module_entry * m , * r ;
while ( b1 < end ) {
try_again :
m = ( zend_module_entry * ) ( * b1 ) - > pData ;
if ( ! m - > module_started & & m - > deps ) {
2007-09-28 02:00:48 +08:00
const zend_module_dep * dep = m - > deps ;
2005-06-17 17:36:26 +08:00
while ( dep - > name ) {
if ( dep - > type = = MODULE_DEP_REQUIRED | | dep - > type = = MODULE_DEP_OPTIONAL ) {
b2 = b1 + 1 ;
while ( b2 < end ) {
2007-07-06 20:17:58 +08:00
r = ( zend_module_entry * ) ( * b2 ) - > pData ;
if ( strcasecmp ( dep - > name , r - > name ) = = 0 ) {
2007-11-03 03:40:39 +08:00
tmp = * b1 ;
2007-07-06 20:17:58 +08:00
* b1 = * b2 ;
* b2 = tmp ;
goto try_again ;
}
b2 + + ;
}
}
dep + + ;
2006-05-10 07:53:23 +08:00
}
2005-06-17 17:36:26 +08:00
}
b1 + + ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-06-17 17:36:26 +08:00
2010-10-15 15:30:24 +08:00
ZEND_API void zend_collect_module_handlers ( TSRMLS_D ) /* { { { */
2010-07-06 19:40:17 +08:00
{
HashPosition pos ;
zend_module_entry * module ;
int startup_count = 0 ;
int shutdown_count = 0 ;
int post_deactivate_count = 0 ;
zend_class_entry * * pce ;
int class_count = 0 ;
/* Collect extensions with request startup/shutdown handlers */
for ( zend_hash_internal_pointer_reset_ex ( & module_registry , & pos ) ;
zend_hash_get_current_data_ex ( & module_registry , ( void * ) & module , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( & module_registry , & pos ) ) {
if ( module - > request_startup_func ) {
startup_count + + ;
}
if ( module - > request_shutdown_func ) {
shutdown_count + + ;
}
if ( module - > post_deactivate_func ) {
post_deactivate_count + + ;
}
}
module_request_startup_handlers = ( zend_module_entry * * ) malloc (
sizeof ( zend_module_entry * ) *
( startup_count + 1 +
shutdown_count + 1 +
post_deactivate_count + 1 ) ) ;
module_request_startup_handlers [ startup_count ] = NULL ;
module_request_shutdown_handlers = module_request_startup_handlers + startup_count + 1 ;
module_request_shutdown_handlers [ shutdown_count ] = NULL ;
module_post_deactivate_handlers = module_request_shutdown_handlers + shutdown_count + 1 ;
module_post_deactivate_handlers [ post_deactivate_count ] = NULL ;
startup_count = 0 ;
for ( zend_hash_internal_pointer_reset_ex ( & module_registry , & pos ) ;
zend_hash_get_current_data_ex ( & module_registry , ( void * ) & module , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( & module_registry , & pos ) ) {
if ( module - > request_startup_func ) {
module_request_startup_handlers [ startup_count + + ] = module ;
}
if ( module - > request_shutdown_func ) {
module_request_shutdown_handlers [ - - shutdown_count ] = module ;
}
if ( module - > post_deactivate_func ) {
module_post_deactivate_handlers [ - - post_deactivate_count ] = module ;
}
}
/* Collect internal classes with static members */
for ( zend_hash_internal_pointer_reset_ex ( CG ( class_table ) , & pos ) ;
zend_hash_get_current_data_ex ( CG ( class_table ) , ( void * ) & pce , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( CG ( class_table ) , & pos ) ) {
if ( ( * pce ) - > type = = ZEND_INTERNAL_CLASS & &
( * pce ) - > default_static_members_count > 0 ) {
class_count + + ;
}
}
class_cleanup_handlers = ( zend_class_entry * * ) malloc (
sizeof ( zend_class_entry * ) *
( class_count + 1 ) ) ;
class_cleanup_handlers [ class_count ] = NULL ;
if ( class_count ) {
for ( zend_hash_internal_pointer_reset_ex ( CG ( class_table ) , & pos ) ;
zend_hash_get_current_data_ex ( CG ( class_table ) , ( void * ) & pce , & pos ) = = SUCCESS ;
zend_hash_move_forward_ex ( CG ( class_table ) , & pos ) ) {
if ( ( * pce ) - > type = = ZEND_INTERNAL_CLASS & &
( * pce ) - > default_static_members_count > 0 ) {
class_cleanup_handlers [ - - class_count ] = * pce ;
}
}
}
}
/* }}} */
2007-11-03 03:40:39 +08:00
ZEND_API int zend_startup_modules ( TSRMLS_D ) /* { { { */
2005-06-17 17:36:26 +08:00
{
zend_hash_sort ( & module_registry , zend_sort_modules , NULL , 0 TSRMLS_CC ) ;
2005-06-30 21:43:00 +08:00
zend_hash_apply ( & module_registry , ( apply_func_t ) zend_startup_module_ex TSRMLS_CC ) ;
2005-06-17 17:36:26 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-06-17 17:36:26 +08:00
2010-07-06 19:40:17 +08:00
ZEND_API void zend_destroy_modules ( void ) /* { { { */
{
free ( class_cleanup_handlers ) ;
free ( module_request_startup_handlers ) ;
zend_hash_graceful_reverse_destroy ( & module_registry ) ;
}
/* }}} */
2007-11-03 03:40:39 +08:00
ZEND_API zend_module_entry * zend_register_module_ex ( zend_module_entry * module TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2004-05-13 07:05:28 +08:00
int name_len ;
char * lcname ;
2004-05-19 05:19:15 +08:00
zend_module_entry * module_ptr ;
2006-05-10 07:53:23 +08:00
2004-05-13 07:05:28 +08:00
if ( ! module ) {
2005-07-19 00:20:08 +08:00
return NULL ;
2004-05-13 07:05:28 +08:00
}
2004-05-13 07:03:38 +08:00
2004-05-13 07:05:28 +08:00
#if 0
2007-11-03 03:40:39 +08:00
zend_printf ( " %s: Registering module %d \n " , module - > name , module - > module_number ) ;
2004-05-13 07:05:28 +08:00
# endif
2005-06-17 17:36:26 +08:00
/* Check module dependencies */
if ( module - > deps ) {
2007-09-28 02:00:48 +08:00
const zend_module_dep * dep = module - > deps ;
2005-06-17 17:36:26 +08:00
while ( dep - > name ) {
if ( dep - > type = = MODULE_DEP_CONFLICTS ) {
name_len = strlen ( dep - > name ) ;
lcname = zend_str_tolower_dup ( dep - > name , name_len ) ;
if ( zend_hash_exists ( & module_registry , lcname , name_len + 1 ) ) {
efree ( lcname ) ;
/* TODO: Check version relationship */
zend_error ( E_CORE_WARNING , " Cannot load module '%s' because conflicting module '%s' is already loaded " , module - > name , dep - > name ) ;
2005-07-19 00:20:08 +08:00
return NULL ;
2006-05-10 07:53:23 +08:00
}
2005-06-17 17:36:26 +08:00
efree ( lcname ) ;
}
+ + dep ;
}
}
2004-05-13 07:05:28 +08:00
name_len = strlen ( module - > name ) ;
lcname = zend_str_tolower_dup ( module - > name , name_len ) ;
2004-05-19 05:19:15 +08:00
if ( zend_hash_add ( & module_registry , lcname , name_len + 1 , ( void * ) module , sizeof ( zend_module_entry ) , ( void * * ) & module_ptr ) = = FAILURE ) {
2004-05-13 07:05:28 +08:00
zend_error ( E_CORE_WARNING , " Module '%s' already loaded " , module - > name ) ;
efree ( lcname ) ;
2005-07-19 00:20:08 +08:00
return NULL ;
2004-05-13 07:05:28 +08:00
}
efree ( lcname ) ;
2004-05-19 05:19:15 +08:00
module = module_ptr ;
2006-05-10 07:53:23 +08:00
EG ( current_module ) = module ;
2004-05-13 07:05:28 +08:00
if ( module - > functions & & zend_register_functions ( NULL , module - > functions , NULL , module - > type TSRMLS_CC ) = = FAILURE ) {
2006-05-10 07:53:23 +08:00
EG ( current_module ) = NULL ;
2007-11-03 03:40:39 +08:00
zend_error ( E_CORE_WARNING , " %s: Unable to register functions, unable to load " , module - > name ) ;
2005-07-19 00:20:08 +08:00
return NULL ;
2004-05-13 07:05:28 +08:00
}
2006-05-10 07:53:23 +08:00
EG ( current_module ) = NULL ;
2005-07-19 00:20:08 +08:00
return module ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API zend_module_entry * zend_register_internal_module ( zend_module_entry * module TSRMLS_DC ) /* { { { */
2004-05-13 07:05:28 +08:00
{
module - > module_number = zend_next_free_module ( ) ;
module - > type = MODULE_PERSISTENT ;
return zend_register_module_ex ( module TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2004-05-13 07:05:28 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API void zend_check_magic_method_implementation ( const zend_class_entry * ce , const zend_function * fptr , int error_type TSRMLS_DC ) /* { { { */
2004-09-10 00:51:45 +08:00
{
char lcname [ 16 ] ;
int name_len ;
2007-11-03 03:40:39 +08:00
/* we don't care if the function name is longer, in fact lowercasing only
2004-09-10 00:51:45 +08:00
* the beginning of the name speeds up the check process */
name_len = strlen ( fptr - > common . function_name ) ;
zend_str_tolower_copy ( lcname , fptr - > common . function_name , MIN ( name_len , sizeof ( lcname ) - 1 ) ) ;
lcname [ sizeof ( lcname ) - 1 ] = ' \0 ' ; /* zend_str_tolower_copy won't necessarily set the zero byte */
if ( name_len = = sizeof ( ZEND_DESTRUCTOR_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_DESTRUCTOR_FUNC_NAME , sizeof ( ZEND_DESTRUCTOR_FUNC_NAME ) ) & & fptr - > common . num_args ! = 0 ) {
2006-07-25 14:49:38 +08:00
zend_error ( error_type , " Destructor %s::%s() cannot take arguments " , ce - > name , ZEND_DESTRUCTOR_FUNC_NAME ) ;
2004-09-10 00:51:45 +08:00
} else if ( name_len = = sizeof ( ZEND_CLONE_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_CLONE_FUNC_NAME , sizeof ( ZEND_CLONE_FUNC_NAME ) ) & & fptr - > common . num_args ! = 0 ) {
zend_error ( error_type , " Method %s::%s() cannot accept any arguments " , ce - > name , ZEND_CLONE_FUNC_NAME ) ;
2007-08-31 20:36:14 +08:00
} else if ( name_len = = sizeof ( ZEND_GET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_GET_FUNC_NAME , sizeof ( ZEND_GET_FUNC_NAME ) ) ) {
if ( fptr - > common . num_args ! = 1 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 1 argument " , ce - > name , ZEND_GET_FUNC_NAME ) ;
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) ) {
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name , ZEND_GET_FUNC_NAME ) ;
}
} else if ( name_len = = sizeof ( ZEND_SET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_SET_FUNC_NAME , sizeof ( ZEND_SET_FUNC_NAME ) ) ) {
if ( fptr - > common . num_args ! = 2 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 2 arguments " , ce - > name , ZEND_SET_FUNC_NAME ) ;
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) | | ARG_SHOULD_BE_SENT_BY_REF ( fptr , 2 ) ) {
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name , ZEND_SET_FUNC_NAME ) ;
}
} else if ( name_len = = sizeof ( ZEND_UNSET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_UNSET_FUNC_NAME , sizeof ( ZEND_UNSET_FUNC_NAME ) ) ) {
if ( fptr - > common . num_args ! = 1 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 1 argument " , ce - > name , ZEND_UNSET_FUNC_NAME ) ;
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) ) {
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name , ZEND_UNSET_FUNC_NAME ) ;
}
} else if ( name_len = = sizeof ( ZEND_ISSET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_ISSET_FUNC_NAME , sizeof ( ZEND_ISSET_FUNC_NAME ) ) ) {
if ( fptr - > common . num_args ! = 1 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 1 argument " , ce - > name , ZEND_ISSET_FUNC_NAME ) ;
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) ) {
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name , ZEND_ISSET_FUNC_NAME ) ;
}
} else if ( name_len = = sizeof ( ZEND_CALL_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_CALL_FUNC_NAME , sizeof ( ZEND_CALL_FUNC_NAME ) ) ) {
if ( fptr - > common . num_args ! = 2 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 2 arguments " , ce - > name , ZEND_CALL_FUNC_NAME ) ;
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) | | ARG_SHOULD_BE_SENT_BY_REF ( fptr , 2 ) ) {
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name , ZEND_CALL_FUNC_NAME ) ;
}
2007-09-29 16:52:40 +08:00
} else if ( name_len = = sizeof ( ZEND_CALLSTATIC_FUNC_NAME ) - 1 & &
2007-11-03 03:40:39 +08:00
! memcmp ( lcname , ZEND_CALLSTATIC_FUNC_NAME , sizeof ( ZEND_CALLSTATIC_FUNC_NAME ) - 1 )
) {
2007-09-29 16:52:40 +08:00
if ( fptr - > common . num_args ! = 2 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 2 arguments " , ce - > name , ZEND_CALLSTATIC_FUNC_NAME ) ;
} else if ( ARG_SHOULD_BE_SENT_BY_REF ( fptr , 1 ) | | ARG_SHOULD_BE_SENT_BY_REF ( fptr , 2 ) ) {
zend_error ( error_type , " Method %s::%s() cannot take arguments by reference " , ce - > name , ZEND_CALLSTATIC_FUNC_NAME ) ;
}
} else if ( name_len = = sizeof ( ZEND_TOSTRING_FUNC_NAME ) - 1 & &
2007-11-03 03:40:39 +08:00
! memcmp ( lcname , ZEND_TOSTRING_FUNC_NAME , sizeof ( ZEND_TOSTRING_FUNC_NAME ) - 1 ) & & fptr - > common . num_args ! = 0
) {
2007-09-29 16:52:40 +08:00
zend_error ( error_type , " Method %s::%s() cannot take arguments " , ce - > name , ZEND_TOSTRING_FUNC_NAME ) ;
2004-09-10 00:51:45 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
/* registers all functions in *library_functions in the function hash */
2007-11-03 03:40:39 +08:00
ZEND_API int zend_register_functions ( zend_class_entry * scope , const zend_function_entry * functions , HashTable * function_table , int type TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2007-09-28 02:00:48 +08:00
const zend_function_entry * ptr = functions ;
2003-01-10 22:41:53 +08:00
zend_function function , * reg_function ;
1999-12-28 03:17:40 +08:00
zend_internal_function * internal_function = ( zend_internal_function * ) & function ;
2011-07-10 20:37:42 +08:00
int count = 0 , unload = 0 , result = 0 ;
1999-05-28 20:06:59 +08:00
HashTable * target_function_table = function_table ;
2000-06-13 04:22:17 +08:00
int error_type ;
2007-09-29 16:52:40 +08:00
zend_function * ctor = NULL , * dtor = NULL , * clone = NULL , * __get = NULL , * __set = NULL , * __unset = NULL , * __isset = NULL , * __call = NULL , * __callstatic = NULL , * __tostring = NULL ;
2011-09-13 21:29:35 +08:00
const char * lowercase_name ;
2003-06-02 20:13:11 +08:00
int fname_len ;
2010-10-15 05:33:10 +08:00
const char * lc_class_name = NULL ;
2006-02-07 04:37:11 +08:00
int class_name_len = 0 ;
1999-04-08 02:10:10 +08:00
2000-06-13 04:22:17 +08:00
if ( type = = MODULE_PERSISTENT ) {
error_type = E_CORE_WARNING ;
} else {
error_type = E_WARNING ;
}
1999-05-28 20:06:59 +08:00
if ( ! target_function_table ) {
target_function_table = CG ( function_table ) ;
}
1999-12-28 01:29:35 +08:00
internal_function - > type = ZEND_INTERNAL_FUNCTION ;
2007-05-30 18:17:43 +08:00
internal_function - > module = EG ( current_module ) ;
2007-11-03 03:40:39 +08:00
2004-09-10 00:51:45 +08:00
if ( scope ) {
class_name_len = strlen ( scope - > name ) ;
2008-11-04 23:58:55 +08:00
if ( ( lc_class_name = zend_memrchr ( scope - > name , ' \\ ' , class_name_len ) ) ) {
+ + lc_class_name ;
2008-05-05 17:44:39 +08:00
class_name_len - = ( lc_class_name - scope - > name ) ;
lc_class_name = zend_str_tolower_dup ( lc_class_name , class_name_len ) ;
} else {
lc_class_name = zend_str_tolower_dup ( scope - > name , class_name_len ) ;
}
2004-09-10 00:51:45 +08:00
}
2003-04-04 20:25:47 +08:00
1999-04-08 02:10:10 +08:00
while ( ptr - > fname ) {
1999-12-28 01:29:35 +08:00
internal_function - > handler = ptr - > handler ;
2007-09-28 02:00:48 +08:00
internal_function - > function_name = ( char * ) ptr - > fname ;
2002-11-24 04:44:12 +08:00
internal_function - > scope = scope ;
2003-03-29 19:19:38 +08:00
internal_function - > prototype = NULL ;
2003-08-04 05:04:39 +08:00
if ( ptr - > flags ) {
2003-08-04 05:06:23 +08:00
if ( ! ( ptr - > flags & ZEND_ACC_PPP_MASK ) ) {
2006-02-26 02:25:45 +08:00
if ( ptr - > flags ! = ZEND_ACC_DEPRECATED | | scope ) {
zend_error ( error_type , " Invalid access level for %s%s%s() - access must be exactly one of public, protected or private " , scope ? scope - > name : " " , scope ? " :: " : " " , ptr - > fname ) ;
}
2006-02-19 18:39:31 +08:00
internal_function - > fn_flags = ZEND_ACC_PUBLIC | ptr - > flags ;
2003-08-24 19:07:30 +08:00
} else {
internal_function - > fn_flags = ptr - > flags ;
2003-08-04 05:06:23 +08:00
}
2003-08-04 05:04:39 +08:00
} else {
internal_function - > fn_flags = ZEND_ACC_PUBLIC ;
}
2010-09-15 15:38:52 +08:00
if ( ptr - > arg_info ) {
zend_internal_function_info * info = ( zend_internal_function_info * ) ptr - > arg_info ;
internal_function - > arg_info = ( zend_arg_info * ) ptr - > arg_info + 1 ;
internal_function - > num_args = ptr - > num_args ;
/* Currently you cannot denote that the function can accept less arguments than num_args */
if ( info - > required_num_args = = - 1 ) {
internal_function - > required_num_args = ptr - > num_args ;
} else {
internal_function - > required_num_args = info - > required_num_args ;
}
if ( info - > pass_rest_by_reference ) {
if ( info - > pass_rest_by_reference = = ZEND_SEND_PREFER_REF ) {
internal_function - > fn_flags | = ZEND_ACC_PASS_REST_PREFER_REF ;
} else {
internal_function - > fn_flags | = ZEND_ACC_PASS_REST_BY_REFERENCE ;
}
}
if ( info - > return_reference ) {
internal_function - > fn_flags | = ZEND_ACC_RETURN_REFERENCE ;
}
} else {
internal_function - > arg_info = NULL ;
internal_function - > num_args = 0 ;
internal_function - > required_num_args = 0 ;
}
2004-02-27 17:14:55 +08:00
if ( ptr - > flags & ZEND_ACC_ABSTRACT ) {
2003-08-17 08:57:35 +08:00
if ( scope ) {
2004-02-28 02:20:53 +08:00
/* This is a class that must be abstract itself. Here we set the check info. */
2004-03-10 00:38:37 +08:00
scope - > ce_flags | = ZEND_ACC_IMPLICIT_ABSTRACT_CLASS ;
2004-02-27 17:14:55 +08:00
if ( ! ( scope - > ce_flags & ZEND_ACC_INTERFACE ) ) {
2004-02-28 02:20:53 +08:00
/* Since the class is not an interface it needs to be declared as a abstract class. */
2004-03-10 00:38:37 +08:00
/* Since here we are handling internal functions only we can add the keyword flag. */
2008-02-19 14:52:43 +08:00
/* This time we set the flag for the keyword 'abstract'. */
2004-03-10 00:38:37 +08:00
scope - > ce_flags | = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ;
2004-02-27 17:14:55 +08:00
}
2003-08-17 08:57:35 +08:00
}
2006-06-04 18:27:28 +08:00
if ( ptr - > flags & ZEND_ACC_STATIC & & ( ! scope | | ! ( scope - > ce_flags & ZEND_ACC_INTERFACE ) ) ) {
zend_error ( error_type , " Static function %s%s%s() cannot be abstract " , scope ? scope - > name : " " , scope ? " :: " : " " , ptr - > fname ) ;
}
2003-08-17 08:57:35 +08:00
} else {
2004-02-27 17:14:55 +08:00
if ( scope & & ( scope - > ce_flags & ZEND_ACC_INTERFACE ) ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lc_class_name ) ;
2003-09-18 18:21:38 +08:00
zend_error ( error_type , " Interface %s cannot contain non abstract method %s() " , scope - > name , ptr - > fname ) ;
return FAILURE ;
}
2003-08-17 08:57:35 +08:00
if ( ! internal_function - > handler ) {
2005-10-27 22:07:30 +08:00
if ( scope ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lc_class_name ) ;
2005-10-27 22:07:30 +08:00
}
2003-08-17 08:57:35 +08:00
zend_error ( error_type , " Method %s%s%s() cannot be a NULL function " , scope ? scope - > name : " " , scope ? " :: " : " " , ptr - > fname ) ;
zend_unregister_functions ( functions , count , target_function_table TSRMLS_CC ) ;
return FAILURE ;
}
1999-04-08 02:10:10 +08:00
}
2003-03-20 05:07:49 +08:00
fname_len = strlen ( ptr - > fname ) ;
2010-05-25 17:00:20 +08:00
lowercase_name = zend_new_interned_string ( zend_str_tolower_dup ( ptr - > fname , fname_len ) , fname_len + 1 , 1 TSRMLS_CC ) ;
2011-07-10 10:00:00 +08:00
if ( IS_INTERNED ( lowercase_name ) ) {
2011-07-10 20:37:42 +08:00
result = zend_hash_quick_add ( target_function_table , lowercase_name , fname_len + 1 , INTERNED_HASH ( lowercase_name ) , & function , sizeof ( zend_function ) , ( void * * ) & reg_function ) ;
} else {
result = zend_hash_add ( target_function_table , lowercase_name , fname_len + 1 , & function , sizeof ( zend_function ) , ( void * * ) & reg_function ) ;
}
if ( result = = FAILURE ) {
unload = 1 ;
str_efree ( lowercase_name ) ;
break ;
1999-04-08 02:10:10 +08:00
}
2003-01-10 22:41:53 +08:00
if ( scope ) {
2003-06-02 20:13:11 +08:00
/* Look for ctor, dtor, clone
* If it ' s an old - style constructor , store it only if we don ' t have
* a constructor already .
*/
2011-07-10 20:37:42 +08:00
if ( ( fname_len = = class_name_len ) & & ! ctor & & ! memcmp ( lowercase_name , lc_class_name , class_name_len + 1 ) ) {
2003-06-02 20:13:11 +08:00
ctor = reg_function ;
2004-09-10 00:51:45 +08:00
} else if ( ( fname_len = = sizeof ( ZEND_CONSTRUCTOR_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_CONSTRUCTOR_FUNC_NAME , sizeof ( ZEND_CONSTRUCTOR_FUNC_NAME ) ) ) {
2003-06-02 20:13:11 +08:00
ctor = reg_function ;
2004-09-10 00:51:45 +08:00
} else if ( ( fname_len = = sizeof ( ZEND_DESTRUCTOR_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_DESTRUCTOR_FUNC_NAME , sizeof ( ZEND_DESTRUCTOR_FUNC_NAME ) ) ) {
2003-06-02 20:13:11 +08:00
dtor = reg_function ;
2004-03-27 04:05:35 +08:00
if ( internal_function - > num_args ) {
zend_error ( error_type , " Destructor %s::%s() cannot take arguments " , scope - > name , ptr - > fname ) ;
}
2004-09-10 00:51:45 +08:00
} else if ( ( fname_len = = sizeof ( ZEND_CLONE_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_CLONE_FUNC_NAME , sizeof ( ZEND_CLONE_FUNC_NAME ) ) ) {
2003-06-02 20:13:11 +08:00
clone = reg_function ;
2004-09-10 00:51:45 +08:00
} else if ( ( fname_len = = sizeof ( ZEND_CALL_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_CALL_FUNC_NAME , sizeof ( ZEND_CALL_FUNC_NAME ) ) ) {
__call = reg_function ;
2007-09-29 16:52:40 +08:00
} else if ( ( fname_len = = sizeof ( ZEND_CALLSTATIC_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_CALLSTATIC_FUNC_NAME , sizeof ( ZEND_CALLSTATIC_FUNC_NAME ) ) ) {
__callstatic = reg_function ;
2006-05-10 07:53:23 +08:00
} else if ( ( fname_len = = sizeof ( ZEND_TOSTRING_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_TOSTRING_FUNC_NAME , sizeof ( ZEND_TOSTRING_FUNC_NAME ) ) ) {
__tostring = reg_function ;
2004-09-10 00:51:45 +08:00
} else if ( ( fname_len = = sizeof ( ZEND_GET_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_GET_FUNC_NAME , sizeof ( ZEND_GET_FUNC_NAME ) ) ) {
__get = reg_function ;
} else if ( ( fname_len = = sizeof ( ZEND_SET_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_SET_FUNC_NAME , sizeof ( ZEND_SET_FUNC_NAME ) ) ) {
__set = reg_function ;
2005-07-08 00:07:09 +08:00
} else if ( ( fname_len = = sizeof ( ZEND_UNSET_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_UNSET_FUNC_NAME , sizeof ( ZEND_UNSET_FUNC_NAME ) ) ) {
__unset = reg_function ;
} else if ( ( fname_len = = sizeof ( ZEND_ISSET_FUNC_NAME ) - 1 ) & & ! memcmp ( lowercase_name , ZEND_ISSET_FUNC_NAME , sizeof ( ZEND_ISSET_FUNC_NAME ) ) ) {
__isset = reg_function ;
2004-09-10 00:51:45 +08:00
} else {
reg_function = NULL ;
}
if ( reg_function ) {
zend_check_magic_method_implementation ( scope , reg_function , error_type TSRMLS_CC ) ;
2003-01-10 22:41:53 +08:00
}
}
1999-04-08 02:10:10 +08:00
ptr + + ;
count + + ;
2010-04-20 19:05:54 +08:00
str_efree ( lowercase_name ) ;
1999-04-08 02:10:10 +08:00
}
if ( unload ) { /* before unloading, display all remaining bad function in the module */
2004-09-10 00:51:45 +08:00
if ( scope ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lc_class_name ) ;
2004-09-10 00:51:45 +08:00
}
1999-04-08 02:10:10 +08:00
while ( ptr - > fname ) {
2008-08-22 22:51:30 +08:00
fname_len = strlen ( ptr - > fname ) ;
lowercase_name = zend_str_tolower_dup ( ptr - > fname , fname_len ) ;
if ( zend_hash_exists ( target_function_table , lowercase_name , fname_len + 1 ) ) {
2004-11-02 21:10:37 +08:00
zend_error ( error_type , " Function registration failed - duplicate name - %s%s%s " , scope ? scope - > name : " " , scope ? " :: " : " " , ptr - > fname ) ;
1999-04-08 02:10:10 +08:00
}
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lowercase_name ) ;
1999-04-08 02:10:10 +08:00
ptr + + ;
}
2001-07-30 09:48:22 +08:00
zend_unregister_functions ( functions , count , target_function_table TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
return FAILURE ;
}
2003-01-10 22:41:53 +08:00
if ( scope ) {
scope - > constructor = ctor ;
scope - > destructor = dtor ;
scope - > clone = clone ;
2004-09-10 00:51:45 +08:00
scope - > __call = __call ;
2007-09-29 16:52:40 +08:00
scope - > __callstatic = __callstatic ;
2006-05-10 07:53:23 +08:00
scope - > __tostring = __tostring ;
2004-09-10 00:51:45 +08:00
scope - > __get = __get ;
scope - > __set = __set ;
2005-07-08 00:07:09 +08:00
scope - > __unset = __unset ;
scope - > __isset = __isset ;
2003-08-23 23:38:58 +08:00
if ( ctor ) {
2004-01-25 00:59:24 +08:00
ctor - > common . fn_flags | = ZEND_ACC_CTOR ;
2003-09-02 21:26:25 +08:00
if ( ctor - > common . fn_flags & ZEND_ACC_STATIC ) {
2004-09-10 00:51:45 +08:00
zend_error ( error_type , " Constructor %s::%s() cannot be static " , scope - > name , ctor - > common . function_name ) ;
2003-09-02 21:26:25 +08:00
}
2004-01-25 00:59:24 +08:00
ctor - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
2003-08-23 23:38:58 +08:00
}
if ( dtor ) {
2004-01-25 00:59:24 +08:00
dtor - > common . fn_flags | = ZEND_ACC_DTOR ;
2003-09-02 21:26:25 +08:00
if ( dtor - > common . fn_flags & ZEND_ACC_STATIC ) {
2004-09-10 00:51:45 +08:00
zend_error ( error_type , " Destructor %s::%s() cannot be static " , scope - > name , dtor - > common . function_name ) ;
2003-09-02 21:26:25 +08:00
}
2004-01-25 00:59:24 +08:00
dtor - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
2003-08-23 23:38:58 +08:00
}
2004-01-24 04:52:39 +08:00
if ( clone ) {
2004-01-25 00:59:24 +08:00
clone - > common . fn_flags | = ZEND_ACC_CLONE ;
2004-01-24 04:52:39 +08:00
if ( clone - > common . fn_flags & ZEND_ACC_STATIC ) {
2004-09-10 00:51:45 +08:00
zend_error ( error_type , " Constructor %s::%s() cannot be static " , scope - > name , clone - > common . function_name ) ;
2004-01-24 04:52:39 +08:00
}
2004-01-25 00:59:24 +08:00
clone - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
2004-01-24 04:52:39 +08:00
}
2004-09-10 00:51:45 +08:00
if ( __call ) {
if ( __call - > common . fn_flags & ZEND_ACC_STATIC ) {
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name , __call - > common . function_name ) ;
}
__call - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
2007-09-29 16:52:40 +08:00
if ( __callstatic ) {
if ( ! ( __callstatic - > common . fn_flags & ZEND_ACC_STATIC ) ) {
zend_error ( error_type , " Method %s::%s() must be static " , scope - > name , __callstatic - > common . function_name ) ;
}
__callstatic - > common . fn_flags | = ZEND_ACC_STATIC ;
}
2006-05-10 07:53:23 +08:00
if ( __tostring ) {
if ( __tostring - > common . fn_flags & ZEND_ACC_STATIC ) {
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name , __tostring - > common . function_name ) ;
}
__tostring - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
2004-09-10 00:51:45 +08:00
if ( __get ) {
if ( __get - > common . fn_flags & ZEND_ACC_STATIC ) {
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name , __get - > common . function_name ) ;
}
__get - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
if ( __set ) {
if ( __set - > common . fn_flags & ZEND_ACC_STATIC ) {
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name , __set - > common . function_name ) ;
}
__set - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
2005-07-08 00:07:09 +08:00
if ( __unset ) {
if ( __unset - > common . fn_flags & ZEND_ACC_STATIC ) {
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name , __unset - > common . function_name ) ;
}
__unset - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
if ( __isset ) {
if ( __isset - > common . fn_flags & ZEND_ACC_STATIC ) {
zend_error ( error_type , " Method %s::%s() cannot be static " , scope - > name , __isset - > common . function_name ) ;
}
__isset - > common . fn_flags & = ~ ZEND_ACC_ALLOW_STATIC ;
}
2011-09-13 21:29:35 +08:00
efree ( ( char * ) lc_class_name ) ;
2003-01-10 22:41:53 +08:00
}
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2006-05-10 07:53:23 +08:00
/* count=-1 means erase all functions, otherwise,
1999-04-08 02:10:10 +08:00
* erase the first count functions
*/
2007-11-03 03:40:39 +08:00
ZEND_API void zend_unregister_functions ( const zend_function_entry * functions , int count , HashTable * function_table TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2007-09-28 02:00:48 +08:00
const zend_function_entry * ptr = functions ;
1999-04-08 02:10:10 +08:00
int i = 0 ;
1999-05-28 20:06:59 +08:00
HashTable * target_function_table = function_table ;
1999-04-08 02:10:10 +08:00
1999-05-28 20:06:59 +08:00
if ( ! target_function_table ) {
target_function_table = CG ( function_table ) ;
}
1999-04-08 02:10:10 +08:00
while ( ptr - > fname ) {
if ( count ! = - 1 & & i > = count ) {
break ;
}
#if 0
1999-05-28 20:06:59 +08:00
zend_printf ( " Unregistering %s() \n " , ptr - > fname ) ;
1999-04-08 02:10:10 +08:00
# endif
1999-05-28 20:06:59 +08:00
zend_hash_del ( target_function_table , ptr - > fname , strlen ( ptr - > fname ) + 1 ) ;
1999-04-08 02:10:10 +08:00
ptr + + ;
i + + ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int zend_startup_module ( zend_module_entry * module ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2001-07-30 09:48:22 +08:00
TSRMLS_FETCH ( ) ;
2006-05-10 07:53:23 +08:00
2007-11-03 03:40:39 +08:00
if ( ( module = zend_register_internal_module ( module TSRMLS_CC ) ) ! = NULL & & zend_startup_module_ex ( module TSRMLS_CC ) = = SUCCESS ) {
2005-06-17 17:36:26 +08:00
return SUCCESS ;
}
return FAILURE ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_get_module_started ( const char * module_name ) /* { { { */
2004-01-19 08:39:29 +08:00
{
zend_module_entry * module ;
2006-05-10 07:53:23 +08:00
2004-01-19 08:39:29 +08:00
return ( zend_hash_find ( & module_registry , module_name , strlen ( module_name ) + 1 , ( void * * ) & module ) = = SUCCESS & & module - > module_started ) ? SUCCESS : FAILURE ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2004-01-19 08:39:29 +08:00
2011-03-31 19:59:34 +08:00
static int clean_module_class ( const zend_class_entry * * ce , int * module_number TSRMLS_DC ) /* { { { */
{
2011-04-01 07:58:06 +08:00
if ( ( * ce ) - > type = = ZEND_INTERNAL_CLASS & & ( * ce ) - > info . internal . module - > module_number = = * module_number ) {
2011-03-31 19:59:34 +08:00
return ZEND_HASH_APPLY_REMOVE ;
} else {
return ZEND_HASH_APPLY_KEEP ;
}
}
/* }}} */
static void clean_module_classes ( int module_number TSRMLS_DC ) /* { { { */
{
zend_hash_apply_with_argument ( EG ( class_table ) , ( apply_func_arg_t ) clean_module_class , ( void * ) & module_number TSRMLS_CC ) ;
}
/* }}} */
2007-11-03 03:40:39 +08:00
void module_destructor ( zend_module_entry * module ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2001-07-30 09:48:22 +08:00
TSRMLS_FETCH ( ) ;
1999-04-08 02:10:10 +08:00
if ( module - > type = = MODULE_TEMPORARY ) {
2001-07-31 12:53:54 +08:00
zend_clean_module_rsrc_dtors ( module - > module_number TSRMLS_CC ) ;
2001-07-30 15:43:02 +08:00
clean_module_constants ( module - > module_number TSRMLS_CC ) ;
2011-03-31 19:59:34 +08:00
clean_module_classes ( module - > module_number TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
if ( module - > module_started & & module - > module_shutdown_func ) {
#if 0
2007-11-03 03:40:39 +08:00
zend_printf ( " %s: Module shutdown \n " , module - > name ) ;
1999-04-08 02:10:10 +08:00
# endif
2001-07-30 14:12:15 +08:00
module - > module_shutdown_func ( module - > type , module - > module_number TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
2006-06-15 22:03:21 +08:00
/* Deinitilaise module globals */
if ( module - > globals_size ) {
# ifdef ZTS
ts_free_id ( * module - > globals_id_ptr ) ;
# else
if ( module - > globals_dtor ) {
module - > globals_dtor ( module - > globals_ptr TSRMLS_CC ) ;
}
# endif
}
1999-04-08 02:10:10 +08:00
module - > module_started = 0 ;
1999-05-09 20:24:21 +08:00
if ( module - > functions ) {
2001-07-30 09:48:22 +08:00
zend_unregister_functions ( module - > functions , - 1 , NULL TSRMLS_CC ) ;
1999-05-09 20:24:21 +08:00
}
1999-04-08 02:10:10 +08:00
2009-08-06 09:33:54 +08:00
# if HAVE_LIBDL
2004-09-24 23:40:22 +08:00
# if !(defined(NETWARE) && defined(APACHE_1_BUILD))
2011-07-14 20:21:15 +08:00
if ( module - > handle & & ! getenv ( " ZEND_DONT_UNLOAD_MODULES " ) ) {
2009-11-30 20:27:18 +08:00
DL_UNLOAD ( module - > handle ) ;
2006-05-10 07:53:23 +08:00
}
2004-09-22 22:31:21 +08:00
# endif
1999-04-08 02:10:10 +08:00
# endif
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2010-07-06 19:40:17 +08:00
void zend_activate_modules ( TSRMLS_D ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2010-07-06 19:40:17 +08:00
zend_module_entry * * p = module_request_startup_handlers ;
while ( * p ) {
zend_module_entry * module = * p ;
2001-07-27 18:10:39 +08:00
if ( module - > request_startup_func ( module - > type , module - > module_number TSRMLS_CC ) = = FAILURE ) {
1999-11-26 21:53:18 +08:00
zend_error ( E_WARNING , " request_startup() for %s module failed " , module - > name ) ;
exit ( 1 ) ;
}
2010-07-06 19:40:17 +08:00
p + + ;
1999-04-08 02:10:10 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2005-03-16 07:46:29 +08:00
/* call request shutdown for all modules */
2007-11-03 03:40:39 +08:00
int module_registry_cleanup ( zend_module_entry * module TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2005-03-16 07:46:29 +08:00
if ( module - > request_shutdown_func ) {
2000-04-25 00:04:13 +08:00
#if 0
2007-11-03 03:40:39 +08:00
zend_printf ( " %s: Request shutdown \n " , module - > name ) ;
2000-04-25 00:04:13 +08:00
# endif
2005-03-16 07:46:29 +08:00
module - > request_shutdown_func ( module - > type , module - > module_number TSRMLS_CC ) ;
}
return 0 ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-03-16 07:46:29 +08:00
2010-07-06 19:40:17 +08:00
void zend_deactivate_modules ( TSRMLS_D ) /* { { { */
{
EG ( opline_ptr ) = NULL ; /* we're no longer executing anything */
zend_try {
if ( EG ( full_tables_cleanup ) ) {
zend_hash_reverse_apply ( & module_registry , ( apply_func_t ) module_registry_cleanup TSRMLS_CC ) ;
} else {
zend_module_entry * * p = module_request_shutdown_handlers ;
while ( * p ) {
zend_module_entry * module = * p ;
module - > request_shutdown_func ( module - > type , module - > module_number TSRMLS_CC ) ;
p + + ;
}
}
} zend_end_try ( ) ;
}
/* }}} */
ZEND_API void zend_cleanup_internal_classes ( TSRMLS_D ) /* { { { */
{
zend_class_entry * * p = class_cleanup_handlers ;
while ( * p ) {
zend_cleanup_internal_class_data ( * p TSRMLS_CC ) ;
p + + ;
}
}
/* }}} */
2008-08-13 01:20:25 +08:00
int module_registry_unload_temp ( const zend_module_entry * module TSRMLS_DC ) /* { { { */
2005-03-16 07:46:29 +08:00
{
2006-03-17 16:34:16 +08:00
return ( module - > type = = MODULE_TEMPORARY ) ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_STOP ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2010-07-06 19:40:17 +08:00
static int exec_done_cb ( zend_module_entry * module TSRMLS_DC ) /* { { { */
{
if ( module - > post_deactivate_func ) {
module - > post_deactivate_func ( ) ;
}
return 0 ;
}
/* }}} */
void zend_post_deactivate_modules ( TSRMLS_D ) /* { { { */
{
if ( EG ( full_tables_cleanup ) ) {
zend_hash_apply ( & module_registry , ( apply_func_t ) exec_done_cb TSRMLS_CC ) ;
zend_hash_reverse_apply ( & module_registry , ( apply_func_t ) module_registry_unload_temp TSRMLS_CC ) ;
} else {
zend_module_entry * * p = module_post_deactivate_handlers ;
while ( * p ) {
zend_module_entry * module = * p ;
module - > post_deactivate_func ( ) ;
p + + ;
}
}
}
/* }}} */
1999-04-08 02:10:10 +08:00
/* return the next free module number */
2007-11-03 03:40:39 +08:00
int zend_next_free_module ( void ) /* { { { */
1999-04-08 02:10:10 +08:00
{
return + + module_count ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
static zend_class_entry * do_register_internal_class ( zend_class_entry * orig_class_entry , zend_uint ce_flags TSRMLS_DC ) /* { { { */
2003-10-23 03:59:58 +08:00
{
zend_class_entry * class_entry = malloc ( sizeof ( zend_class_entry ) ) ;
2010-04-20 19:05:54 +08:00
char * lowercase_name = emalloc ( orig_class_entry - > name_length + 1 ) ;
2003-10-23 03:59:58 +08:00
* class_entry = * orig_class_entry ;
class_entry - > type = ZEND_INTERNAL_CLASS ;
zend_initialize_class_data ( class_entry , 0 TSRMLS_CC ) ;
class_entry - > ce_flags = ce_flags ;
2010-09-15 15:38:52 +08:00
class_entry - > info . internal . module = EG ( current_module ) ;
2003-10-23 03:59:58 +08:00
2010-09-15 15:38:52 +08:00
if ( class_entry - > info . internal . builtin_functions ) {
zend_register_functions ( class_entry , class_entry - > info . internal . builtin_functions , & class_entry - > function_table , MODULE_PERSISTENT TSRMLS_CC ) ;
2003-10-23 03:59:58 +08:00
}
zend_str_tolower_copy ( lowercase_name , orig_class_entry - > name , class_entry - > name_length ) ;
2011-09-13 21:29:35 +08:00
lowercase_name = ( char * ) zend_new_interned_string ( lowercase_name , class_entry - > name_length + 1 , 1 TSRMLS_CC ) ;
2011-07-10 20:37:42 +08:00
if ( IS_INTERNED ( lowercase_name ) ) {
zend_hash_quick_update ( CG ( class_table ) , lowercase_name , class_entry - > name_length + 1 , INTERNED_HASH ( lowercase_name ) , & class_entry , sizeof ( zend_class_entry * ) , NULL ) ;
} else {
zend_hash_update ( CG ( class_table ) , lowercase_name , class_entry - > name_length + 1 , & class_entry , sizeof ( zend_class_entry * ) , NULL ) ;
}
2010-04-20 19:05:54 +08:00
str_efree ( lowercase_name ) ;
2003-10-23 03:59:58 +08:00
return class_entry ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-10-23 03:59:58 +08:00
2000-06-09 22:40:14 +08:00
/* If parent_ce is not NULL then it inherits from parent_ce
* If parent_ce is NULL and parent_name isn ' t then it looks for the parent and inherits from it
* If both parent_ce and parent_name are NULL it does a regular class registration
* If parent_name is specified but not found NULL is returned
*/
2007-11-03 03:40:39 +08:00
ZEND_API zend_class_entry * zend_register_internal_class_ex ( zend_class_entry * class_entry , zend_class_entry * parent_ce , char * parent_name TSRMLS_DC ) /* { { { */
2000-06-09 22:40:14 +08:00
{
zend_class_entry * register_class ;
if ( ! parent_ce & & parent_name ) {
2002-03-12 18:08:47 +08:00
zend_class_entry * * pce ;
if ( zend_hash_find ( CG ( class_table ) , parent_name , strlen ( parent_name ) + 1 , ( void * * ) & pce ) = = FAILURE ) {
return NULL ;
} else {
parent_ce = * pce ;
}
2000-06-09 22:40:14 +08:00
}
2001-07-30 09:48:22 +08:00
register_class = zend_register_internal_class ( class_entry TSRMLS_CC ) ;
2000-06-09 22:40:14 +08:00
if ( parent_ce ) {
2003-10-23 03:59:58 +08:00
zend_do_inheritance ( register_class , parent_ce TSRMLS_CC ) ;
2000-06-09 22:40:14 +08:00
}
return register_class ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-04-08 02:10:10 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_class_implements ( zend_class_entry * class_entry TSRMLS_DC , int num_interfaces , . . . ) /* { { { */
2003-10-15 14:24:17 +08:00
{
zend_class_entry * interface_entry ;
va_list interface_list ;
2005-02-18 04:15:40 +08:00
va_start ( interface_list , num_interfaces ) ;
2003-10-15 14:24:17 +08:00
while ( num_interfaces - - ) {
interface_entry = va_arg ( interface_list , zend_class_entry * ) ;
2006-06-07 17:21:06 +08:00
zend_do_implement_interface ( class_entry , interface_entry TSRMLS_CC ) ;
2003-10-15 14:24:17 +08:00
}
2007-11-03 03:40:39 +08:00
2003-10-15 14:24:17 +08:00
va_end ( interface_list ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-10-15 14:24:17 +08:00
2003-10-23 03:59:58 +08:00
/* A class that contains at least one abstract method automatically becomes an abstract class.
*/
2007-11-03 03:40:39 +08:00
ZEND_API zend_class_entry * zend_register_internal_class ( zend_class_entry * orig_class_entry TSRMLS_DC ) /* { { { */
1999-04-08 02:10:10 +08:00
{
2003-10-23 03:59:58 +08:00
return do_register_internal_class ( orig_class_entry , 0 TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-02-03 06:23:37 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API zend_class_entry * zend_register_internal_interface ( zend_class_entry * orig_class_entry TSRMLS_DC ) /* { { { */
2003-10-23 03:59:58 +08:00
{
2004-03-10 00:38:37 +08:00
return do_register_internal_class ( orig_class_entry , ZEND_ACC_INTERFACE TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
1999-05-09 20:24:21 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_register_class_alias_ex ( const char * name , int name_len , zend_class_entry * ce TSRMLS_DC ) /* { { { */
2008-05-12 15:11:55 +08:00
{
char * lcname = zend_str_tolower_dup ( name , name_len ) ;
int ret ;
ret = zend_hash_add ( CG ( class_table ) , lcname , name_len + 1 , & ce , sizeof ( zend_class_entry * ) , NULL ) ;
efree ( lcname ) ;
if ( ret = = SUCCESS ) {
ce - > refcount + + ;
}
return ret ;
}
/* }}} */
2008-08-13 01:20:25 +08:00
ZEND_API int zend_set_hash_symbol ( zval * symbol , const char * name , int name_length , zend_bool is_ref , int num_symbol_tables , . . . ) /* { { { */
1999-12-05 00:50:18 +08:00
{
2007-11-03 03:40:39 +08:00
HashTable * symbol_table ;
va_list symbol_table_list ;
1999-12-05 00:50:18 +08:00
2006-05-10 07:53:23 +08:00
if ( num_symbol_tables < = 0 ) return FAILURE ;
1999-12-05 00:50:18 +08:00
2007-10-07 13:22:07 +08:00
Z_SET_ISREF_TO_P ( symbol , is_ref ) ;
1999-12-05 00:50:18 +08:00
2006-05-10 07:53:23 +08:00
va_start ( symbol_table_list , num_symbol_tables ) ;
while ( num_symbol_tables - - > 0 ) {
symbol_table = va_arg ( symbol_table_list , HashTable * ) ;
zend_hash_update ( symbol_table , name , name_length + 1 , & symbol , sizeof ( zval * ) , NULL ) ;
zval_add_ref ( & symbol ) ;
}
va_end ( symbol_table_list ) ;
return SUCCESS ;
1999-12-05 00:50:18 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-05-30 01:16:52 +08:00
/* Disabled functions support */
2007-11-03 03:40:39 +08:00
/* {{{ proto void display_disabled_function(void)
Dummy function which displays an error when a disabled function is called . */
2002-09-16 09:36:48 +08:00
ZEND_API ZEND_FUNCTION ( display_disabled_function )
2000-05-30 01:16:52 +08:00
{
2001-07-30 15:43:02 +08:00
zend_error ( E_WARNING , " %s() has been disabled for security reasons " , get_active_function_name ( TSRMLS_C ) ) ;
2000-05-30 01:16:52 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2000-05-30 01:16:52 +08:00
2007-11-03 03:40:39 +08:00
static zend_function_entry disabled_function [ ] = {
2000-05-30 01:16:52 +08:00
ZEND_FE ( display_disabled_function , NULL )
2011-08-06 09:22:27 +08:00
ZEND_FE_END
2000-05-30 01:16:52 +08:00
} ;
2007-11-03 03:40:39 +08:00
ZEND_API int zend_disable_function ( char * function_name , uint function_name_length TSRMLS_DC ) /* { { { */
2000-05-30 01:16:52 +08:00
{
if ( zend_hash_del ( CG ( function_table ) , function_name , function_name_length + 1 ) = = FAILURE ) {
return FAILURE ;
}
disabled_function [ 0 ] . fname = function_name ;
2002-11-24 04:44:12 +08:00
return zend_register_functions ( NULL , disabled_function , CG ( function_table ) , MODULE_PERSISTENT TSRMLS_CC ) ;
2000-06-06 10:47:43 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-02-01 13:01:26 +08:00
2007-11-03 03:40:39 +08:00
static zend_object_value display_disabled_class ( zend_class_entry * class_type TSRMLS_DC ) /* { { { */
2003-03-03 09:22:43 +08:00
{
zend_object_value retval ;
zend_object * intern ;
2003-03-26 14:32:53 +08:00
retval = zend_objects_new ( & intern , class_type TSRMLS_CC ) ;
2003-03-03 09:22:43 +08:00
zend_error ( E_WARNING , " %s() has been disabled for security reasons " , class_type - > name ) ;
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-03-03 09:22:43 +08:00
2007-11-03 03:40:39 +08:00
static const zend_function_entry disabled_class_new [ ] = {
2011-08-06 09:22:27 +08:00
ZEND_FE_END
2003-03-03 09:22:43 +08:00
} ;
2007-11-03 03:40:39 +08:00
ZEND_API int zend_disable_class ( char * class_name , uint class_name_length TSRMLS_DC ) /* { { { */
2003-03-03 09:22:43 +08:00
{
2006-12-21 07:01:31 +08:00
zend_class_entry disabled_class ;
2006-05-10 07:53:23 +08:00
2003-03-03 09:56:14 +08:00
zend_str_tolower ( class_name , class_name_length ) ;
2003-03-03 09:22:43 +08:00
if ( zend_hash_del ( CG ( class_table ) , class_name , class_name_length + 1 ) = = FAILURE ) {
return FAILURE ;
}
2007-11-03 03:40:39 +08:00
INIT_OVERLOADED_CLASS_ENTRY_EX ( disabled_class , class_name , class_name_length , disabled_class_new , NULL , NULL , NULL , NULL , NULL ) ;
2006-12-21 07:01:31 +08:00
disabled_class . create_object = display_disabled_class ;
disabled_class . name_length = class_name_length ;
zend_register_internal_class ( & disabled_class TSRMLS_CC ) ;
return SUCCESS ;
2003-03-03 09:22:43 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-03-03 09:22:43 +08:00
2009-11-30 19:39:53 +08:00
static int zend_is_callable_check_class ( const char * name , int name_len , zend_fcall_info_cache * fcc , int * strict_class , char * * error TSRMLS_DC ) /* { { { */
2001-02-01 13:01:26 +08:00
{
2008-07-24 17:42:18 +08:00
int ret = 0 ;
zend_class_entry * * pce ;
char * lcname = zend_str_tolower_dup ( name , name_len ) ;
2009-11-30 19:39:53 +08:00
* strict_class = 0 ;
2008-07-24 17:42:18 +08:00
if ( name_len = = sizeof ( " self " ) - 1 & &
! memcmp ( lcname , " self " , sizeof ( " self " ) - 1 ) ) {
if ( ! EG ( scope ) ) {
if ( error ) * error = estrdup ( " cannot access self:: when no class scope is active " ) ;
} else {
fcc - > called_scope = EG ( called_scope ) ;
fcc - > calling_scope = EG ( scope ) ;
2008-11-28 03:01:23 +08:00
if ( ! fcc - > object_ptr ) {
fcc - > object_ptr = EG ( This ) ;
2008-07-26 21:14:04 +08:00
}
2008-07-24 17:42:18 +08:00
ret = 1 ;
}
} else if ( name_len = = sizeof ( " parent " ) - 1 & &
! memcmp ( lcname , " parent " , sizeof ( " parent " ) - 1 ) ) {
if ( ! EG ( scope ) ) {
if ( error ) * error = estrdup ( " cannot access parent:: when no class scope is active " ) ;
} else if ( ! EG ( scope ) - > parent ) {
if ( error ) * error = estrdup ( " cannot access parent:: when current class scope has no parent " ) ;
} else {
fcc - > called_scope = EG ( called_scope ) ;
fcc - > calling_scope = EG ( scope ) - > parent ;
2008-11-28 03:01:23 +08:00
if ( ! fcc - > object_ptr ) {
fcc - > object_ptr = EG ( This ) ;
2008-07-26 21:14:04 +08:00
}
2009-11-30 19:39:53 +08:00
* strict_class = 1 ;
2008-07-24 17:42:18 +08:00
ret = 1 ;
}
} else if ( name_len = = sizeof ( " static " ) - 1 & &
! memcmp ( lcname , " static " , sizeof ( " static " ) - 1 ) ) {
if ( ! EG ( called_scope ) ) {
if ( error ) * error = estrdup ( " cannot access static:: when no class scope is active " ) ;
} else {
fcc - > called_scope = EG ( called_scope ) ;
fcc - > calling_scope = EG ( called_scope ) ;
2008-11-28 03:01:23 +08:00
if ( ! fcc - > object_ptr ) {
fcc - > object_ptr = EG ( This ) ;
2008-07-26 21:14:04 +08:00
}
2009-11-30 19:39:53 +08:00
* strict_class = 1 ;
2008-07-24 17:42:18 +08:00
ret = 1 ;
}
2010-04-20 18:57:45 +08:00
} else if ( zend_lookup_class_ex ( name , name_len , NULL , 1 , & pce TSRMLS_CC ) = = SUCCESS ) {
2008-07-26 21:14:04 +08:00
zend_class_entry * scope = EG ( active_op_array ) ? EG ( active_op_array ) - > scope : NULL ;
fcc - > calling_scope = * pce ;
2008-11-28 03:01:23 +08:00
if ( scope & & ! fcc - > object_ptr & & EG ( This ) & &
2008-07-26 21:14:04 +08:00
instanceof_function ( Z_OBJCE_P ( EG ( This ) ) , scope TSRMLS_CC ) & &
instanceof_function ( scope , fcc - > calling_scope TSRMLS_CC ) ) {
2008-11-28 03:01:23 +08:00
fcc - > object_ptr = EG ( This ) ;
fcc - > called_scope = Z_OBJCE_P ( fcc - > object_ptr ) ;
2008-07-26 21:14:04 +08:00
} else {
2008-11-28 03:01:23 +08:00
fcc - > called_scope = fcc - > object_ptr ? Z_OBJCE_P ( fcc - > object_ptr ) : fcc - > calling_scope ;
2008-07-26 21:14:04 +08:00
}
2009-11-30 19:39:53 +08:00
* strict_class = 1 ;
2008-07-24 17:42:18 +08:00
ret = 1 ;
} else {
if ( error ) zend_spprintf ( error , 0 , " class '%.*s' not found " , name_len , name ) ;
}
efree ( lcname ) ;
return ret ;
}
/* }}} */
2009-11-30 19:39:53 +08:00
static int zend_is_callable_check_func ( int check_flags , zval * callable , zend_fcall_info_cache * fcc , int strict_class , char * * error TSRMLS_DC ) /* { { { */
2008-07-24 17:42:18 +08:00
{
zend_class_entry * ce_org = fcc - > calling_scope ;
2008-07-26 21:14:04 +08:00
int retval = 0 ;
2010-10-15 05:33:10 +08:00
char * mname , * lmname ;
const char * colon ;
2005-12-17 06:15:41 +08:00
int clen , mlen ;
2008-02-10 05:22:31 +08:00
zend_class_entry * last_scope ;
2005-12-17 06:15:41 +08:00
HashTable * ftable ;
2008-07-24 17:42:18 +08:00
int call_via_handler = 0 ;
2006-05-10 07:53:23 +08:00
2008-02-03 06:29:41 +08:00
if ( error ) {
* error = NULL ;
}
2008-07-24 17:42:18 +08:00
fcc - > calling_scope = NULL ;
fcc - > function_handler = NULL ;
2005-12-17 06:15:41 +08:00
2007-09-29 03:52:53 +08:00
if ( ! ce_org ) {
2008-11-04 23:58:55 +08:00
/* Skip leading \ */
if ( Z_STRVAL_P ( callable ) [ 0 ] = = ' \\ ' ) {
mlen = Z_STRLEN_P ( callable ) - 1 ;
mname = Z_STRVAL_P ( callable ) + 1 ;
lmname = zend_str_tolower_dup ( Z_STRVAL_P ( callable ) + 1 , mlen ) ;
2007-09-29 03:52:53 +08:00
} else {
mlen = Z_STRLEN_P ( callable ) ;
2008-07-26 21:14:04 +08:00
mname = Z_STRVAL_P ( callable ) ;
2007-09-29 03:52:53 +08:00
lmname = zend_str_tolower_dup ( Z_STRVAL_P ( callable ) , mlen ) ;
}
/* Check if function with given name exists.
2007-11-03 03:40:39 +08:00
* This may be a compound name that includes namespace name */
2008-07-24 17:42:18 +08:00
if ( zend_hash_find ( EG ( function_table ) , lmname , mlen + 1 , ( void * * ) & fcc - > function_handler ) = = SUCCESS ) {
2007-09-29 03:52:53 +08:00
efree ( lmname ) ;
return 1 ;
}
efree ( lmname ) ;
}
/* Split name into class/namespace and method/function names */
if ( ( colon = zend_memrchr ( Z_STRVAL_P ( callable ) , ' : ' , Z_STRLEN_P ( callable ) ) ) ! = NULL & &
2007-11-03 03:40:39 +08:00
colon > Z_STRVAL_P ( callable ) & &
* ( colon - 1 ) = = ' : '
) {
2007-09-29 03:52:53 +08:00
colon - - ;
2005-12-17 06:15:41 +08:00
clen = colon - Z_STRVAL_P ( callable ) ;
mlen = Z_STRLEN_P ( callable ) - clen - 2 ;
2007-12-21 09:21:52 +08:00
2007-12-25 18:58:30 +08:00
if ( colon = = Z_STRVAL_P ( callable ) ) {
2008-02-02 05:27:55 +08:00
if ( error ) zend_spprintf ( error , 0 , " invalid function name " ) ;
2007-12-25 18:58:30 +08:00
return 0 ;
}
2007-09-29 03:52:53 +08:00
/* This is a compound name.
2007-11-03 03:40:39 +08:00
* Try to fetch class and then find static method . */
2008-02-10 05:22:31 +08:00
last_scope = EG ( scope ) ;
2008-02-07 04:40:19 +08:00
if ( ce_org ) {
EG ( scope ) = ce_org ;
}
2008-07-24 17:42:18 +08:00
2009-11-30 19:39:53 +08:00
if ( ! zend_is_callable_check_class ( Z_STRVAL_P ( callable ) , clen , fcc , & strict_class , error TSRMLS_CC ) ) {
2008-07-24 17:42:18 +08:00
EG ( scope ) = last_scope ;
2005-12-17 06:15:41 +08:00
return 0 ;
}
2008-07-24 17:42:18 +08:00
EG ( scope ) = last_scope ;
ftable = & fcc - > calling_scope - > function_table ;
if ( ce_org & & ! instanceof_function ( ce_org , fcc - > calling_scope TSRMLS_CC ) ) {
if ( error ) zend_spprintf ( error , 0 , " class '%s' is not a subclass of '%s' " , ce_org - > name , fcc - > calling_scope - > name ) ;
2005-12-17 06:15:41 +08:00
return 0 ;
}
2008-07-26 21:14:04 +08:00
mname = Z_STRVAL_P ( callable ) + clen + 2 ;
2007-09-29 03:52:53 +08:00
} else if ( ce_org ) {
/* Try to fetch find static method of given class. */
2005-12-17 06:15:41 +08:00
mlen = Z_STRLEN_P ( callable ) ;
2008-07-26 21:14:04 +08:00
mname = Z_STRVAL_P ( callable ) ;
2007-09-29 03:52:53 +08:00
ftable = & ce_org - > function_table ;
2008-07-24 17:42:18 +08:00
fcc - > calling_scope = ce_org ;
2007-09-29 03:52:53 +08:00
} else {
/* We already checked for plain function before. */
2008-07-26 21:14:04 +08:00
if ( error & & ! ( check_flags & IS_CALLABLE_CHECK_SILENT ) ) {
zend_spprintf ( error , 0 , " function '%s' not found or invalid function name " , Z_STRVAL_P ( callable ) ) ;
}
2007-09-29 03:52:53 +08:00
return 0 ;
2005-12-17 06:15:41 +08:00
}
2008-07-26 21:14:04 +08:00
lmname = zend_str_tolower_dup ( mname , mlen ) ;
2009-11-30 19:39:53 +08:00
if ( strict_class & &
fcc - > calling_scope & &
mlen = = sizeof ( ZEND_CONSTRUCTOR_FUNC_NAME ) - 1 & &
! memcmp ( lmname , ZEND_CONSTRUCTOR_FUNC_NAME , sizeof ( ZEND_CONSTRUCTOR_FUNC_NAME ) ) ) {
fcc - > function_handler = fcc - > calling_scope - > constructor ;
if ( fcc - > function_handler ) {
retval = 1 ;
}
} else if ( zend_hash_find ( ftable , lmname , mlen + 1 , ( void * * ) & fcc - > function_handler ) = = SUCCESS ) {
2008-07-26 21:14:04 +08:00
retval = 1 ;
2008-10-10 23:19:35 +08:00
if ( ( fcc - > function_handler - > op_array . fn_flags & ZEND_ACC_CHANGED ) & &
EG ( scope ) & &
instanceof_function ( fcc - > function_handler - > common . scope , EG ( scope ) TSRMLS_CC ) ) {
zend_function * priv_fbc ;
if ( zend_hash_find ( & EG ( scope ) - > function_table , lmname , mlen + 1 , ( void * * ) & priv_fbc ) = = SUCCESS
& & priv_fbc - > common . fn_flags & ZEND_ACC_PRIVATE
& & priv_fbc - > common . scope = = EG ( scope ) ) {
fcc - > function_handler = priv_fbc ;
}
}
2009-01-14 19:56:08 +08:00
if ( ( check_flags & IS_CALLABLE_CHECK_NO_ACCESS ) = = 0 & &
( fcc - > calling_scope & &
( fcc - > calling_scope - > __call | |
fcc - > calling_scope - > __callstatic ) ) ) {
if ( fcc - > function_handler - > op_array . fn_flags & ZEND_ACC_PRIVATE ) {
if ( ! zend_check_private ( fcc - > function_handler , fcc - > object_ptr ? Z_OBJCE_P ( fcc - > object_ptr ) : EG ( scope ) , lmname , mlen TSRMLS_CC ) ) {
retval = 0 ;
fcc - > function_handler = NULL ;
goto get_function_via_handler ;
}
} else if ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_PROTECTED ) {
if ( ! zend_check_protected ( fcc - > function_handler - > common . scope , EG ( scope ) ) ) {
retval = 0 ;
fcc - > function_handler = NULL ;
goto get_function_via_handler ;
}
}
}
} else {
get_function_via_handler :
2009-07-15 09:11:24 +08:00
if ( fcc - > object_ptr & & fcc - > calling_scope = = ce_org ) {
2009-11-30 19:39:53 +08:00
if ( strict_class & & ce_org - > __call ) {
fcc - > function_handler = emalloc ( sizeof ( zend_internal_function ) ) ;
fcc - > function_handler - > internal_function . type = ZEND_INTERNAL_FUNCTION ;
2010-09-15 15:38:52 +08:00
fcc - > function_handler - > internal_function . module = ( ce_org - > type = = ZEND_INTERNAL_CLASS ) ? ce_org - > info . internal . module : NULL ;
2009-11-30 19:39:53 +08:00
fcc - > function_handler - > internal_function . handler = zend_std_call_user_call ;
fcc - > function_handler - > internal_function . arg_info = NULL ;
fcc - > function_handler - > internal_function . num_args = 0 ;
fcc - > function_handler - > internal_function . scope = ce_org ;
fcc - > function_handler - > internal_function . fn_flags = ZEND_ACC_CALL_VIA_HANDLER ;
fcc - > function_handler - > internal_function . function_name = estrndup ( mname , mlen ) ;
call_via_handler = 1 ;
retval = 1 ;
} else if ( Z_OBJ_HT_P ( fcc - > object_ptr ) - > get_method ) {
2010-04-20 18:57:45 +08:00
fcc - > function_handler = Z_OBJ_HT_P ( fcc - > object_ptr ) - > get_method ( & fcc - > object_ptr , mname , mlen , NULL TSRMLS_CC ) ;
2009-01-14 19:56:08 +08:00
if ( fcc - > function_handler ) {
2009-11-30 19:39:53 +08:00
if ( strict_class & &
( ! fcc - > function_handler - > common . scope | |
! instanceof_function ( ce_org , fcc - > function_handler - > common . scope TSRMLS_CC ) ) ) {
if ( ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ! = 0 ) {
if ( fcc - > function_handler - > type ! = ZEND_OVERLOADED_FUNCTION ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) fcc - > function_handler - > common . function_name ) ;
2009-11-30 19:39:53 +08:00
}
efree ( fcc - > function_handler ) ;
}
} else {
retval = 1 ;
call_via_handler = ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ! = 0 ;
}
2009-01-14 19:56:08 +08:00
}
}
} else if ( fcc - > calling_scope ) {
if ( fcc - > calling_scope - > get_static_method ) {
fcc - > function_handler = fcc - > calling_scope - > get_static_method ( fcc - > calling_scope , mname , mlen TSRMLS_CC ) ;
} else {
2010-04-20 18:57:45 +08:00
fcc - > function_handler = zend_std_get_static_method ( fcc - > calling_scope , mname , mlen , NULL TSRMLS_CC ) ;
2009-01-14 19:56:08 +08:00
}
if ( fcc - > function_handler ) {
retval = 1 ;
call_via_handler = ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ! = 0 ;
2011-05-31 19:36:57 +08:00
if ( call_via_handler & & ! fcc - > object_ptr & & EG ( This ) & &
Z_OBJ_HT_P ( EG ( This ) ) - > get_class_entry & &
instanceof_function ( Z_OBJCE_P ( EG ( This ) ) , fcc - > calling_scope TSRMLS_CC ) ) {
fcc - > object_ptr = EG ( This ) ;
}
2009-01-14 19:56:08 +08:00
}
2005-12-17 06:15:41 +08:00
}
2008-07-26 21:14:04 +08:00
}
if ( retval ) {
if ( fcc - > calling_scope & & ! call_via_handler ) {
2008-11-28 03:01:23 +08:00
if ( ! fcc - > object_ptr & & ! ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_STATIC ) ) {
2008-02-02 21:56:59 +08:00
int severity ;
char * verb ;
2008-07-24 17:42:18 +08:00
if ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
2008-02-02 21:56:59 +08:00
severity = E_STRICT ;
verb = " should not " ;
} else {
2008-02-02 23:48:04 +08:00
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
2008-02-02 21:56:59 +08:00
severity = E_ERROR ;
verb = " cannot " ;
}
2005-12-17 06:15:41 +08:00
if ( ( check_flags & IS_CALLABLE_CHECK_IS_STATIC ) ! = 0 ) {
retval = 0 ;
2008-02-02 05:27:55 +08:00
}
2008-07-24 17:42:18 +08:00
if ( EG ( This ) & & instanceof_function ( Z_OBJCE_P ( EG ( This ) ) , fcc - > calling_scope TSRMLS_CC ) ) {
2008-11-28 03:01:23 +08:00
fcc - > object_ptr = EG ( This ) ;
2008-02-02 05:27:55 +08:00
if ( error ) {
2008-07-24 17:42:18 +08:00
zend_spprintf ( error , 0 , " non-static method %s::%s() %s be called statically, assuming $this from compatible context %s " , fcc - > calling_scope - > name , fcc - > function_handler - > common . function_name , verb , Z_OBJCE_P ( EG ( This ) ) - > name ) ;
2009-04-02 17:56:33 +08:00
if ( severity = = E_ERROR ) {
retval = 0 ;
}
2008-02-02 05:27:55 +08:00
} else if ( retval ) {
2008-07-24 17:42:18 +08:00
zend_error ( severity , " Non-static method %s::%s() %s be called statically, assuming $this from compatible context %s " , fcc - > calling_scope - > name , fcc - > function_handler - > common . function_name , verb , Z_OBJCE_P ( EG ( This ) ) - > name ) ;
2008-02-02 05:27:55 +08:00
}
} else {
if ( error ) {
2008-07-24 17:42:18 +08:00
zend_spprintf ( error , 0 , " non-static method %s::%s() %s be called statically " , fcc - > calling_scope - > name , fcc - > function_handler - > common . function_name , verb ) ;
2009-04-02 17:56:33 +08:00
if ( severity = = E_ERROR ) {
retval = 0 ;
}
2008-02-02 05:27:55 +08:00
} else if ( retval ) {
2008-07-24 17:42:18 +08:00
zend_error ( severity , " Non-static method %s::%s() %s be called statically " , fcc - > calling_scope - > name , fcc - > function_handler - > common . function_name , verb ) ;
2006-01-14 23:22:40 +08:00
}
2005-12-17 06:15:41 +08:00
}
}
if ( retval & & ( check_flags & IS_CALLABLE_CHECK_NO_ACCESS ) = = 0 ) {
2008-07-24 17:42:18 +08:00
if ( fcc - > function_handler - > op_array . fn_flags & ZEND_ACC_PRIVATE ) {
2008-11-28 03:01:23 +08:00
if ( ! zend_check_private ( fcc - > function_handler , fcc - > object_ptr ? Z_OBJCE_P ( fcc - > object_ptr ) : EG ( scope ) , lmname , mlen TSRMLS_CC ) ) {
2008-02-03 06:29:41 +08:00
if ( error ) {
if ( * error ) {
efree ( * error ) ;
}
2008-07-24 17:42:18 +08:00
zend_spprintf ( error , 0 , " cannot access private method %s::%s() " , fcc - > calling_scope - > name , fcc - > function_handler - > common . function_name ) ;
2008-02-03 06:29:41 +08:00
}
2005-12-17 06:15:41 +08:00
retval = 0 ;
}
2008-07-24 17:42:18 +08:00
} else if ( ( fcc - > function_handler - > common . fn_flags & ZEND_ACC_PROTECTED ) ) {
if ( ! zend_check_protected ( fcc - > function_handler - > common . scope , EG ( scope ) ) ) {
2008-02-03 06:29:41 +08:00
if ( error ) {
if ( * error ) {
efree ( * error ) ;
}
2008-07-24 17:42:18 +08:00
zend_spprintf ( error , 0 , " cannot access protected method %s::%s() " , fcc - > calling_scope - > name , fcc - > function_handler - > common . function_name ) ;
2008-02-03 06:29:41 +08:00
}
2005-12-17 06:15:41 +08:00
retval = 0 ;
}
}
}
}
2008-07-26 21:14:04 +08:00
} else if ( error & & ! ( check_flags & IS_CALLABLE_CHECK_SILENT ) ) {
if ( fcc - > calling_scope ) {
if ( error ) zend_spprintf ( error , 0 , " class '%s' does not have a method '%s' " , fcc - > calling_scope - > name , mname ) ;
} else {
if ( error ) zend_spprintf ( error , 0 , " function '%s' does not exist " , mname ) ;
}
2005-12-17 06:15:41 +08:00
}
2008-08-07 20:04:14 +08:00
efree ( lmname ) ;
2008-11-28 03:01:23 +08:00
if ( fcc - > object_ptr ) {
fcc - > called_scope = Z_OBJCE_P ( fcc - > object_ptr ) ;
2008-07-24 17:42:18 +08:00
}
2008-07-26 21:14:04 +08:00
if ( retval ) {
2008-07-24 17:42:18 +08:00
fcc - > initialized = 1 ;
}
2005-12-17 06:15:41 +08:00
return retval ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-12-17 06:15:41 +08:00
2008-11-28 03:01:23 +08:00
ZEND_API zend_bool zend_is_callable_ex ( zval * callable , zval * object_ptr , uint check_flags , char * * callable_name , int * callable_name_len , zend_fcall_info_cache * fcc , char * * error TSRMLS_DC ) /* { { { */
2005-12-17 06:15:41 +08:00
{
2008-07-26 21:14:04 +08:00
zend_bool ret ;
2005-12-17 06:15:41 +08:00
int callable_name_len_local ;
2008-07-24 17:42:18 +08:00
zend_fcall_info_cache fcc_local ;
2005-07-29 04:55:50 +08:00
2006-03-23 21:14:55 +08:00
if ( callable_name ) {
* callable_name = NULL ;
}
2005-07-29 04:55:50 +08:00
if ( callable_name_len = = NULL ) {
callable_name_len = & callable_name_len_local ;
}
2008-07-24 17:42:18 +08:00
if ( fcc = = NULL ) {
fcc = & fcc_local ;
2005-07-29 04:55:50 +08:00
}
2008-02-02 05:27:55 +08:00
if ( error ) {
* error = NULL ;
}
2008-07-24 17:42:18 +08:00
fcc - > initialized = 0 ;
fcc - > calling_scope = NULL ;
fcc - > called_scope = NULL ;
fcc - > function_handler = NULL ;
fcc - > calling_scope = NULL ;
2008-11-28 03:01:23 +08:00
fcc - > object_ptr = NULL ;
2001-02-01 13:01:26 +08:00
2008-11-28 03:01:23 +08:00
if ( object_ptr & & Z_TYPE_P ( object_ptr ) ! = IS_OBJECT ) {
object_ptr = NULL ;
2008-07-27 02:32:20 +08:00
}
2008-11-28 03:01:23 +08:00
if ( object_ptr & &
2008-07-27 02:32:20 +08:00
( ! EG ( objects_store ) . object_buckets | |
2008-11-28 03:01:23 +08:00
! EG ( objects_store ) . object_buckets [ Z_OBJ_HANDLE_P ( object_ptr ) ] . valid ) ) {
2008-07-27 02:32:20 +08:00
return 0 ;
}
2001-03-12 11:08:28 +08:00
switch ( Z_TYPE_P ( callable ) ) {
2001-02-01 13:01:26 +08:00
case IS_STRING :
2008-11-28 03:01:23 +08:00
if ( object_ptr ) {
fcc - > object_ptr = object_ptr ;
fcc - > calling_scope = Z_OBJCE_P ( object_ptr ) ;
2008-07-26 21:14:04 +08:00
if ( callable_name ) {
char * ptr ;
* callable_name_len = fcc - > calling_scope - > name_length + Z_STRLEN_P ( callable ) + sizeof ( " :: " ) - 1 ;
ptr = * callable_name = emalloc ( * callable_name_len + 1 ) ;
memcpy ( ptr , fcc - > calling_scope - > name , fcc - > calling_scope - > name_length ) ;
ptr + = fcc - > calling_scope - > name_length ;
memcpy ( ptr , " :: " , sizeof ( " :: " ) - 1 ) ;
ptr + = sizeof ( " :: " ) - 1 ;
memcpy ( ptr , Z_STRVAL_P ( callable ) , Z_STRLEN_P ( callable ) + 1 ) ;
}
} else if ( callable_name ) {
2001-05-10 04:07:49 +08:00
* callable_name = estrndup ( Z_STRVAL_P ( callable ) , Z_STRLEN_P ( callable ) ) ;
2005-07-29 04:55:50 +08:00
* callable_name_len = Z_STRLEN_P ( callable ) ;
2003-12-29 00:20:06 +08:00
}
2005-04-27 23:45:36 +08:00
if ( check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY ) {
2008-07-26 21:14:04 +08:00
fcc - > called_scope = fcc - > calling_scope ;
2001-03-12 11:08:28 +08:00
return 1 ;
2003-12-29 00:20:06 +08:00
}
2007-11-03 03:40:39 +08:00
2009-11-30 19:39:53 +08:00
ret = zend_is_callable_check_func ( check_flags , callable , fcc , 0 , error TSRMLS_CC ) ;
2008-07-26 21:14:04 +08:00
if ( fcc = = & fcc_local & &
fcc - > function_handler & &
( ( fcc - > function_handler - > type = = ZEND_INTERNAL_FUNCTION & &
( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ) | |
fcc - > function_handler - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY | |
fcc - > function_handler - > type = = ZEND_OVERLOADED_FUNCTION ) ) {
if ( fcc - > function_handler - > type ! = ZEND_OVERLOADED_FUNCTION ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) fcc - > function_handler - > common . function_name ) ;
2008-07-26 21:14:04 +08:00
}
efree ( fcc - > function_handler ) ;
}
return ret ;
2001-02-01 13:01:26 +08:00
case IS_ARRAY :
{
2008-02-02 05:27:55 +08:00
zval * * method = NULL ;
zval * * obj = NULL ;
2009-11-30 19:39:53 +08:00
int strict_class = 0 ;
2006-05-10 07:53:23 +08:00
2008-02-02 05:27:55 +08:00
if ( zend_hash_num_elements ( Z_ARRVAL_P ( callable ) ) = = 2 ) {
zend_hash_index_find ( Z_ARRVAL_P ( callable ) , 0 , ( void * * ) & obj ) ;
zend_hash_index_find ( Z_ARRVAL_P ( callable ) , 1 , ( void * * ) & method ) ;
}
if ( obj & & method & &
2007-11-03 03:40:39 +08:00
( Z_TYPE_PP ( obj ) = = IS_OBJECT | |
Z_TYPE_PP ( obj ) = = IS_STRING ) & &
2001-02-01 13:01:26 +08:00
Z_TYPE_PP ( method ) = = IS_STRING ) {
2001-03-12 11:08:28 +08:00
if ( Z_TYPE_PP ( obj ) = = IS_STRING ) {
2001-05-10 04:07:49 +08:00
if ( callable_name ) {
char * ptr ;
2005-07-29 04:55:50 +08:00
* callable_name_len = Z_STRLEN_PP ( obj ) + Z_STRLEN_PP ( method ) + sizeof ( " :: " ) - 1 ;
ptr = * callable_name = emalloc ( * callable_name_len + 1 ) ;
2001-05-10 04:07:49 +08:00
memcpy ( ptr , Z_STRVAL_PP ( obj ) , Z_STRLEN_PP ( obj ) ) ;
ptr + = Z_STRLEN_PP ( obj ) ;
memcpy ( ptr , " :: " , sizeof ( " :: " ) - 1 ) ;
ptr + = sizeof ( " :: " ) - 1 ;
memcpy ( ptr , Z_STRVAL_PP ( method ) , Z_STRLEN_PP ( method ) + 1 ) ;
2005-10-13 17:48:38 +08:00
}
2001-05-10 04:07:49 +08:00
2005-10-26 07:19:59 +08:00
if ( check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY ) {
2001-05-10 04:07:49 +08:00
return 1 ;
2005-10-26 07:19:59 +08:00
}
2001-05-10 04:07:49 +08:00
2009-11-30 19:39:53 +08:00
if ( ! zend_is_callable_check_class ( Z_STRVAL_PP ( obj ) , Z_STRLEN_PP ( obj ) , fcc , & strict_class , error TSRMLS_CC ) ) {
2008-07-24 17:42:18 +08:00
return 0 ;
2002-03-12 18:08:47 +08:00
}
2008-07-24 17:42:18 +08:00
2001-03-13 00:27:26 +08:00
} else {
2008-07-27 02:32:20 +08:00
if ( ! EG ( objects_store ) . object_buckets | |
! EG ( objects_store ) . object_buckets [ Z_OBJ_HANDLE_PP ( obj ) ] . valid ) {
return 0 ;
}
2008-07-24 17:42:18 +08:00
fcc - > calling_scope = Z_OBJCE_PP ( obj ) ; /* TBFixed: what if it's overloaded? */
2006-05-10 07:53:23 +08:00
2008-11-28 03:01:23 +08:00
fcc - > object_ptr = * obj ;
2001-05-10 04:07:49 +08:00
if ( callable_name ) {
char * ptr ;
2008-07-24 17:42:18 +08:00
* callable_name_len = fcc - > calling_scope - > name_length + Z_STRLEN_PP ( method ) + sizeof ( " :: " ) - 1 ;
2005-07-29 04:55:50 +08:00
ptr = * callable_name = emalloc ( * callable_name_len + 1 ) ;
2008-07-24 17:42:18 +08:00
memcpy ( ptr , fcc - > calling_scope - > name , fcc - > calling_scope - > name_length ) ;
ptr + = fcc - > calling_scope - > name_length ;
2001-05-10 04:07:49 +08:00
memcpy ( ptr , " :: " , sizeof ( " :: " ) - 1 ) ;
ptr + = sizeof ( " :: " ) - 1 ;
memcpy ( ptr , Z_STRVAL_PP ( method ) , Z_STRLEN_PP ( method ) + 1 ) ;
}
2005-10-26 07:19:59 +08:00
if ( check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY ) {
2008-07-24 17:42:18 +08:00
fcc - > called_scope = fcc - > calling_scope ;
2001-05-10 04:07:49 +08:00
return 1 ;
2005-10-26 07:19:59 +08:00
}
2001-03-13 00:27:26 +08:00
}
2001-05-10 04:07:49 +08:00
2009-11-30 19:39:53 +08:00
ret = zend_is_callable_check_func ( check_flags , * method , fcc , strict_class , error TSRMLS_CC ) ;
2008-07-26 21:14:04 +08:00
if ( fcc = = & fcc_local & &
fcc - > function_handler & &
( ( fcc - > function_handler - > type = = ZEND_INTERNAL_FUNCTION & &
( fcc - > function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ) | |
fcc - > function_handler - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY | |
fcc - > function_handler - > type = = ZEND_OVERLOADED_FUNCTION ) ) {
if ( fcc - > function_handler - > type ! = ZEND_OVERLOADED_FUNCTION ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) fcc - > function_handler - > common . function_name ) ;
2008-07-26 21:14:04 +08:00
}
efree ( fcc - > function_handler ) ;
}
return ret ;
2008-02-02 05:27:55 +08:00
} else {
if ( zend_hash_num_elements ( Z_ARRVAL_P ( callable ) ) = = 2 ) {
2008-05-09 02:51:28 +08:00
if ( ! obj | | ( Z_TYPE_PP ( obj ) ! = IS_STRING & & Z_TYPE_PP ( obj ) ! = IS_OBJECT ) ) {
2008-02-02 05:27:55 +08:00
if ( error ) zend_spprintf ( error , 0 , " first array member is not a valid class name or object " ) ;
} else {
if ( error ) zend_spprintf ( error , 0 , " second array member is not a valid method " ) ;
}
} else {
if ( error ) zend_spprintf ( error , 0 , " array must have exactly two members " ) ;
}
if ( callable_name ) {
* callable_name = estrndup ( " Array " , sizeof ( " Array " ) - 1 ) ;
* callable_name_len = sizeof ( " Array " ) - 1 ;
2001-03-12 11:08:28 +08:00
}
2003-07-03 17:18:41 +08:00
}
2001-02-01 13:01:26 +08:00
}
2007-11-03 03:40:39 +08:00
return 0 ;
2001-02-01 13:01:26 +08:00
2008-07-14 17:49:03 +08:00
case IS_OBJECT :
2008-11-28 03:01:23 +08:00
if ( Z_OBJ_HANDLER_P ( callable , get_closure ) & & Z_OBJ_HANDLER_P ( callable , get_closure ) ( callable , & fcc - > calling_scope , & fcc - > function_handler , & fcc - > object_ptr TSRMLS_CC ) = = SUCCESS ) {
2008-07-24 17:42:18 +08:00
fcc - > called_scope = fcc - > calling_scope ;
2008-07-14 17:49:03 +08:00
if ( callable_name ) {
2008-07-14 20:18:23 +08:00
zend_class_entry * ce = Z_OBJCE_P ( callable ) ; /* TBFixed: what if it's overloaded? */
* callable_name_len = ce - > name_length + sizeof ( " ::__invoke " ) - 1 ;
* callable_name = emalloc ( * callable_name_len + 1 ) ;
memcpy ( * callable_name , ce - > name , ce - > name_length ) ;
memcpy ( ( * callable_name ) + ce - > name_length , " ::__invoke " , sizeof ( " ::__invoke " ) ) ;
2008-07-14 17:49:03 +08:00
}
return 1 ;
}
/* break missing intentionally */
2001-02-01 13:01:26 +08:00
default :
2001-03-12 11:08:28 +08:00
if ( callable_name ) {
zval expr_copy ;
int use_copy ;
zend_make_printable_zval ( callable , & expr_copy , & use_copy ) ;
* callable_name = estrndup ( Z_STRVAL ( expr_copy ) , Z_STRLEN ( expr_copy ) ) ;
2005-07-29 04:55:50 +08:00
* callable_name_len = Z_STRLEN ( expr_copy ) ;
2001-03-12 11:08:28 +08:00
zval_dtor ( & expr_copy ) ;
}
2008-02-02 05:27:55 +08:00
if ( error ) zend_spprintf ( error , 0 , " no array or string given " ) ;
2007-11-03 03:40:39 +08:00
return 0 ;
2001-02-01 13:01:26 +08:00
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2001-10-13 02:40:30 +08:00
2008-08-02 12:46:07 +08:00
ZEND_API zend_bool zend_is_callable ( zval * callable , uint check_flags , char * * callable_name TSRMLS_DC ) /* { { { */
2005-07-29 04:55:50 +08:00
{
2008-07-26 21:14:04 +08:00
return zend_is_callable_ex ( callable , NULL , check_flags , callable_name , NULL , NULL , NULL TSRMLS_CC ) ;
2005-07-29 04:55:50 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-07-29 04:55:50 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API zend_bool zend_make_callable ( zval * callable , char * * callable_name TSRMLS_DC ) /* { { { */
2003-10-26 06:58:06 +08:00
{
2008-07-24 17:42:18 +08:00
zend_fcall_info_cache fcc ;
2005-11-04 07:45:18 +08:00
2008-07-26 21:14:04 +08:00
if ( zend_is_callable_ex ( callable , NULL , IS_CALLABLE_STRICT , callable_name , NULL , & fcc , NULL TSRMLS_CC ) ) {
2008-07-24 17:42:18 +08:00
if ( Z_TYPE_P ( callable ) = = IS_STRING & & fcc . calling_scope ) {
2005-11-04 07:45:18 +08:00
zval_dtor ( callable ) ;
array_init ( callable ) ;
2008-07-24 17:42:18 +08:00
add_next_index_string ( callable , fcc . calling_scope - > name , 1 ) ;
add_next_index_string ( callable , fcc . function_handler - > common . function_name , 1 ) ;
2005-11-04 07:45:18 +08:00
}
2008-07-26 21:14:04 +08:00
if ( fcc . function_handler & &
( ( fcc . function_handler - > type = = ZEND_INTERNAL_FUNCTION & &
( fcc . function_handler - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) ) | |
fcc . function_handler - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY | |
fcc . function_handler - > type = = ZEND_OVERLOADED_FUNCTION ) ) {
if ( fcc . function_handler - > type ! = ZEND_OVERLOADED_FUNCTION ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) fcc . function_handler - > common . function_name ) ;
2008-07-26 21:14:04 +08:00
}
efree ( fcc . function_handler ) ;
}
2003-10-26 06:58:06 +08:00
return 1 ;
}
2005-11-04 07:45:18 +08:00
return 0 ;
2003-10-26 06:58:06 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-10-26 06:58:06 +08:00
2008-02-02 05:27:55 +08:00
ZEND_API int zend_fcall_info_init ( zval * callable , uint check_flags , zend_fcall_info * fci , zend_fcall_info_cache * fcc , char * * callable_name , char * * error TSRMLS_DC ) /* { { { */
2006-06-07 17:43:54 +08:00
{
2008-07-26 21:14:04 +08:00
if ( ! zend_is_callable_ex ( callable , NULL , check_flags , callable_name , NULL , fcc , error TSRMLS_CC ) ) {
2006-06-07 17:43:54 +08:00
return FAILURE ;
}
fci - > size = sizeof ( * fci ) ;
2008-07-24 17:42:18 +08:00
fci - > function_table = fcc - > calling_scope ? & fcc - > calling_scope - > function_table : EG ( function_table ) ;
2008-11-28 03:01:23 +08:00
fci - > object_ptr = fcc - > object_ptr ;
2007-05-01 03:54:41 +08:00
fci - > function_name = callable ;
2006-06-07 17:43:54 +08:00
fci - > retval_ptr_ptr = NULL ;
fci - > param_count = 0 ;
fci - > params = NULL ;
fci - > no_separation = 1 ;
fci - > symbol_table = NULL ;
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2006-06-07 17:43:54 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_fcall_info_args_clear ( zend_fcall_info * fci , int free_mem ) /* { { { */
2006-06-07 17:43:54 +08:00
{
if ( fci - > params ) {
2007-04-06 03:49:42 +08:00
if ( free_mem ) {
efree ( fci - > params ) ;
fci - > params = NULL ;
}
2006-06-07 17:43:54 +08:00
}
fci - > param_count = 0 ;
2007-04-06 03:49:42 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2007-04-06 03:49:42 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_fcall_info_args_save ( zend_fcall_info * fci , int * param_count , zval * * * * params ) /* { { { */
2007-04-06 03:49:42 +08:00
{
* param_count = fci - > param_count ;
* params = fci - > params ;
fci - > param_count = 0 ;
fci - > params = NULL ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2007-04-06 03:49:42 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API void zend_fcall_info_args_restore ( zend_fcall_info * fci , int param_count , zval * * * params ) /* { { { */
2007-04-06 03:49:42 +08:00
{
zend_fcall_info_args_clear ( fci , 1 ) ;
fci - > param_count = param_count ;
fci - > params = params ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2007-04-06 03:49:42 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int zend_fcall_info_args ( zend_fcall_info * fci , zval * args TSRMLS_DC ) /* { { { */
2007-04-06 03:49:42 +08:00
{
HashPosition pos ;
2007-11-03 03:40:39 +08:00
zval * * arg , * * * params ;
2007-04-06 03:49:42 +08:00
zend_fcall_info_args_clear ( fci , ! args ) ;
2006-06-07 17:43:54 +08:00
if ( ! args ) {
return SUCCESS ;
}
if ( Z_TYPE_P ( args ) ! = IS_ARRAY ) {
return FAILURE ;
}
fci - > param_count = zend_hash_num_elements ( Z_ARRVAL_P ( args ) ) ;
2007-11-03 03:40:39 +08:00
fci - > params = params = ( zval * * * ) erealloc ( fci - > params , fci - > param_count * sizeof ( zval * * ) ) ;
2006-06-07 17:43:54 +08:00
zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_P ( args ) , & pos ) ;
2007-11-03 03:40:39 +08:00
while ( zend_hash_get_current_data_ex ( Z_ARRVAL_P ( args ) , ( void * ) & arg , & pos ) = = SUCCESS ) {
2006-06-07 17:43:54 +08:00
* params + + = arg ;
zend_hash_move_forward_ex ( Z_ARRVAL_P ( args ) , & pos ) ;
}
2007-11-03 03:40:39 +08:00
return SUCCESS ;
}
/* }}} */
ZEND_API int zend_fcall_info_argp ( zend_fcall_info * fci TSRMLS_DC , int argc , zval * * * argv ) /* { { { */
{
int i ;
if ( argc < 0 ) {
return FAILURE ;
}
zend_fcall_info_args_clear ( fci , ! argc ) ;
if ( argc ) {
fci - > param_count = argc ;
fci - > params = ( zval * * * ) erealloc ( fci - > params , fci - > param_count * sizeof ( zval * * ) ) ;
for ( i = 0 ; i < argc ; + + i ) {
fci - > params [ i ] = argv [ i ] ;
}
}
return SUCCESS ;
}
/* }}} */
ZEND_API int zend_fcall_info_argv ( zend_fcall_info * fci TSRMLS_DC , int argc , va_list * argv ) /* { { { */
{
int i ;
zval * * arg ;
if ( argc < 0 ) {
return FAILURE ;
}
zend_fcall_info_args_clear ( fci , ! argc ) ;
if ( argc ) {
fci - > param_count = argc ;
fci - > params = ( zval * * * ) erealloc ( fci - > params , fci - > param_count * sizeof ( zval * * ) ) ;
for ( i = 0 ; i < argc ; + + i ) {
arg = va_arg ( * argv , zval * * ) ;
fci - > params [ i ] = arg ;
}
}
2006-06-07 17:43:54 +08:00
return SUCCESS ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
ZEND_API int zend_fcall_info_argn ( zend_fcall_info * fci TSRMLS_DC , int argc , . . . ) /* { { { */
{
int ret ;
va_list argv ;
2006-06-07 17:43:54 +08:00
2007-11-03 03:40:39 +08:00
va_start ( argv , argc ) ;
ret = zend_fcall_info_argv ( fci TSRMLS_CC , argc , & argv ) ;
va_end ( argv ) ;
return ret ;
}
/* }}} */
2006-06-07 17:43:54 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API int zend_fcall_info_call ( zend_fcall_info * fci , zend_fcall_info_cache * fcc , zval * * retval_ptr_ptr , zval * args TSRMLS_DC ) /* { { { */
2006-06-07 17:43:54 +08:00
{
2006-06-20 21:28:11 +08:00
zval * retval , * * * org_params = NULL ;
2007-11-03 03:40:39 +08:00
int result , org_count = 0 ;
2006-06-07 17:43:54 +08:00
fci - > retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : & retval ;
if ( args ) {
2007-04-06 03:49:42 +08:00
zend_fcall_info_args_save ( fci , & org_count , & org_params ) ;
2006-06-07 17:43:54 +08:00
zend_fcall_info_args ( fci , args TSRMLS_CC ) ;
}
result = zend_call_function ( fci , fcc TSRMLS_CC ) ;
2007-11-03 03:40:39 +08:00
2006-06-07 17:43:54 +08:00
if ( ! retval_ptr_ptr & & retval ) {
zval_ptr_dtor ( & retval ) ;
}
if ( args ) {
2007-04-06 03:49:42 +08:00
zend_fcall_info_args_restore ( fci , org_count , org_params ) ;
2006-06-07 17:43:54 +08:00
}
return result ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2006-06-07 17:43:54 +08:00
2007-11-03 03:40:39 +08:00
ZEND_API const char * zend_get_module_version ( const char * module_name ) /* { { { */
2001-10-13 02:40:30 +08:00
{
2007-05-17 02:57:15 +08:00
char * lname ;
int name_len = strlen ( module_name ) ;
2001-10-13 02:40:30 +08:00
zend_module_entry * module ;
2007-05-17 02:57:15 +08:00
lname = zend_str_tolower_dup ( module_name , name_len ) ;
2007-11-03 03:40:39 +08:00
if ( zend_hash_find ( & module_registry , lname , name_len + 1 , ( void * * ) & module ) = = FAILURE ) {
2007-05-17 02:57:15 +08:00
efree ( lname ) ;
2001-10-13 02:40:30 +08:00
return NULL ;
}
2007-05-17 02:57:15 +08:00
efree ( lname ) ;
2006-05-10 07:53:23 +08:00
return module - > version ;
2001-10-13 02:40:30 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-02-01 09:49:15 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_ex ( zend_class_entry * ce , const char * name , int name_length , zval * property , int access_type , const char * doc_comment , int doc_comment_len TSRMLS_DC ) /* { { { */
2003-07-07 03:55:20 +08:00
{
2010-05-24 22:11:39 +08:00
zend_property_info property_info , * property_info_ptr ;
2011-09-13 21:29:35 +08:00
const char * interned_name ;
2010-05-24 22:11:39 +08:00
ulong h = zend_get_hash_value ( name , name_length + 1 ) ;
2003-07-07 03:55:20 +08:00
if ( ! ( access_type & ZEND_ACC_PPP_MASK ) ) {
access_type | = ZEND_ACC_PUBLIC ;
}
if ( access_type & ZEND_ACC_STATIC ) {
2010-05-24 22:11:39 +08:00
if ( zend_hash_quick_find ( & ce - > properties_info , name , name_length + 1 , h , ( void * * ) & property_info_ptr ) = = SUCCESS & &
( property_info_ptr - > flags & ZEND_ACC_STATIC ) ! = 0 ) {
property_info . offset = property_info_ptr - > offset ;
zval_ptr_dtor ( & ce - > default_static_members_table [ property_info . offset ] ) ;
zend_hash_quick_del ( & ce - > properties_info , name , name_length + 1 , h ) ;
} else {
property_info . offset = ce - > default_static_members_count + + ;
ce - > default_static_members_table = perealloc ( ce - > default_static_members_table , sizeof ( zval * ) * ce - > default_static_members_count , ce - > type = = ZEND_INTERNAL_CLASS ) ;
}
ce - > default_static_members_table [ property_info . offset ] = property ;
if ( ce - > type = = ZEND_USER_CLASS ) {
ce - > static_members_table = ce - > default_static_members_table ;
}
2003-07-07 03:55:20 +08:00
} else {
2010-05-24 22:11:39 +08:00
if ( zend_hash_quick_find ( & ce - > properties_info , name , name_length + 1 , h , ( void * * ) & property_info_ptr ) = = SUCCESS & &
( property_info_ptr - > flags & ZEND_ACC_STATIC ) = = 0 ) {
property_info . offset = property_info_ptr - > offset ;
zval_ptr_dtor ( & ce - > default_properties_table [ property_info . offset ] ) ;
zend_hash_quick_del ( & ce - > properties_info , name , name_length + 1 , h ) ;
} else {
property_info . offset = ce - > default_properties_count + + ;
ce - > default_properties_table = perealloc ( ce - > default_properties_table , sizeof ( zval * ) * ce - > default_properties_count , ce - > type = = ZEND_INTERNAL_CLASS ) ;
}
ce - > default_properties_table [ property_info . offset ] = property ;
2003-07-07 03:55:20 +08:00
}
2003-08-25 06:45:59 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
switch ( Z_TYPE_P ( property ) ) {
case IS_ARRAY :
case IS_CONSTANT_ARRAY :
case IS_OBJECT :
case IS_RESOURCE :
zend_error ( E_CORE_ERROR , " Internal zval's can't be arrays, objects or resources " ) ;
break ;
default :
break ;
}
2003-08-25 01:32:47 +08:00
}
2003-07-07 03:55:20 +08:00
switch ( access_type & ZEND_ACC_PPP_MASK ) {
2003-07-08 00:22:56 +08:00
case ZEND_ACC_PRIVATE : {
char * priv_name ;
int priv_name_length ;
2004-01-03 21:51:02 +08:00
zend_mangle_property_name ( & priv_name , & priv_name_length , ce - > name , ce - > name_length , name , name_length , ce - > type & ZEND_INTERNAL_CLASS ) ;
2003-07-08 00:22:56 +08:00
property_info . name = priv_name ;
property_info . name_length = priv_name_length ;
}
break ;
case ZEND_ACC_PROTECTED : {
char * prot_name ;
int prot_name_length ;
2004-01-03 21:51:02 +08:00
zend_mangle_property_name ( & prot_name , & prot_name_length , " * " , 1 , name , name_length , ce - > type & ZEND_INTERNAL_CLASS ) ;
2003-07-08 00:22:56 +08:00
property_info . name = prot_name ;
property_info . name_length = prot_name_length ;
}
break ;
case ZEND_ACC_PUBLIC :
2010-04-20 19:05:54 +08:00
if ( IS_INTERNED ( name ) ) {
property_info . name = ( char * ) name ;
} else {
property_info . name = ce - > type & ZEND_INTERNAL_CLASS ? zend_strndup ( name , name_length ) : estrndup ( name , name_length ) ;
}
2003-07-08 00:22:56 +08:00
property_info . name_length = name_length ;
break ;
2003-07-07 03:55:20 +08:00
}
2010-04-20 19:05:54 +08:00
2010-05-25 17:00:20 +08:00
interned_name = zend_new_interned_string ( property_info . name , property_info . name_length + 1 , 0 TSRMLS_CC ) ;
2010-04-20 19:05:54 +08:00
if ( interned_name ! = property_info . name ) {
if ( ce - > type = = ZEND_USER_CLASS ) {
2011-09-13 21:29:35 +08:00
efree ( ( char * ) property_info . name ) ;
2010-04-20 19:05:54 +08:00
} else {
2011-09-13 21:29:35 +08:00
free ( ( char * ) property_info . name ) ;
2010-04-20 19:05:54 +08:00
}
property_info . name = interned_name ;
}
2003-07-07 03:55:20 +08:00
property_info . flags = access_type ;
2010-05-24 22:11:39 +08:00
property_info . h = ( access_type & ZEND_ACC_PUBLIC ) ? h : zend_get_hash_value ( property_info . name , property_info . name_length + 1 ) ;
2003-07-07 03:55:20 +08:00
2005-04-20 06:04:59 +08:00
property_info . doc_comment = doc_comment ;
property_info . doc_comment_len = doc_comment_len ;
2006-05-28 02:39:53 +08:00
property_info . ce = ce ;
2006-05-28 03:06:06 +08:00
2011-08-07 21:04:02 +08:00
zend_hash_quick_update ( & ce - > properties_info , name , name_length + 1 , h , & property_info , sizeof ( zend_property_info ) , NULL ) ;
2003-07-08 00:22:56 +08:00
return SUCCESS ;
2003-07-07 03:55:20 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property ( zend_class_entry * ce , const char * name , int name_length , zval * property , int access_type TSRMLS_DC ) /* { { { */
2007-11-03 03:40:39 +08:00
{
return zend_declare_property_ex ( ce , name , name_length , property , access_type , NULL , 0 TSRMLS_CC ) ;
}
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_null ( zend_class_entry * ce , const char * name , int name_length , int access_type TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
zval * property ;
2006-05-10 07:53:23 +08:00
2003-08-24 03:37:39 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( property ) ;
2003-08-24 03:37:39 +08:00
} else {
ALLOC_ZVAL ( property ) ;
}
INIT_ZVAL ( * property ) ;
2003-09-04 02:01:22 +08:00
return zend_declare_property ( ce , name , name_length , property , access_type TSRMLS_CC ) ;
2003-08-24 03:37:39 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_bool ( zend_class_entry * ce , const char * name , int name_length , long value , int access_type TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
zval * property ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( property ) ;
2005-02-05 04:24:21 +08:00
} else {
ALLOC_ZVAL ( property ) ;
}
INIT_PZVAL ( property ) ;
ZVAL_BOOL ( property , value ) ;
return zend_declare_property ( ce , name , name_length , property , access_type TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_long ( zend_class_entry * ce , const char * name , int name_length , long value , int access_type TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
zval * property ;
2006-05-10 07:53:23 +08:00
2003-08-24 03:37:39 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( property ) ;
2003-08-24 03:37:39 +08:00
} else {
ALLOC_ZVAL ( property ) ;
}
INIT_PZVAL ( property ) ;
ZVAL_LONG ( property , value ) ;
2003-09-04 02:01:22 +08:00
return zend_declare_property ( ce , name , name_length , property , access_type TSRMLS_CC ) ;
2003-08-25 01:32:47 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-25 01:32:47 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_double ( zend_class_entry * ce , const char * name , int name_length , double value , int access_type TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
zval * property ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( property ) ;
2005-02-05 04:24:21 +08:00
} else {
ALLOC_ZVAL ( property ) ;
}
INIT_PZVAL ( property ) ;
ZVAL_DOUBLE ( property , value ) ;
return zend_declare_property ( ce , name , name_length , property , access_type TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_string ( zend_class_entry * ce , const char * name , int name_length , const char * value , int access_type TSRMLS_DC ) /* { { { */
2003-08-25 01:32:47 +08:00
{
zval * property ;
int len = strlen ( value ) ;
2006-05-10 07:53:23 +08:00
2003-08-25 01:32:47 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( property ) ;
2003-08-25 02:47:11 +08:00
ZVAL_STRINGL ( property , zend_strndup ( value , len ) , len , 0 ) ;
2003-08-25 01:32:47 +08:00
} else {
ALLOC_ZVAL ( property ) ;
2003-08-25 02:47:11 +08:00
ZVAL_STRINGL ( property , value , len , 1 ) ;
2003-08-25 01:32:47 +08:00
}
INIT_PZVAL ( property ) ;
2003-09-04 02:01:22 +08:00
return zend_declare_property ( ce , name , name_length , property , access_type TSRMLS_CC ) ;
2003-08-24 03:37:39 +08:00
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_declare_property_stringl ( zend_class_entry * ce , const char * name , int name_length , const char * value , int value_len , int access_type TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
zval * property ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( property ) ;
2005-02-05 04:24:21 +08:00
ZVAL_STRINGL ( property , zend_strndup ( value , value_len ) , value_len , 0 ) ;
} else {
ALLOC_ZVAL ( property ) ;
ZVAL_STRINGL ( property , value , value_len , 1 ) ;
}
INIT_PZVAL ( property ) ;
return zend_declare_property ( ce , name , name_length , property , access_type TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant ( zend_class_entry * ce , const char * name , size_t name_length , zval * value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
return zend_hash_update ( & ce - > constants_table , name , name_length + 1 , & value , sizeof ( zval * ) , NULL ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_null ( zend_class_entry * ce , const char * name , size_t name_length TSRMLS_DC ) /* { { { */
2006-03-06 00:12:24 +08:00
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( constant ) ;
2006-03-06 00:12:24 +08:00
} else {
ALLOC_ZVAL ( constant ) ;
}
ZVAL_NULL ( constant ) ;
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2006-03-06 00:12:24 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_long ( zend_class_entry * ce , const char * name , size_t name_length , long value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( constant ) ;
2005-09-01 18:05:32 +08:00
} else {
ALLOC_ZVAL ( constant ) ;
}
ZVAL_LONG ( constant , value ) ;
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_bool ( zend_class_entry * ce , const char * name , size_t name_length , zend_bool value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( constant ) ;
2005-09-01 18:05:32 +08:00
} else {
ALLOC_ZVAL ( constant ) ;
}
ZVAL_BOOL ( constant , value ) ;
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_double ( zend_class_entry * ce , const char * name , size_t name_length , double value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( constant ) ;
2005-09-01 18:05:32 +08:00
} else {
ALLOC_ZVAL ( constant ) ;
}
ZVAL_DOUBLE ( constant , value ) ;
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_stringl ( zend_class_entry * ce , const char * name , size_t name_length , const char * value , size_t value_length TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
2008-01-24 18:49:26 +08:00
ALLOC_PERMANENT_ZVAL ( constant ) ;
2005-09-01 18:05:32 +08:00
ZVAL_STRINGL ( constant , zend_strndup ( value , value_length ) , value_length , 0 ) ;
} else {
ALLOC_ZVAL ( constant ) ;
ZVAL_STRINGL ( constant , value , value_length , 1 ) ;
}
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-13 01:20:25 +08:00
ZEND_API int zend_declare_class_constant_string ( zend_class_entry * ce , const char * name , size_t name_length , const char * value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
return zend_declare_class_constant_stringl ( ce , name , name_length , value , strlen ( value ) TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property ( zend_class_entry * scope , zval * object , const char * name , int name_length , zval * value TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
2005-11-23 19:15:11 +08:00
zval * property ;
2003-08-24 03:37:39 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
2006-05-10 07:53:23 +08:00
2003-08-24 03:37:39 +08:00
EG ( scope ) = scope ;
if ( ! Z_OBJ_HT_P ( object ) - > write_property ) {
2011-09-13 21:29:35 +08:00
const char * class_name ;
2005-06-28 02:13:13 +08:00
zend_uint class_name_len ;
zend_get_object_classname ( object , & class_name , & class_name_len TSRMLS_CC ) ;
2006-05-10 07:53:23 +08:00
2005-06-28 02:13:13 +08:00
zend_error ( E_CORE_ERROR , " Property %s of class %s cannot be updated " , name , class_name ) ;
2003-08-24 03:37:39 +08:00
}
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( property ) ;
ZVAL_STRINGL ( property , name , name_length , 1 ) ;
2010-04-20 18:57:45 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , value , 0 TSRMLS_CC ) ;
2005-11-23 19:15:11 +08:00
zval_ptr_dtor ( & property ) ;
2003-08-24 03:37:39 +08:00
EG ( scope ) = old_scope ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_null ( zend_class_entry * scope , zval * object , const char * name , int name_length TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
zval * tmp ;
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2003-08-24 03:37:39 +08:00
ZVAL_NULL ( tmp ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_bool ( zend_class_entry * scope , zval * object , const char * name , int name_length , long value TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-02-05 04:24:21 +08:00
ZVAL_BOOL ( tmp , value ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_long ( zend_class_entry * scope , zval * object , const char * name , int name_length , long value TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2003-08-24 03:37:39 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2003-08-24 03:37:39 +08:00
ZVAL_LONG ( tmp , value ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_double ( zend_class_entry * scope , zval * object , const char * name , int name_length , double value TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-08-12 22:56:59 +08:00
ZVAL_DOUBLE ( tmp , value ) ;
2005-02-05 04:24:21 +08:00
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_string ( zend_class_entry * scope , zval * object , const char * name , int name_length , const char * value TSRMLS_DC ) /* { { { */
2003-08-24 03:37:39 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2003-08-24 03:37:39 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2003-08-24 03:37:39 +08:00
ZVAL_STRING ( tmp , value , 1 ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 03:37:39 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API void zend_update_property_stringl ( zend_class_entry * scope , zval * object , const char * name , int name_length , const char * value , int value_len TSRMLS_DC ) /* { { { */
2005-02-05 04:24:21 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-02-05 04:24:21 +08:00
ZVAL_STRINGL ( tmp , value , value_len , 1 ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-02-05 04:24:21 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property ( zend_class_entry * scope , const char * name , int name_length , zval * value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * * property ;
zend_class_entry * old_scope = EG ( scope ) ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
EG ( scope ) = scope ;
2010-04-20 18:57:45 +08:00
property = zend_std_get_static_property ( scope , name , name_length , 0 , NULL TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
EG ( scope ) = old_scope ;
if ( ! property ) {
return FAILURE ;
} else {
if ( * property ! = value ) {
if ( PZVAL_IS_REF ( * property ) ) {
zval_dtor ( * property ) ;
2006-05-10 07:53:23 +08:00
Z_TYPE_PP ( property ) = Z_TYPE_P ( value ) ;
2005-09-01 18:05:32 +08:00
( * property ) - > value = value - > value ;
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( value ) > 0 ) {
2005-09-01 18:05:32 +08:00
zval_copy_ctor ( * property ) ;
}
} else {
zval * garbage = * property ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2005-09-01 18:05:32 +08:00
if ( PZVAL_IS_REF ( value ) ) {
SEPARATE_ZVAL ( & value ) ;
}
* property = value ;
zval_ptr_dtor ( & garbage ) ;
}
}
return SUCCESS ;
}
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_null ( zend_class_entry * scope , const char * name , int name_length TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * tmp ;
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-09-01 18:05:32 +08:00
ZVAL_NULL ( tmp ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_bool ( zend_class_entry * scope , const char * name , int name_length , long value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-09-01 18:05:32 +08:00
ZVAL_BOOL ( tmp , value ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_long ( zend_class_entry * scope , const char * name , int name_length , long value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-09-01 18:05:32 +08:00
ZVAL_LONG ( tmp , value ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_double ( zend_class_entry * scope , const char * name , int name_length , double value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-09-01 18:05:32 +08:00
ZVAL_DOUBLE ( tmp , value ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_string ( zend_class_entry * scope , const char * name , int name_length , const char * value TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-09-01 18:05:32 +08:00
ZVAL_STRING ( tmp , value , 1 ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API int zend_update_static_property_stringl ( zend_class_entry * scope , const char * name , int name_length , const char * value , int value_len TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( tmp ) ;
Z_SET_REFCOUNT_P ( tmp , 0 ) ;
2005-09-01 18:05:32 +08:00
ZVAL_STRINGL ( tmp , value , value_len , 1 ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API zval * zend_read_property ( zend_class_entry * scope , zval * object , const char * name , int name_length , zend_bool silent TSRMLS_DC ) /* { { { */
2003-08-24 08:36:53 +08:00
{
2005-11-24 02:51:44 +08:00
zval * property , * value ;
2003-08-24 08:36:53 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
2006-05-10 07:53:23 +08:00
2003-08-24 08:36:53 +08:00
EG ( scope ) = scope ;
if ( ! Z_OBJ_HT_P ( object ) - > read_property ) {
2011-09-13 21:29:35 +08:00
const char * class_name ;
2005-06-28 02:13:13 +08:00
zend_uint class_name_len ;
zend_get_object_classname ( object , & class_name , & class_name_len TSRMLS_CC ) ;
zend_error ( E_CORE_ERROR , " Property %s of class %s cannot be read " , name , class_name ) ;
2003-08-24 08:36:53 +08:00
}
2006-05-10 07:53:23 +08:00
2005-11-24 02:51:44 +08:00
MAKE_STD_ZVAL ( property ) ;
ZVAL_STRINGL ( property , name , name_length , 1 ) ;
2010-04-20 18:57:45 +08:00
value = Z_OBJ_HT_P ( object ) - > read_property ( object , property , silent ? BP_VAR_IS : BP_VAR_R , 0 TSRMLS_CC ) ;
2005-11-24 02:51:44 +08:00
zval_ptr_dtor ( & property ) ;
2006-05-10 07:53:23 +08:00
2003-08-24 08:36:53 +08:00
EG ( scope ) = old_scope ;
return value ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2003-08-24 08:36:53 +08:00
2011-09-13 21:29:35 +08:00
ZEND_API zval * zend_read_static_property ( zend_class_entry * scope , const char * name , int name_length , zend_bool silent TSRMLS_DC ) /* { { { */
2005-09-01 18:05:32 +08:00
{
zval * * property ;
zend_class_entry * old_scope = EG ( scope ) ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
EG ( scope ) = scope ;
2010-04-20 18:57:45 +08:00
property = zend_std_get_static_property ( scope , name , name_length , silent , NULL TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
EG ( scope ) = old_scope ;
return property ? * property : NULL ;
}
2007-11-03 03:40:39 +08:00
/* }}} */
2005-09-01 18:05:32 +08:00
2008-08-09 01:47:31 +08:00
ZEND_API void zend_save_error_handling ( zend_error_handling * current TSRMLS_DC ) /* { { { */
{
current - > handling = EG ( error_handling ) ;
current - > exception = EG ( exception_class ) ;
2008-08-12 01:19:20 +08:00
current - > user_handler = EG ( user_error_handler ) ;
if ( current - > user_handler ) {
Z_ADDREF_P ( current - > user_handler ) ;
}
2008-08-09 01:47:31 +08:00
}
/* }}} */
ZEND_API void zend_replace_error_handling ( zend_error_handling_t error_handling , zend_class_entry * exception_class , zend_error_handling * current TSRMLS_DC ) /* { { { */
{
if ( current ) {
zend_save_error_handling ( current TSRMLS_CC ) ;
2008-08-12 01:19:20 +08:00
if ( error_handling ! = EH_NORMAL & & EG ( user_error_handler ) ) {
zval_ptr_dtor ( & EG ( user_error_handler ) ) ;
EG ( user_error_handler ) = NULL ;
}
2008-08-09 01:47:31 +08:00
}
EG ( error_handling ) = error_handling ;
EG ( exception_class ) = error_handling = = EH_THROW ? exception_class : NULL ;
}
/* }}} */
2008-08-12 01:19:20 +08:00
ZEND_API void zend_restore_error_handling ( zend_error_handling * saved TSRMLS_DC ) /* { { { */
2008-08-09 01:47:31 +08:00
{
EG ( error_handling ) = saved - > handling ;
EG ( exception_class ) = saved - > handling = = EH_THROW ? saved - > exception : NULL ;
2008-08-12 01:19:20 +08:00
if ( saved - > user_handler & & saved - > user_handler ! = EG ( user_error_handler ) ) {
if ( EG ( user_error_handler ) ) {
zval_ptr_dtor ( & EG ( user_error_handler ) ) ;
}
EG ( user_error_handler ) = saved - > user_handler ;
} else if ( saved - > user_handler ) {
zval_ptr_dtor ( & saved - > user_handler ) ;
}
saved - > user_handler = NULL ;
2008-08-09 01:47:31 +08:00
}
/* }}} */
2003-02-01 09:49:15 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/