1999-04-08 02:10:10 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-05 07:53:05 +08:00
| Copyright ( c ) 1998 - 2006 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"
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
/* this function doesn't check for too many parameters */
2000-02-19 21:11: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
2000-03-27 02:40:24 +08:00
p = EG ( argument_stack ) . top_element - 2 ;
1999-04-21 11:49:09 +08:00
arg_count = ( ulong ) * 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 ) ;
1999-07-10 02:19:48 +08:00
if ( ! PZVAL_IS_REF ( param_ptr ) & & param_ptr - > refcount > 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 ;
2000-06-10 09:08:55 +08:00
( ( zval * ) * ( p - arg_count ) ) - > refcount - - ;
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 ;
}
2001-07-30 10:07:52 +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
2000-03-27 02:40:24 +08:00
p = EG ( argument_stack ) . top_element - 2 ;
1999-04-21 11:49:09 +08:00
arg_count = ( ulong ) * p ;
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 ) ;
1999-07-10 02:19:48 +08:00
if ( ! PZVAL_IS_REF ( param_ptr ) & & param_ptr - > refcount > 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 ;
2000-06-10 09:08:55 +08:00
( ( zval * ) * ( p - arg_count ) ) - > refcount - - ;
* ( 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 ;
}
1999-04-15 03:53:33 +08:00
/* Zend-optimized Extended functions */
/* this function doesn't check for too many parameters */
2000-02-19 21:11: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
2000-03-27 02:40:24 +08:00
p = EG ( argument_stack ) . top_element - 2 ;
1999-04-21 11:49:09 +08:00
arg_count = ( ulong ) * p ;
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 ;
}
2001-07-30 10:07:52 +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
2000-03-27 02:40:24 +08:00
p = EG ( argument_stack ) . top_element - 2 ;
1999-04-21 11:49:09 +08:00
arg_count = ( ulong ) * p ;
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 ) ;
2006-06-05 21:58:52 +08:00
if ( EG ( ze1_compatibility_mode ) & & Z_TYPE_PP ( value ) = = IS_OBJECT ) {
zval * value_ptr ;
char * class_name ;
zend_uint class_name_len ;
int dup ;
dup = zend_get_object_classname ( * value , & class_name , & class_name_len TSRMLS_CC ) ;
ALLOC_ZVAL ( value_ptr ) ;
* value_ptr = * * value ;
INIT_PZVAL ( value_ptr ) ;
zend_error ( E_STRICT , " Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode' " , class_name ) ;
if ( ! dup ) {
efree ( class_name ) ;
}
value_ptr - > value . obj = Z_OBJ_HANDLER_PP ( value , clone_obj ) ( * value TSRMLS_CC ) ;
zval_ptr_dtor ( value ) ;
* value = value_ptr ;
}
2005-04-29 15:59:04 +08:00
* ( argument_array + + ) = value ;
arg_count - - ;
1999-04-15 03:53:33 +08:00
}
return SUCCESS ;
}
2004-09-29 06:55:22 +08:00
ZEND_API int zend_copy_parameters_array ( int param_count , zval * argument_array TSRMLS_DC )
{
void * * p ;
int arg_count ;
p = EG ( argument_stack ) . top_element - 2 ;
arg_count = ( ulong ) * p ;
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 ;
}
2001-07-30 15:43:02 +08:00
ZEND_API void zend_wrong_param_count ( TSRMLS_D )
1999-04-08 02:10:10 +08:00
{
2005-06-17 19:25:31 +08:00
char * space ;
char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
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
}
2001-07-10 02:51:29 +08:00
/* Argument parsing API -- andrei */
2006-05-25 18:01:06 +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 " ;
case IS_ARRAY :
return " array " ;
2001-07-10 02:51:29 +08:00
default :
return " unknown " ;
}
}
2006-05-25 18:01:06 +08:00
ZEND_API char * zend_zval_type_name ( zval * arg )
{
return zend_get_type_by_const ( Z_TYPE_P ( arg ) ) ;
}
2003-03-26 15:44:11 +08:00
ZEND_API zend_class_entry * zend_get_class_entry ( 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
}
}
2005-06-29 16:43:38 +08:00
/* returns 1 if you need to copy result, 0 if it's already a copy */
2005-06-28 02:13:13 +08:00
ZEND_API int zend_get_object_classname ( zval * object , char * * class_name , zend_uint * class_name_len TSRMLS_DC )
{
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 ;
}
2006-05-13 18:37:45 +08:00
static int parse_arg_object_to_string ( zval * * arg , char * * p , int * pl , int type TSRMLS_DC )
{
if ( Z_OBJ_HANDLER_PP ( arg , cast_object ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( arg ) ;
if ( Z_OBJ_HANDLER_PP ( arg , cast_object ) ( * arg , * arg , type TSRMLS_CC ) = = SUCCESS ) {
* pl = Z_STRLEN_PP ( arg ) ;
* p = Z_STRVAL_PP ( arg ) ;
return SUCCESS ;
}
}
/* 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 ) ;
z - > refcount + + ;
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 ;
}
2001-07-10 02:51:29 +08:00
2006-02-28 06:23:21 +08:00
static char * zend_parse_arg_impl ( int arg_num , zval * * arg , va_list * va , char * * spec TSRMLS_DC )
2001-07-10 02:51:29 +08:00
{
char * spec_walk = * spec ;
char c = * spec_walk + + ;
int return_null = 0 ;
while ( * spec_walk = = ' / ' | | * spec_walk = = ' ! ' ) {
if ( * spec_walk = = ' / ' ) {
SEPARATE_ZVAL_IF_NOT_REF ( arg ) ;
} else if ( * spec_walk = = ' ! ' & & Z_TYPE_PP ( arg ) = = IS_NULL ) {
return_null = 1 ;
}
spec_walk + + ;
}
switch ( c ) {
case ' l ' :
{
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 ) {
* p = ( long ) d ;
}
}
break ;
case IS_NULL :
case IS_LONG :
case IS_DOUBLE :
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 ;
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 ) ;
* p = Z_STRVAL_PP ( arg ) ;
* pl = Z_STRLEN_PP ( arg ) ;
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 ) {
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 :
return " string " ;
}
}
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 * * ) ;
if ( Z_TYPE_PP ( arg ) ! = IS_RESOURCE ) {
if ( Z_TYPE_PP ( arg ) = = IS_NULL & & return_null ) {
* p = NULL ;
} else {
return " resource " ;
}
2006-05-10 07:53:23 +08:00
} else {
2001-07-10 02:51:29 +08:00
* p = * arg ;
2006-05-10 07:53:23 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
case ' a ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
if ( Z_TYPE_PP ( arg ) ! = IS_ARRAY ) {
if ( Z_TYPE_PP ( arg ) = = IS_NULL & & return_null ) {
* p = NULL ;
} else {
return " array " ;
}
2006-05-10 07:53:23 +08:00
} else {
2001-07-10 02:51:29 +08:00
* p = * arg ;
2006-05-10 07:53:23 +08:00
}
2001-07-10 02:51:29 +08:00
}
break ;
2006-01-26 06:03:18 +08:00
case ' h ' :
{
HashTable * * p = va_arg ( * va , HashTable * * ) ;
if ( Z_TYPE_PP ( arg ) ! = IS_ARRAY ) {
if ( Z_TYPE_PP ( arg ) = = IS_NULL & & return_null ) {
* p = NULL ;
} else {
return " array " ;
}
} else {
* p = Z_ARRVAL_PP ( arg ) ;
}
}
break ;
2001-07-10 02:51:29 +08:00
case ' o ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
if ( Z_TYPE_PP ( arg ) ! = IS_OBJECT ) {
if ( Z_TYPE_PP ( arg ) = = IS_NULL & & return_null ) {
* p = NULL ;
} else {
return " object " ;
}
2006-05-10 07:53:23 +08:00
} else {
2001-07-10 02:51:29 +08:00
* p = * arg ;
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
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 {
2001-07-10 02:51:29 +08:00
if ( Z_TYPE_PP ( arg ) = = IS_NULL & & return_null ) {
* p = NULL ;
2006-05-28 03:06:06 +08:00
} else if ( ce ) {
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 ;
2006-05-24 06:22:11 +08:00
if ( return_null & & Z_TYPE_PP ( arg ) = = IS_NULL ) {
* 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 ) {
if ( ( ! * pce | | ! instanceof_function ( * pce , ce_base TSRMLS_CC ) ) & & ! return_null ) {
char * space ;
char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
zend_error ( E_WARNING , " %s%s%s() expects parameter %d to be a class name derived from %s, '%s' given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) ,
arg_num , ce_base - > name , Z_STRVAL_PP ( arg ) ) ;
* pce = NULL ;
return " " ;
}
}
2006-05-24 06:22:11 +08:00
if ( ! * pce ) {
2006-02-28 06:23:21 +08:00
char * space ;
char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
zend_error ( E_WARNING , " %s%s%s() expects parameter %d to be a valid class name, '%s' given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) ,
arg_num , Z_STRVAL_PP ( arg ) ) ;
return " " ;
}
break ;
}
break ;
2006-06-07 17:43:54 +08:00
case ' f ' :
{
zend_fcall_info * fci = va_arg ( * va , zend_fcall_info * ) ;
zend_fcall_info_cache * fcc = va_arg ( * va , zend_fcall_info_cache * ) ;
if ( zend_fcall_info_init ( * arg , fci , fcc TSRMLS_CC ) = = SUCCESS ) {
break ;
} else if ( return_null ) {
fci - > size = 0 ;
fcc - > initialized = 0 ;
break ;
} else {
return " function " ;
}
}
2001-07-10 02:51:29 +08:00
case ' z ' :
{
zval * * p = va_arg ( * va , zval * * ) ;
if ( Z_TYPE_PP ( arg ) = = IS_NULL & & return_null ) {
* p = NULL ;
} else {
* p = * arg ;
}
}
break ;
2003-07-12 22:54:53 +08:00
case ' Z ' :
{
zval * * * p = va_arg ( * va , zval * * * ) ;
if ( Z_TYPE_PP ( arg ) = = IS_NULL & & return_null ) {
* p = NULL ;
} else {
* p = arg ;
}
2003-07-11 18:21:39 +08:00
}
break ;
2001-07-10 02:51:29 +08:00
default :
return " unknown " ;
}
* spec = spec_walk ;
return NULL ;
}
2001-07-30 15:43:02 +08:00
static int zend_parse_arg ( int arg_num , zval * * arg , va_list * va , char * * spec , int quiet TSRMLS_DC )
2001-07-10 02:51:29 +08:00
{
char * expected_type = NULL ;
2006-02-28 06:23:21 +08:00
expected_type = zend_parse_arg_impl ( arg_num , arg , va , spec TSRMLS_CC ) ;
2001-07-10 02:51:29 +08:00
if ( expected_type ) {
2006-05-24 05:50:29 +08:00
if ( ! quiet & & * expected_type ) {
2005-06-17 19:25:31 +08:00
char * space ;
char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
zend_error ( E_WARNING , " %s%s%s() expects parameter %d to be %s, %s given " ,
class_name , space , get_active_function_name ( TSRMLS_C ) , arg_num , expected_type ,
2001-07-10 02:51:29 +08:00
zend_zval_type_name ( * arg ) ) ;
}
return FAILURE ;
}
2006-05-10 07:53:23 +08:00
2001-07-10 02:51:29 +08:00
return SUCCESS ;
}
2001-07-30 12:54:16 +08:00
static int zend_parse_va_args ( int num_args , char * type_spec , va_list * va , int flags TSRMLS_DC )
2001-07-10 02:51:29 +08:00
{
char * spec_walk ;
int c , i ;
int min_num_args = - 1 ;
int max_num_args = 0 ;
zval * * arg ;
void * * p ;
int arg_count ;
int quiet = flags & ZEND_PARSE_PARAMS_QUIET ;
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 ' :
2006-05-28 03:06:06 +08:00
case ' f ' :
2001-07-10 02:51:29 +08:00
max_num_args + + ;
break ;
case ' | ' :
min_num_args = max_num_args ;
break ;
case ' / ' :
case ' ! ' :
/* Pass */
break ;
default :
if ( ! quiet ) {
2003-08-13 15:02:44 +08:00
zend_function * active_function = EG ( function_state_ptr ) - > function ;
char * class_name = active_function - > common . scope ? active_function - > common . scope - > name : " " ;
zend_error ( E_WARNING , " %s%s%s(): bad type specifier while parsing parameters " ,
class_name ,
class_name [ 0 ] ? " :: " : " " ,
get_active_function_name ( TSRMLS_C ) ) ;
2001-07-10 02:51:29 +08:00
}
return FAILURE ;
}
}
if ( min_num_args < 0 ) {
min_num_args = max_num_args ;
}
if ( num_args < min_num_args | | num_args > max_num_args ) {
if ( ! quiet ) {
2003-08-13 15:02:44 +08:00
zend_function * active_function = EG ( function_state_ptr ) - > function ;
char * class_name = active_function - > common . scope ? active_function - > common . scope - > name : " " ;
zend_error ( E_WARNING , " %s%s%s() expects %s %d parameter%s, %d given " ,
class_name ,
class_name [ 0 ] ? " :: " : " " ,
2001-07-30 15:43:02 +08:00
get_active_function_name ( TSRMLS_C ) ,
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 ;
}
p = EG ( argument_stack ) . top_element - 2 ;
arg_count = ( ulong ) * p ;
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 ) {
arg = ( zval * * ) p - ( arg_count - i ) ;
if ( * type_spec = = ' | ' ) {
type_spec + + ;
}
2001-07-30 15:43:02 +08:00
if ( zend_parse_arg ( i + 1 , arg , va , & type_spec , quiet TSRMLS_CC ) = = FAILURE ) {
2001-07-10 02:51:29 +08:00
return FAILURE ;
}
i + + ;
}
return SUCCESS ;
}
2001-07-30 13:05:26 +08:00
ZEND_API int zend_parse_parameters_ex ( int flags , int num_args TSRMLS_DC , char * type_spec , . . . )
2001-07-10 02:51:29 +08:00
{
va_list va ;
int retval ;
2006-05-10 07:53:23 +08:00
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 ;
}
2001-07-30 12:54:16 +08:00
ZEND_API int zend_parse_parameters ( int num_args TSRMLS_DC , char * type_spec , . . . )
2001-07-10 02:51:29 +08:00
{
va_list va ;
int retval ;
2006-05-10 07:53:23 +08:00
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 ;
}
2003-02-09 04:54:02 +08:00
ZEND_API int zend_parse_method_parameters ( int num_args TSRMLS_DC , zval * this_ptr , char * type_spec , . . . )
2003-02-03 07:30:14 +08:00
{
va_list va ;
int retval ;
2003-02-09 04:54:02 +08:00
char * p = type_spec ;
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 ) {
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 + + ;
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 ;
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 ;
}
2003-08-01 00:30:15 +08:00
2004-03-03 00:17:58 +08:00
ZEND_API int zend_parse_method_parameters_ex ( int flags , int num_args TSRMLS_DC , zval * this_ptr , char * type_spec , . . . )
2003-02-03 07:30:14 +08:00
{
va_list va ;
int retval ;
2004-03-03 00:17:58 +08:00
char * p = type_spec ;
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 ) {
va_start ( va , type_spec ) ;
retval = zend_parse_va_args ( num_args , type_spec , & va , 0 TSRMLS_CC ) ;
va_end ( va ) ;
} else {
p + + ;
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 ;
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
}
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 ;
}
2004-03-03 00:17:58 +08:00
2001-07-10 02:51:29 +08:00
/* Argument parsing API -- andrei */
2001-07-12 01:18:22 +08:00
ZEND_API int _array_init ( zval * arg ZEND_FILE_LINE_DC )
1999-04-08 02:10:10 +08:00
{
2000-02-20 03:21:45 +08:00
ALLOC_HASHTABLE_REL ( arg - > value . ht ) ;
1999-12-28 03:07:33 +08:00
2003-08-19 05:17:26 +08:00
_zend_hash_init ( arg - > value . ht , 0 , NULL , ZVAL_PTR_DTOR , 0 ZEND_FILE_LINE_RELAY_CC ) ;
1999-04-08 02:10:10 +08:00
arg - > type = IS_ARRAY ;
return SUCCESS ;
}
2003-08-30 07:27:22 +08:00
static int zend_merge_property ( zval * * value , int num_args , va_list args , zend_hash_key * hash_key )
{
/* 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
TSRMLS_FETCH ( ) ;
2005-11-23 19:15:11 +08:00
MAKE_STD_ZVAL ( member ) ;
ZVAL_STRINGL ( member , hash_key - > arKey , hash_key - > nKeyLength - 1 , 1 ) ;
obj_ht - > write_property ( obj , member , * value TSRMLS_CC ) ;
zval_ptr_dtor ( & member ) ;
2003-08-30 07:27:22 +08:00
}
return ZEND_HASH_APPLY_KEEP ;
}
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 . */
ZEND_API void zend_merge_properties ( zval * obj , HashTable * properties , int destroy_ht TSRMLS_DC )
{
zend_object_handlers * obj_ht = Z_OBJ_HT_P ( obj ) ;
zend_class_entry * old_scope = EG ( scope ) ;
EG ( scope ) = Z_OBJCE_P ( obj ) ;
zend_hash_apply_with_arguments ( properties , ( apply_func_args_t ) zend_merge_property , 2 , obj , obj_ht ) ;
EG ( scope ) = old_scope ;
if ( destroy_ht ) {
zend_hash_destroy ( properties ) ;
FREE_HASHTABLE ( properties ) ;
}
}
2005-01-22 20:23:01 +08:00
ZEND_API void zend_update_class_constants ( zend_class_entry * class_type TSRMLS_DC )
{
2005-12-01 19:48:17 +08:00
if ( ! class_type - > constants_updated | | ! CE_STATIC_MEMBERS ( class_type ) ) {
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 ;
* 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-01-22 20:23:01 +08:00
zend_hash_apply_with_argument ( & class_type - > default_properties , ( apply_func_arg_t ) zval_update_constant , ( void * ) 1 TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
2005-12-01 19:48:17 +08:00
if ( ! CE_STATIC_MEMBERS ( class_type ) ) {
2005-09-01 18:05:32 +08:00
HashPosition pos ;
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
ALLOC_HASHTABLE ( CG ( static_members ) [ ( long ) ( class_type - > static_members ) ] ) ;
# else
2005-09-01 18:05:32 +08:00
ALLOC_HASHTABLE ( class_type - > static_members ) ;
2005-12-01 19:48:17 +08:00
# endif
2006-10-03 19:10:33 +08:00
zend_hash_init ( CE_STATIC_MEMBERS ( class_type ) , zend_hash_num_elements ( & class_type - > default_static_members ) , NULL , ZVAL_PTR_DTOR , 0 ) ;
2005-09-01 18:05:32 +08:00
zend_hash_internal_pointer_reset_ex ( & class_type - > default_static_members , & pos ) ;
while ( zend_hash_get_current_data_ex ( & class_type - > default_static_members , ( void * * ) & p , & pos ) = = SUCCESS ) {
char * str_index ;
uint str_length ;
ulong num_index ;
zval * * q ;
zend_hash_get_current_key_ex ( & class_type - > default_static_members , & str_index , & str_length , & num_index , 0 , & pos ) ;
if ( ( * p ) - > is_ref & &
class_type - > parent & &
zend_hash_find ( & class_type - > parent - > default_static_members , str_index , str_length , ( void * * ) & q ) = = SUCCESS & &
* p = = * q & &
2005-12-01 19:48:17 +08:00
zend_hash_find ( CE_STATIC_MEMBERS ( class_type - > parent ) , str_index , str_length , ( void * * ) & q ) = = SUCCESS ) {
2005-09-01 18:05:32 +08:00
( * q ) - > refcount + + ;
( * q ) - > is_ref = 1 ;
2005-12-01 19:48:17 +08:00
zend_hash_add ( CE_STATIC_MEMBERS ( class_type ) , str_index , str_length , ( void * * ) q , sizeof ( zval * ) , NULL ) ;
2005-09-01 18:05:32 +08:00
} else {
zval * q ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( q ) ;
* q = * * p ;
2005-11-23 19:15:11 +08:00
INIT_PZVAL ( q ) ;
2005-09-01 18:05:32 +08:00
zval_copy_ctor ( q ) ;
2005-12-01 19:48:17 +08:00
zend_hash_add ( CE_STATIC_MEMBERS ( class_type ) , str_index , str_length , ( void * * ) & q , sizeof ( zval * ) , NULL ) ;
2005-09-01 18:05:32 +08:00
}
zend_hash_move_forward_ex ( & class_type - > default_static_members , & pos ) ;
}
}
2005-12-01 19:48:17 +08:00
zend_hash_apply_with_argument ( CE_STATIC_MEMBERS ( class_type ) , ( apply_func_arg_t ) zval_update_constant , ( void * ) 1 TSRMLS_CC ) ;
2005-09-01 18:05:32 +08:00
2005-04-26 17:27:28 +08:00
* scope = old_scope ;
2005-01-22 20:23:01 +08:00
class_type - > constants_updated = 1 ;
}
}
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 ( ) . */
2001-08-12 02:26:47 +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
{
zval * tmp ;
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 ) ) {
char * what = class_type - > ce_flags & ZEND_ACC_INTERFACE ? " interface " : " abstract class " ;
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 ;
} else {
ALLOC_HASHTABLE_REL ( object - > properties ) ;
2006-10-03 19:10:33 +08:00
zend_hash_init ( object - > properties , zend_hash_num_elements ( & class_type - > default_properties ) , NULL , ZVAL_PTR_DTOR , 0 ) ;
2002-02-07 22:08:43 +08:00
zend_hash_copy ( object - > properties , & class_type - > default_properties , ( copy_ctor_func_t ) zval_add_ref , ( void * ) & tmp , sizeof ( zval * ) ) ;
}
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 ;
}
2001-08-12 02:26:47 +08:00
ZEND_API int _object_init_ex ( zval * arg , zend_class_entry * class_type ZEND_FILE_LINE_DC TSRMLS_DC )
{
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
}
1999-04-08 02:10:10 +08:00
2001-08-05 09:37:10 +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
}
2001-08-11 23:56:40 +08:00
ZEND_API int add_assoc_function ( zval * arg , 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 ;
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_assoc_long_ex ( zval * arg , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_assoc_null_ex ( zval * arg , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_assoc_bool_ex ( zval * arg , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_assoc_resource_ex ( zval * arg , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_assoc_double_ex ( zval * arg , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_assoc_string_ex ( zval * arg , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_assoc_stringl_ex ( zval * arg , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_assoc_zval_ex ( zval * arg , 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
}
1999-04-08 02:10:10 +08:00
2005-10-28 22:46:30 +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
}
2005-10-28 22:46:30 +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 ) ;
}
1999-12-31 21:56:59 +08:00
2005-10-28 22:46:30 +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
}
2005-10-28 22:46:30 +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
}
2005-10-28 22:46:30 +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
}
2005-10-28 22:46:30 +08:00
ZEND_API int add_index_string ( zval * arg , ulong index , 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
}
2005-10-28 22:46:30 +08:00
ZEND_API int add_index_stringl ( zval * arg , ulong index , 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 ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , NULL ) ;
}
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
2005-10-28 22:46:30 +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
}
2001-07-11 17:33:41 +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
}
2001-07-11 17:33:41 +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
}
2001-07-11 17:33:41 +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
}
2001-07-11 17:33:41 +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
}
2001-07-11 17:33:41 +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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_next_index_string ( zval * arg , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_next_index_stringl ( zval * arg , 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
}
2001-07-11 17:33:41 +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 ) ;
}
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
2001-07-11 17:33:41 +08:00
ZEND_API int add_get_assoc_string_ex ( zval * arg , char * key , uint key_len , 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_get_assoc_stringl_ex ( zval * arg , char * key , uint key_len , 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
}
2005-10-28 22:46:30 +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
}
2005-10-28 22:46:30 +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
}
2005-10-28 22:46:30 +08:00
ZEND_API int add_get_index_string ( zval * arg , ulong index , 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 ) ;
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
}
2005-10-28 22:46:30 +08:00
ZEND_API int add_get_index_stringl ( zval * arg , ulong index , 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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRINGL ( tmp , str , length , duplicate ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( void * ) & tmp , sizeof ( zval * ) , dest ) ;
1999-04-08 02:10:10 +08:00
}
2003-01-14 20:15:09 +08:00
ZEND_API int add_property_long_ex ( zval * arg , 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 ) ;
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
2005-11-23 19:15:11 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp 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
}
2003-01-14 20:15:09 +08:00
ZEND_API int add_property_bool_ex ( zval * arg , 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
2005-11-23 19:15:11 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp 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
}
2003-01-14 20:15:09 +08:00
ZEND_API int add_property_null_ex ( zval * arg , 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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_NULL ( tmp ) ;
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
2005-11-23 19:15:11 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp 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
}
2003-01-14 20:15:09 +08:00
ZEND_API int add_property_resource_ex ( zval * arg , 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 ;
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 ) ;
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp 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
}
1999-04-08 02:10:10 +08:00
2003-01-14 20:15:09 +08:00
ZEND_API int add_property_double_ex ( zval * arg , 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 ) ;
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
2005-11-23 19:15:11 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp 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
}
2003-01-14 20:15:09 +08:00
ZEND_API int add_property_string_ex ( zval * arg , char * key , uint key_len , 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
2005-11-23 19:15:11 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp 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
}
1999-04-08 02:10:10 +08:00
2003-01-14 20:15:09 +08:00
ZEND_API int add_property_stringl_ex ( zval * arg , char * key , uint key_len , 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
2005-11-23 19:15:11 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , tmp 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
}
2003-01-14 20:15:09 +08:00
ZEND_API int add_property_zval_ex ( zval * arg , 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
2005-11-23 19:15:11 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , z_key , value TSRMLS_CC ) ;
zval_ptr_dtor ( & z_key ) ;
2003-01-14 20:15:09 +08:00
return SUCCESS ;
2001-01-21 03:16:38 +08:00
}
1999-04-08 02:10:10 +08:00
2005-06-30 21:43:00 +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 ) {
zend_module_dep * dep = module - > deps ;
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 ) ;
if ( zend_hash_find ( & module_registry , lcname , name_len + 1 , ( void * * ) & req_mod ) = = FAILURE | |
! req_mod - > module_started ) {
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 ;
}
static void zend_sort_modules ( void * base , size_t count , size_t siz , compare_func_t compare TSRMLS_DC )
{
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 ) {
zend_module_dep * dep = m - > deps ;
while ( dep - > name ) {
if ( dep - > type = = MODULE_DEP_REQUIRED | | dep - > type = = MODULE_DEP_OPTIONAL ) {
b2 = b1 + 1 ;
while ( b2 < end ) {
r = ( zend_module_entry * ) ( * b2 ) - > pData ;
if ( strcasecmp ( dep - > name , r - > name ) = = 0 ) {
tmp = * b1 ;
* b1 = * b2 ;
2006-05-10 07:53:23 +08:00
* b2 = tmp ;
2005-06-17 17:36:26 +08:00
goto try_again ;
}
b2 + + ;
}
}
dep + + ;
2006-05-10 07:53:23 +08:00
}
2005-06-17 17:36:26 +08:00
}
b1 + + ;
}
}
ZEND_API int zend_startup_modules ( TSRMLS_D )
{
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 ;
}
2005-07-19 00:20:08 +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
zend_printf ( " %s: Registering module %d \n " , module - > name , module - > module_number ) ;
# endif
2005-06-17 17:36:26 +08:00
/* Check module dependencies */
if ( module - > deps ) {
zend_module_dep * dep = module - > deps ;
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 ;
2004-05-13 07:05:28 +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
}
2005-07-19 00:20:08 +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 ) ;
}
2004-09-10 00:51:45 +08:00
ZEND_API void zend_check_magic_method_implementation ( zend_class_entry * ce , zend_function * fptr , int error_type TSRMLS_DC )
{
char lcname [ 16 ] ;
int name_len ;
/* we don't care if the function name is longer, in fact lowercasing only
* 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 ) ;
} else if ( name_len = = sizeof ( ZEND_GET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_GET_FUNC_NAME , sizeof ( ZEND_GET_FUNC_NAME ) ) & & 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 ( name_len = = sizeof ( ZEND_SET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_SET_FUNC_NAME , sizeof ( ZEND_SET_FUNC_NAME ) ) & & fptr - > common . num_args ! = 2 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 2 arguments " , ce - > name , ZEND_SET_FUNC_NAME ) ;
2005-07-08 00:07:09 +08:00
} else if ( name_len = = sizeof ( ZEND_UNSET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_UNSET_FUNC_NAME , sizeof ( ZEND_UNSET_FUNC_NAME ) ) & & 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 ( name_len = = sizeof ( ZEND_ISSET_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_ISSET_FUNC_NAME , sizeof ( ZEND_ISSET_FUNC_NAME ) ) & & fptr - > common . num_args ! = 1 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 1 argument " , ce - > name , ZEND_ISSET_FUNC_NAME ) ;
2004-09-10 00:51:45 +08:00
} else if ( name_len = = sizeof ( ZEND_CALL_FUNC_NAME ) - 1 & & ! memcmp ( lcname , ZEND_CALL_FUNC_NAME , sizeof ( ZEND_CALL_FUNC_NAME ) ) & & fptr - > common . num_args ! = 2 ) {
zend_error ( error_type , " Method %s::%s() must take exactly 2 arguments " , ce - > name , ZEND_CALL_FUNC_NAME ) ;
}
}
1999-04-08 02:10:10 +08:00
/* registers all functions in *library_functions in the function hash */
2003-12-22 21:09:15 +08:00
ZEND_API int zend_register_functions ( zend_class_entry * scope , zend_function_entry * functions , HashTable * function_table , int type TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
1999-04-18 23:11:52 +08:00
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 ;
2001-08-11 23:56:40 +08:00
int count = 0 , unload = 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 ;
2006-05-10 21:49:27 +08:00
zend_function * ctor = NULL , * dtor = NULL , * clone = NULL , * __get = NULL , * __set = NULL , * __unset = NULL , * __isset = NULL , * __call = NULL , * __tostring = NULL ;
2003-03-20 05:07:49 +08:00
char * lowercase_name ;
2003-06-02 20:13:11 +08:00
int fname_len ;
2006-02-07 04:37:11 +08:00
char * lc_class_name = NULL ;
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 ;
2004-09-10 00:51:45 +08:00
if ( scope ) {
class_name_len = strlen ( scope - > name ) ;
lc_class_name = zend_str_tolower_dup ( scope - > name , class_name_len ) ;
}
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 ;
internal_function - > function_name = 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 ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
if ( ptr - > arg_info ) {
internal_function - > arg_info = ptr - > arg_info + 1 ;
internal_function - > num_args = ptr - > num_args ;
2004-02-25 17:25:37 +08:00
/* Currently you cannot denote that the function can accept less arguments than num_args */
2004-02-25 22:56:45 +08:00
if ( ptr - > arg_info [ 0 ] . required_num_args = = - 1 ) {
internal_function - > required_num_args = ptr - > num_args ;
} else {
internal_function - > required_num_args = ptr - > arg_info [ 0 ] . required_num_args ;
}
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
internal_function - > pass_rest_by_reference = ptr - > arg_info [ 0 ] . pass_by_reference ;
2004-02-12 21:49:55 +08:00
internal_function - > return_reference = ptr - > arg_info [ 0 ] . return_reference ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
} else {
internal_function - > arg_info = NULL ;
internal_function - > num_args = 0 ;
2004-02-25 17:25:37 +08:00
internal_function - > required_num_args = 0 ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
internal_function - > pass_rest_by_reference = 0 ;
2004-02-12 21:49:55 +08:00
internal_function - > return_reference = 0 ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
}
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 ;
}
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. */
2004-02-28 02:20:53 +08:00
/* This time we set the flag for the keyword 'abstratc'. */
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 ) ) {
2005-10-27 22:07:30 +08:00
efree ( 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 ) {
efree ( lc_class_name ) ;
}
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 ) ;
lowercase_name = do_alloca ( fname_len + 1 ) ;
2003-05-22 06:57:51 +08:00
zend_str_tolower_copy ( lowercase_name , ptr - > fname , fname_len ) ;
2003-03-20 05:07:49 +08:00
if ( zend_hash_add ( target_function_table , lowercase_name , fname_len + 1 , & function , sizeof ( zend_function ) , ( void * * ) & reg_function ) = = FAILURE ) {
1999-04-08 02:10:10 +08:00
unload = 1 ;
2003-03-20 05:07:49 +08:00
free_alloca ( lowercase_name ) ;
1999-04-08 02:10:10 +08:00
break ;
}
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 .
*/
2004-09-10 00:51:45 +08:00
if ( ( fname_len = = class_name_len ) & & ! memcmp ( lowercase_name , lc_class_name , class_name_len + 1 ) & & ! ctor ) {
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 ;
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 + + ;
2003-03-20 05:07:49 +08:00
free_alloca ( 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 ) {
efree ( lc_class_name ) ;
}
1999-04-08 02:10:10 +08:00
while ( ptr - > fname ) {
1999-05-28 20:06:59 +08:00
if ( zend_hash_exists ( target_function_table , ptr - > fname , strlen ( ptr - > fname ) + 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
}
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 ;
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 ;
}
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 ;
}
2004-09-10 00:51:45 +08:00
efree ( lc_class_name ) ;
2003-01-10 22:41:53 +08:00
}
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
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
*/
2003-12-22 21:09:15 +08:00
ZEND_API void zend_unregister_functions ( zend_function_entry * functions , int count , HashTable * function_table TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
1999-04-18 23:11:52 +08:00
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 + + ;
}
}
2005-06-30 21:43:00 +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
2005-07-19 00:20:08 +08:00
if ( ( module = zend_register_internal_module ( module TSRMLS_CC ) ) ! = NULL & &
2005-06-30 21:43:00 +08:00
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
}
2004-01-19 08:39:29 +08:00
ZEND_API int zend_get_module_started ( char * module_name )
{
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 ;
}
1999-04-08 02:10:10 +08:00
void module_destructor ( zend_module_entry * module )
{
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 ) ;
1999-04-08 02:10:10 +08:00
}
if ( module - > module_started & & module - > module_shutdown_func ) {
#if 0
2001-08-11 23:56:40 +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
}
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
2005-01-15 08:11:20 +08:00
# if HAVE_LIBDL || defined(HAVE_MACH_O_DYLD_H)
2004-09-24 23:40:22 +08:00
# if !(defined(NETWARE) && defined(APACHE_1_BUILD))
2006-05-10 07:53:23 +08:00
if ( module - > handle ) {
DL_UNLOAD ( module - > handle ) ;
}
2004-09-22 22:31:21 +08:00
# endif
1999-04-08 02:10:10 +08:00
# endif
}
/* call request startup for all modules */
2001-07-31 12:53:54 +08:00
int module_registry_request_startup ( zend_module_entry * module TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
1999-11-26 21:53:18 +08:00
if ( module - > request_startup_func ) {
1999-04-08 02:10:10 +08:00
#if 0
2001-08-11 23:56:40 +08:00
zend_printf ( " %s: Request startup \n " , module - > name ) ;
1999-04-08 02:10:10 +08:00
# endif
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 ) ;
}
1999-04-08 02:10:10 +08:00
}
return 0 ;
}
2005-03-16 07:46:29 +08:00
/* call request shutdown for all modules */
2001-07-31 12:53:54 +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
2005-03-16 07:46:29 +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 ;
}
int module_registry_unload_temp ( zend_module_entry * module TSRMLS_DC )
{
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
}
/* return the next free module number */
int zend_next_free_module ( void )
{
return + + module_count ;
}
2003-10-23 03:59:58 +08:00
static zend_class_entry * do_register_internal_class ( zend_class_entry * orig_class_entry , zend_uint ce_flags TSRMLS_DC )
{
zend_class_entry * class_entry = malloc ( sizeof ( zend_class_entry ) ) ;
char * lowercase_name = malloc ( orig_class_entry - > name_length + 1 ) ;
* 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 ;
2004-03-31 02:36:53 +08:00
class_entry - > module = EG ( current_module ) ;
2003-10-23 03:59:58 +08:00
if ( class_entry - > builtin_functions ) {
zend_register_functions ( class_entry , class_entry - > builtin_functions , & class_entry - > function_table , MODULE_PERSISTENT TSRMLS_CC ) ;
}
zend_str_tolower_copy ( lowercase_name , orig_class_entry - > name , class_entry - > name_length ) ;
zend_hash_update ( CG ( class_table ) , lowercase_name , class_entry - > name_length + 1 , & class_entry , sizeof ( zend_class_entry * ) , NULL ) ;
free ( lowercase_name ) ;
return class_entry ;
}
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
*/
2001-07-30 09:48:22 +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 ;
}
1999-04-08 02:10:10 +08:00
2003-10-15 14:24:17 +08:00
ZEND_API void zend_class_implements ( zend_class_entry * class_entry TSRMLS_DC , int num_interfaces , . . . )
{
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
}
2006-06-07 17:21:06 +08:00
2003-10-15 14:24:17 +08:00
va_end ( interface_list ) ;
}
2003-10-23 03:59:58 +08:00
/* A class that contains at least one abstract method automatically becomes an abstract class.
*/
2002-03-12 18:08:47 +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 ) ;
}
2000-02-03 06:23:37 +08:00
2003-10-23 03:59:58 +08:00
ZEND_API zend_class_entry * zend_register_internal_interface ( zend_class_entry * orig_class_entry TSRMLS_DC )
{
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
}
1999-05-09 20:24:21 +08:00
1999-12-05 00:50:18 +08:00
ZEND_API int zend_set_hash_symbol ( zval * symbol , char * name , int name_length ,
2002-04-24 02:06:54 +08:00
zend_bool is_ref , int num_symbol_tables , . . . )
1999-12-05 00:50:18 +08:00
{
2006-05-10 07:53:23 +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
2006-05-10 07:53:23 +08:00
symbol - > is_ref = 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
}
2000-05-30 01:16:52 +08:00
/* Disabled functions support */
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
}
static zend_function_entry disabled_function [ ] = {
ZEND_FE ( display_disabled_function , NULL )
{ NULL , NULL , NULL }
} ;
2001-07-31 12:53:54 +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
}
2001-02-01 13:01:26 +08:00
2003-03-03 09:22:43 +08:00
static zend_object_value display_disabled_class ( zend_class_entry * class_type TSRMLS_DC )
{
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
ALLOC_HASHTABLE ( intern - > properties ) ;
zend_hash_init ( intern - > properties , 0 , NULL , ZVAL_PTR_DTOR , 0 ) ;
zend_error ( E_WARNING , " %s() has been disabled for security reasons " , class_type - > name ) ;
return retval ;
}
static zend_function_entry disabled_class_new [ ] = {
{ NULL , NULL , NULL }
} ;
ZEND_API int zend_disable_class ( char * class_name , uint class_name_length TSRMLS_DC )
{
zend_class_entry * disabled_class ;
disabled_class = ( zend_class_entry * ) emalloc ( sizeof ( zend_class_entry ) ) ;
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 ;
}
INIT_CLASS_ENTRY ( ( * disabled_class ) , class_name , disabled_class_new ) ;
disabled_class - > create_object = display_disabled_class ;
2006-07-22 23:41:42 +08:00
disabled_class - > name_length = class_name_length ;
2003-03-03 09:22:43 +08:00
zend_register_internal_class ( disabled_class TSRMLS_CC ) ;
return 1 ;
}
2006-01-14 23:22:40 +08:00
static int zend_is_callable_check_func ( int check_flags , zval * * * zobj_ptr_ptr , zend_class_entry * ce_org , zval * callable , zend_class_entry * * ce_ptr , zend_function * * fptr_ptr TSRMLS_DC )
2001-02-01 13:01:26 +08:00
{
2005-12-17 06:15:41 +08:00
int retval ;
2005-11-03 04:30:13 +08:00
char * lcname , * lmname , * colon ;
2005-12-17 06:15:41 +08:00
int clen , mlen ;
zend_function * fptr ;
zend_class_entry * * pce ;
HashTable * ftable ;
2006-05-10 07:53:23 +08:00
2005-12-17 06:15:41 +08:00
* ce_ptr = NULL ;
* fptr_ptr = NULL ;
if ( ( colon = strstr ( Z_STRVAL_P ( callable ) , " :: " ) ) ! = NULL ) {
clen = colon - Z_STRVAL_P ( callable ) ;
mlen = Z_STRLEN_P ( callable ) - clen - 2 ;
2006-04-20 15:30:38 +08:00
lcname = zend_str_tolower_dup ( Z_STRVAL_P ( callable ) , clen ) ;
/* caution: lcname is not '\0' terminated */
if ( clen = = sizeof ( " self " ) - 1 & & memcmp ( lcname , " self " , sizeof ( " self " ) - 1 ) = = 0 ) {
* ce_ptr = EG ( scope ) ;
} else if ( clen = = sizeof ( " parent " ) - 1 & & memcmp ( lcname , " parent " , sizeof ( " parent " ) - 1 ) = = 0 & & EG ( active_op_array ) - > scope ) {
* ce_ptr = EG ( scope ) ? EG ( scope ) - > parent : NULL ;
} else if ( zend_lookup_class ( Z_STRVAL_P ( callable ) , clen , & pce TSRMLS_CC ) = = SUCCESS ) {
2005-12-17 06:15:41 +08:00
* ce_ptr = * pce ;
}
2006-04-20 15:30:38 +08:00
efree ( lcname ) ;
2005-12-17 06:15:41 +08:00
if ( ! * ce_ptr ) {
return 0 ;
}
ftable = & ( * ce_ptr ) - > function_table ;
if ( ce_org & & ! instanceof_function ( ce_org , * ce_ptr TSRMLS_CC ) ) {
return 0 ;
}
lmname = zend_str_tolower_dup ( Z_STRVAL_P ( callable ) + clen + 2 , mlen ) ;
} else {
mlen = Z_STRLEN_P ( callable ) ;
lmname = zend_str_tolower_dup ( Z_STRVAL_P ( callable ) , mlen ) ;
if ( ce_org ) {
ftable = & ce_org - > function_table ;
* ce_ptr = ce_org ;
} else {
ftable = EG ( function_table ) ;
}
}
retval = zend_hash_find ( ftable , lmname , mlen + 1 , ( void * * ) & fptr ) = = SUCCESS ? 1 : 0 ;
if ( ! retval ) {
2006-01-14 23:22:40 +08:00
if ( * zobj_ptr_ptr & & * ce_ptr & & ( * ce_ptr ) - > __call ! = 0 ) {
2005-12-17 06:15:41 +08:00
retval = ( * ce_ptr ) - > __call ! = NULL ;
* fptr_ptr = ( * ce_ptr ) - > __call ;
}
} else {
* fptr_ptr = fptr ;
if ( * ce_ptr ) {
2006-01-14 23:22:40 +08:00
if ( ! * zobj_ptr_ptr & & ! ( fptr - > common . fn_flags & ZEND_ACC_STATIC ) ) {
2005-12-17 06:15:41 +08:00
if ( ( check_flags & IS_CALLABLE_CHECK_IS_STATIC ) ! = 0 ) {
retval = 0 ;
} else {
2006-01-14 23:22:40 +08:00
if ( EG ( This ) & & instanceof_function ( Z_OBJCE_P ( EG ( This ) ) , * ce_ptr TSRMLS_CC ) ) {
* zobj_ptr_ptr = & EG ( This ) ;
zend_error ( E_STRICT , " Non-static method %s::%s() cannot be called statically, assuming $this from compatible context %s " , ( * ce_ptr ) - > name , fptr - > common . function_name , Z_OBJCE_P ( EG ( This ) ) - > name ) ;
} else {
zend_error ( E_STRICT , " Non-static method %s::%s() cannot be called statically " , ( * ce_ptr ) - > name , fptr - > common . function_name ) ;
}
2005-12-17 06:15:41 +08:00
}
}
if ( retval & & ( check_flags & IS_CALLABLE_CHECK_NO_ACCESS ) = = 0 ) {
if ( fptr - > op_array . fn_flags & ZEND_ACC_PRIVATE ) {
2006-01-14 23:22:40 +08:00
if ( ! zend_check_private ( fptr , * zobj_ptr_ptr ? Z_OBJCE_PP ( * zobj_ptr_ptr ) : EG ( scope ) , lmname , mlen TSRMLS_CC ) ) {
2005-12-17 06:15:41 +08:00
retval = 0 ;
}
} else if ( ( fptr - > common . fn_flags & ZEND_ACC_PROTECTED ) ) {
if ( ! zend_check_protected ( fptr - > common . scope , EG ( scope ) ) ) {
retval = 0 ;
}
}
}
}
}
efree ( lmname ) ;
return retval ;
}
ZEND_API zend_bool zend_is_callable_ex ( zval * callable , uint check_flags , char * * callable_name , int * callable_name_len , zend_class_entry * * ce_ptr , zend_function * * fptr_ptr , zval * * * zobj_ptr_ptr TSRMLS_DC )
{
char * lcname ;
2005-07-29 04:55:50 +08:00
zend_bool retval = 0 ;
2005-12-17 06:15:41 +08:00
int callable_name_len_local ;
2005-11-03 04:30:13 +08:00
zend_class_entry * ce_local , * * pce ;
2005-07-29 04:55:50 +08:00
zend_function * fptr_local ;
zval * * zobj_ptr_local ;
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 ;
}
2005-10-26 07:19:59 +08:00
if ( ce_ptr = = NULL ) {
ce_ptr = & ce_local ;
}
2005-07-29 04:55:50 +08:00
if ( fptr_ptr = = NULL ) {
fptr_ptr = & fptr_local ;
}
if ( zobj_ptr_ptr = = NULL ) {
zobj_ptr_ptr = & zobj_ptr_local ;
}
2005-10-26 07:19:59 +08:00
* ce_ptr = NULL ;
2005-07-29 04:55:50 +08:00
* fptr_ptr = NULL ;
* zobj_ptr_ptr = NULL ;
2001-02-01 13:01:26 +08:00
2001-03-12 11:08:28 +08:00
switch ( Z_TYPE_P ( callable ) ) {
2001-02-01 13:01:26 +08:00
case IS_STRING :
2003-12-29 00:20:06 +08:00
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 ) {
2001-03-12 11:08:28 +08:00
return 1 ;
2003-12-29 00:20:06 +08:00
}
2005-11-03 04:30:13 +08:00
2006-01-14 23:22:40 +08:00
retval = zend_is_callable_check_func ( check_flags | IS_CALLABLE_CHECK_IS_STATIC , zobj_ptr_ptr , NULL , callable , ce_ptr , fptr_ptr TSRMLS_CC ) ;
2001-02-01 13:01:26 +08:00
break ;
case IS_ARRAY :
{
2005-11-03 04:30:13 +08:00
zend_class_entry * ce = NULL ;
2001-02-01 13:01:26 +08:00
zval * * method ;
zval * * obj ;
2006-05-10 07:53:23 +08:00
2001-05-10 04:07:49 +08:00
if ( zend_hash_num_elements ( Z_ARRVAL_P ( callable ) ) = = 2 & &
zend_hash_index_find ( Z_ARRVAL_P ( callable ) , 0 , ( void * * ) & obj ) = = SUCCESS & &
2001-03-12 11:08:28 +08:00
zend_hash_index_find ( Z_ARRVAL_P ( callable ) , 1 , ( void * * ) & method ) = = SUCCESS & &
( 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
2006-04-20 15:30:38 +08:00
lcname = zend_str_tolower_dup ( Z_STRVAL_PP ( obj ) , Z_STRLEN_PP ( obj ) ) ;
if ( Z_STRLEN_PP ( obj ) = = sizeof ( " self " ) - 1 & & memcmp ( lcname , " self " , sizeof ( " self " ) ) = = 0 ) {
ce = EG ( active_op_array ) - > scope ;
} else if ( Z_STRLEN_PP ( obj ) = = sizeof ( " parent " ) - 1 & & memcmp ( lcname , " parent " , sizeof ( " parent " ) ) = = 0 & & EG ( active_op_array ) - > scope ) {
ce = EG ( active_op_array ) - > scope - > parent ;
} else if ( zend_lookup_class ( Z_STRVAL_PP ( obj ) , Z_STRLEN_PP ( obj ) , & pce TSRMLS_CC ) = = SUCCESS ) {
2002-03-12 18:08:47 +08:00
ce = * pce ;
}
2006-04-20 15:30:38 +08:00
efree ( lcname ) ;
2001-03-13 00:27:26 +08:00
} else {
2004-01-05 20:10:35 +08:00
ce = Z_OBJCE_PP ( obj ) ; /* TBFixed: what if it's overloaded? */
2006-05-10 07:53:23 +08:00
2005-07-29 04:55:50 +08:00
* zobj_ptr_ptr = obj ;
2001-05-10 04:07:49 +08:00
if ( callable_name ) {
char * ptr ;
2005-07-29 04:55:50 +08:00
* callable_name_len = ce - > name_length + Z_STRLEN_PP ( method ) + sizeof ( " :: " ) - 1 ;
ptr = * callable_name = emalloc ( * callable_name_len + 1 ) ;
2001-05-10 04:07:49 +08:00
memcpy ( ptr , ce - > name , ce - > name_length ) ;
ptr + = ce - > name_length ;
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 ) {
* ce_ptr = ce ;
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
if ( ce ) {
2006-01-14 23:22:40 +08:00
retval = zend_is_callable_check_func ( check_flags , zobj_ptr_ptr , ce , * method , ce_ptr , fptr_ptr TSRMLS_CC ) ;
2001-03-12 11:08:28 +08:00
}
2003-07-03 17:18:41 +08:00
} else if ( callable_name ) {
2001-03-12 11:08:28 +08:00
* callable_name = estrndup ( " Array " , sizeof ( " Array " ) - 1 ) ;
2005-07-29 04:55:50 +08:00
* callable_name_len = sizeof ( " Array " ) - 1 ;
2003-07-03 17:18:41 +08:00
}
2005-10-26 07:19:59 +08:00
* ce_ptr = ce ;
2001-02-01 13:01:26 +08:00
}
break ;
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 ) ;
}
2001-02-01 13:01:26 +08:00
break ;
}
return retval ;
}
2001-10-13 02:40:30 +08:00
2003-07-08 00:22:56 +08:00
2005-07-29 04:55:50 +08:00
ZEND_API zend_bool zend_is_callable ( zval * callable , uint check_flags , char * * callable_name )
{
TSRMLS_FETCH ( ) ;
2005-10-26 07:19:59 +08:00
return zend_is_callable_ex ( callable , check_flags , callable_name , NULL , NULL , NULL , NULL TSRMLS_CC ) ;
2005-07-29 04:55:50 +08:00
}
2003-10-26 06:58:06 +08:00
ZEND_API zend_bool zend_make_callable ( zval * callable , char * * callable_name TSRMLS_DC )
{
2005-11-04 07:45:18 +08:00
zend_class_entry * ce ;
zend_function * fptr ;
zval * * zobj_ptr ;
if ( zend_is_callable_ex ( callable , 0 , callable_name , NULL , & ce , & fptr , & zobj_ptr TSRMLS_CC ) ) {
if ( Z_TYPE_P ( callable ) = = IS_STRING & & ce ) {
zval_dtor ( callable ) ;
array_init ( callable ) ;
add_next_index_string ( callable , ce - > name , 1 ) ;
add_next_index_string ( callable , fptr - > common . function_name , 1 ) ;
}
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
}
2006-06-07 17:43:54 +08:00
ZEND_API int zend_fcall_info_init ( zval * callable , zend_fcall_info * fci , zend_fcall_info_cache * fcc TSRMLS_DC )
{
zend_class_entry * ce ;
zend_function * func ;
zval * * obj ;
if ( ! zend_is_callable_ex ( callable , IS_CALLABLE_STRICT , NULL , NULL , & ce , & func , & obj TSRMLS_CC ) ) {
return FAILURE ;
}
fci - > size = sizeof ( * fci ) ;
fci - > function_table = ce ? & ce - > function_table : EG ( function_table ) ;
fci - > object_pp = obj ;
fci - > function_name = NULL ;
fci - > retval_ptr_ptr = NULL ;
fci - > param_count = 0 ;
fci - > params = NULL ;
fci - > no_separation = 1 ;
fci - > symbol_table = NULL ;
fcc - > initialized = 1 ;
fcc - > function_handler = func ;
fcc - > calling_scope = ce ;
fcc - > object_pp = obj ;
return SUCCESS ;
}
ZEND_API int zend_fcall_info_args ( zend_fcall_info * fci , zval * args TSRMLS_DC )
{
HashPosition pos ;
zval * * arg , * * * params ;
if ( fci - > params ) {
while ( fci - > param_count ) {
zval_ptr_dtor ( fci - > params [ - - fci - > param_count ] ) ;
}
efree ( fci - > params ) ;
}
fci - > params = NULL ;
fci - > param_count = 0 ;
if ( ! args ) {
return SUCCESS ;
}
if ( Z_TYPE_P ( args ) ! = IS_ARRAY ) {
return FAILURE ;
}
fci - > param_count = zend_hash_num_elements ( Z_ARRVAL_P ( args ) ) ;
fci - > params = params = ( zval * * * ) safe_emalloc ( sizeof ( zval * * ) , fci - > param_count , 0 ) ;
zend_hash_internal_pointer_reset_ex ( Z_ARRVAL_P ( args ) , & pos ) ;
while ( zend_hash_get_current_data_ex ( Z_ARRVAL_P ( args ) , ( void * * ) & arg , & pos ) = = SUCCESS ) {
* params + + = arg ;
( * arg ) - > refcount + + ;
zend_hash_move_forward_ex ( Z_ARRVAL_P ( args ) , & pos ) ;
}
return SUCCESS ;
}
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-20 21:28:11 +08:00
zval * retval , * * * org_params = NULL ;
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 ) {
org_params = fci - > params ;
org_count = fci - > param_count ;
zend_fcall_info_args ( fci , args TSRMLS_CC ) ;
}
result = zend_call_function ( fci , fcc TSRMLS_CC ) ;
if ( ! retval_ptr_ptr & & retval ) {
zval_ptr_dtor ( & retval ) ;
}
if ( args ) {
zend_fcall_info_args ( fci , NULL TSRMLS_CC ) ;
fci - > params = org_params ;
fci - > param_count = org_count ;
}
return result ;
}
2001-10-13 02:40:30 +08:00
ZEND_API char * zend_get_module_version ( char * module_name )
{
zend_module_entry * module ;
if ( zend_hash_find ( & module_registry , module_name , strlen ( module_name ) + 1 ,
2006-05-10 07:53:23 +08:00
( void * * ) & module ) = = FAILURE ) {
2001-10-13 02:40:30 +08:00
return NULL ;
}
2006-05-10 07:53:23 +08:00
return module - > version ;
2001-10-13 02:40:30 +08:00
}
2003-02-01 09:49:15 +08:00
2003-07-08 00:22:56 +08:00
2003-09-04 02:01:22 +08:00
ZEND_API int zend_declare_property ( zend_class_entry * ce , char * name , int name_length , zval * property , int access_type TSRMLS_DC )
2005-04-20 06:04:59 +08:00
{
return zend_declare_property_ex ( ce , name , name_length , property , access_type , NULL , 0 TSRMLS_CC ) ;
}
ZEND_API int zend_declare_property_ex ( zend_class_entry * ce , char * name , int name_length , zval * property , int access_type , char * doc_comment , int doc_comment_len TSRMLS_DC )
2003-07-07 03:55:20 +08:00
{
zend_property_info property_info ;
HashTable * target_symbol_table ;
if ( ! ( access_type & ZEND_ACC_PPP_MASK ) ) {
access_type | = ZEND_ACC_PUBLIC ;
}
if ( access_type & ZEND_ACC_STATIC ) {
2005-09-01 18:05:32 +08:00
target_symbol_table = & ce - > default_static_members ;
2003-07-07 03:55:20 +08:00
} else {
target_symbol_table = & ce - > default_properties ;
}
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
zend_hash_update ( target_symbol_table , priv_name , priv_name_length + 1 , & property , sizeof ( zval * ) , NULL ) ;
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
zend_hash_update ( target_symbol_table , prot_name , prot_name_length + 1 , & property , sizeof ( zval * ) , NULL ) ;
property_info . name = prot_name ;
property_info . name_length = prot_name_length ;
}
break ;
case ZEND_ACC_PUBLIC :
2003-09-03 04:49:42 +08:00
if ( ce - > parent ) {
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-09-03 04:49:42 +08:00
zend_hash_del ( target_symbol_table , prot_name , prot_name_length + 1 ) ;
pefree ( prot_name , ce - > type & ZEND_INTERNAL_CLASS ) ;
}
2003-07-08 00:22:56 +08:00
zend_hash_update ( target_symbol_table , name , name_length + 1 , & property , sizeof ( zval * ) , NULL ) ;
2003-08-24 03:37:39 +08:00
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
}
property_info . flags = access_type ;
property_info . h = zend_get_hash_value ( property_info . name , property_info . name_length + 1 ) ;
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
2003-07-08 00:22:56 +08:00
zend_hash_update ( & ce - > properties_info , name , name_length + 1 , & property_info , sizeof ( zend_property_info ) , NULL ) ;
return SUCCESS ;
2003-07-07 03:55:20 +08:00
}
2003-08-24 03:37:39 +08:00
2003-09-04 02:01:22 +08:00
ZEND_API int zend_declare_property_null ( zend_class_entry * ce , 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 ) {
property = malloc ( sizeof ( zval ) ) ;
} 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
}
2005-02-05 04:24:21 +08:00
ZEND_API int zend_declare_property_bool ( zend_class_entry * ce , char * name , int name_length , long value , int access_type TSRMLS_DC )
{
zval * property ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
property = malloc ( sizeof ( zval ) ) ;
} else {
ALLOC_ZVAL ( property ) ;
}
INIT_PZVAL ( property ) ;
ZVAL_BOOL ( property , value ) ;
return zend_declare_property ( ce , name , name_length , property , access_type TSRMLS_CC ) ;
}
2003-09-04 02:01:22 +08:00
ZEND_API int zend_declare_property_long ( zend_class_entry * ce , 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 ) {
property = malloc ( sizeof ( zval ) ) ;
} 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
}
2005-02-05 04:24:21 +08:00
ZEND_API int zend_declare_property_double ( zend_class_entry * ce , char * name , int name_length , double value , int access_type TSRMLS_DC )
{
zval * property ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
property = malloc ( sizeof ( zval ) ) ;
} else {
ALLOC_ZVAL ( property ) ;
}
INIT_PZVAL ( property ) ;
ZVAL_DOUBLE ( property , value ) ;
return zend_declare_property ( ce , name , name_length , property , access_type TSRMLS_CC ) ;
}
2003-09-04 02:01:22 +08:00
ZEND_API int zend_declare_property_string ( zend_class_entry * ce , char * name , int name_length , 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 ) {
property = malloc ( sizeof ( zval ) ) ;
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
}
2005-02-05 04:24:21 +08:00
ZEND_API int zend_declare_property_stringl ( zend_class_entry * ce , char * name , int name_length , char * value , int value_len , int access_type TSRMLS_DC )
{
zval * property ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
property = malloc ( sizeof ( zval ) ) ;
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 ) ;
}
2005-09-01 18:05:32 +08:00
ZEND_API int zend_declare_class_constant ( zend_class_entry * ce , char * name , size_t name_length , zval * value TSRMLS_DC )
{
return zend_hash_update ( & ce - > constants_table , name , name_length + 1 , & value , sizeof ( zval * ) , NULL ) ;
}
2006-03-06 00:12:24 +08:00
ZEND_API int zend_declare_class_constant_null ( zend_class_entry * ce , char * name , size_t name_length TSRMLS_DC )
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
constant = malloc ( sizeof ( zval ) ) ;
} else {
ALLOC_ZVAL ( constant ) ;
}
ZVAL_NULL ( constant ) ;
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
2005-09-01 18:05:32 +08:00
ZEND_API int zend_declare_class_constant_long ( zend_class_entry * ce , char * name , size_t name_length , long value TSRMLS_DC )
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
constant = malloc ( sizeof ( zval ) ) ;
} else {
ALLOC_ZVAL ( constant ) ;
}
ZVAL_LONG ( constant , value ) ;
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
ZEND_API int zend_declare_class_constant_bool ( zend_class_entry * ce , char * name , size_t name_length , zend_bool value TSRMLS_DC )
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
constant = malloc ( sizeof ( zval ) ) ;
} else {
ALLOC_ZVAL ( constant ) ;
}
ZVAL_BOOL ( constant , value ) ;
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
ZEND_API int zend_declare_class_constant_double ( zend_class_entry * ce , char * name , size_t name_length , double value TSRMLS_DC )
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
constant = malloc ( sizeof ( zval ) ) ;
} else {
ALLOC_ZVAL ( constant ) ;
}
ZVAL_DOUBLE ( constant , value ) ;
INIT_PZVAL ( constant ) ;
return zend_declare_class_constant ( ce , name , name_length , constant TSRMLS_CC ) ;
}
ZEND_API int zend_declare_class_constant_stringl ( zend_class_entry * ce , char * name , size_t name_length , char * value , size_t value_length TSRMLS_DC )
{
zval * constant ;
if ( ce - > type & ZEND_INTERNAL_CLASS ) {
constant = malloc ( sizeof ( zval ) ) ;
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 ) ;
}
ZEND_API int zend_declare_class_constant_string ( zend_class_entry * ce , char * name , size_t name_length , char * value TSRMLS_DC )
{
return zend_declare_class_constant_stringl ( ce , name , name_length , value , strlen ( value ) TSRMLS_CC ) ;
}
2003-08-24 03:37:39 +08:00
ZEND_API void zend_update_property ( zend_class_entry * scope , zval * object , char * name , int name_length , zval * value TSRMLS_DC )
{
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 ) {
2005-06-28 02:13:13 +08:00
char * class_name ;
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 ) ;
Z_OBJ_HT_P ( object ) - > write_property ( object , property , value TSRMLS_CC ) ;
zval_ptr_dtor ( & property ) ;
2003-08-24 03:37:39 +08:00
EG ( scope ) = old_scope ;
}
ZEND_API void zend_update_property_null ( zend_class_entry * scope , zval * object , char * name , int name_length TSRMLS_DC )
{
zval * tmp ;
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_NULL ( tmp ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2005-02-05 04:24:21 +08:00
ZEND_API void zend_update_property_bool ( zend_class_entry * scope , zval * object , char * name , int name_length , long value TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_BOOL ( tmp , value ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2003-08-24 03:37:39 +08:00
ZEND_API void zend_update_property_long ( zend_class_entry * scope , zval * object , char * name , int name_length , long value TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2003-08-24 03:37:39 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_LONG ( tmp , value ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2005-02-05 04:24:21 +08:00
ZEND_API void zend_update_property_double ( zend_class_entry * scope , zval * object , char * name , int name_length , double value TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 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 ) ;
}
2003-08-24 03:37:39 +08:00
ZEND_API void zend_update_property_string ( zend_class_entry * scope , zval * object , char * name , int name_length , char * value TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2003-08-24 03:37:39 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_STRING ( tmp , value , 1 ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2005-02-05 04:24:21 +08:00
ZEND_API void zend_update_property_stringl ( zend_class_entry * scope , zval * object , char * name , int name_length , char * value , int value_len TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-02-05 04:24:21 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_STRINGL ( tmp , value , value_len , 1 ) ;
zend_update_property ( scope , object , name , name_length , tmp TSRMLS_CC ) ;
}
2005-09-01 18:05:32 +08:00
ZEND_API int zend_update_static_property ( zend_class_entry * scope , char * name , int name_length , zval * value TSRMLS_DC )
{
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 ;
property = zend_std_get_static_property ( scope , name , name_length , 0 TSRMLS_CC ) ;
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 ;
if ( value - > refcount > 0 ) {
zval_copy_ctor ( * property ) ;
}
} else {
zval * garbage = * property ;
value - > refcount + + ;
if ( PZVAL_IS_REF ( value ) ) {
SEPARATE_ZVAL ( & value ) ;
}
* property = value ;
zval_ptr_dtor ( & garbage ) ;
}
}
return SUCCESS ;
}
}
ZEND_API int zend_update_static_property_null ( zend_class_entry * scope , char * name , int name_length TSRMLS_DC )
{
zval * tmp ;
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_NULL ( tmp ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
ZEND_API int zend_update_static_property_bool ( zend_class_entry * scope , char * name , int name_length , long value TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_BOOL ( tmp , value ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
ZEND_API int zend_update_static_property_long ( zend_class_entry * scope , char * name , int name_length , long value TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_LONG ( tmp , value ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
ZEND_API int zend_update_static_property_double ( zend_class_entry * scope , char * name , int name_length , double value TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_DOUBLE ( tmp , value ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
ZEND_API int zend_update_static_property_string ( zend_class_entry * scope , char * name , int name_length , char * value TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_STRING ( tmp , value , 1 ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
ZEND_API int zend_update_static_property_stringl ( zend_class_entry * scope , char * name , int name_length , char * value , int value_len TSRMLS_DC )
{
zval * tmp ;
2006-05-10 07:53:23 +08:00
2005-09-01 18:05:32 +08:00
ALLOC_ZVAL ( tmp ) ;
tmp - > is_ref = 0 ;
tmp - > refcount = 0 ;
ZVAL_STRINGL ( tmp , value , value_len , 1 ) ;
return zend_update_static_property ( scope , name , name_length , tmp TSRMLS_CC ) ;
}
2003-08-24 08:36:53 +08:00
ZEND_API zval * zend_read_property ( zend_class_entry * scope , zval * object , char * name , int name_length , zend_bool silent TSRMLS_DC )
{
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 ) {
2005-06-28 02:13:13 +08:00
char * class_name ;
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 ) ;
2006-07-21 16:39:30 +08:00
value = Z_OBJ_HT_P ( object ) - > read_property ( object , property , silent ? BP_VAR_IS : BP_VAR_R 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 ;
}
2005-09-01 18:05:32 +08:00
ZEND_API zval * zend_read_static_property ( zend_class_entry * scope , char * name , int name_length , zend_bool silent TSRMLS_DC )
{
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 ;
property = zend_std_get_static_property ( scope , name , name_length , silent TSRMLS_CC ) ;
EG ( scope ) = old_scope ;
return property ? * property : NULL ;
}
2003-02-01 09:49:15 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/