1999-04-08 02:10:10 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2002-12-31 23:59:15 +08:00
| Copyright ( c ) 1998 - 2003 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 , |
1999-07-16 22:58:16 +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 ) {
* ( argument_array + + ) = ( zval * * ) p - ( arg_count - - ) ;
1999-04-15 03:53:33 +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
{
2001-07-30 15:43:02 +08:00
zend_error ( E_WARNING , " Wrong parameter count for %s() " , 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 */
2002-01-03 22:19:13 +08:00
ZEND_API char * zend_zval_type_name ( zval * arg )
2001-07-10 02:51:29 +08:00
{
switch ( Z_TYPE_P ( arg ) ) {
case IS_NULL :
return " null " ;
case IS_LONG :
return " integer " ;
case IS_DOUBLE :
return " double " ;
case IS_STRING :
return " string " ;
case IS_ARRAY :
return " array " ;
case IS_OBJECT :
return " object " ;
case IS_BOOL :
return " boolean " ;
case IS_RESOURCE :
return " resource " ;
default :
return " unknown " ;
}
}
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
}
}
2001-07-10 02:51:29 +08:00
2003-03-26 15:44:11 +08:00
static char * zend_parse_arg_impl ( 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 ;
2001-08-13 08:28:18 +08:00
if ( ( type = is_numeric_string ( Z_STRVAL_PP ( arg ) , Z_STRLEN_PP ( arg ) , p , & d , 0 ) ) = = 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 ;
2001-08-13 08:28:18 +08:00
if ( ( type = is_numeric_string ( Z_STRVAL_PP ( arg ) , Z_STRLEN_PP ( arg ) , & l , p , 0 ) ) = = 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 ;
case IS_ARRAY :
case IS_OBJECT :
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 " ;
}
} else
* p = * arg ;
}
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 " ;
}
} else
* p = * arg ;
}
break ;
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 " ;
}
} else
* p = * arg ;
}
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 ;
} else {
2003-08-21 23:24:33 +08:00
return ce ? ce - > name : " 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 ;
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 ;
2003-03-26 15:44:11 +08:00
expected_type = zend_parse_arg_impl ( arg , va , spec TSRMLS_CC ) ;
2001-07-10 02:51:29 +08:00
if ( expected_type ) {
if ( ! quiet ) {
2003-01-27 07:15:30 +08:00
zend_error ( E_WARNING , " %s() expects parameter %d to be %s, %s given " ,
2001-07-30 15:43:02 +08:00
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 ;
}
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 ' :
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 " ,
2001-07-30 15:43:02 +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 ;
1999-04-08 02:10:10 +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 ;
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
2003-02-03 07:30:14 +08:00
ZEND_API int zend_parse_method_parameters_ex ( int flags , int num_args TSRMLS_DC , zval * this_ptr , char * type_spec , zend_class_entry * ce , void * * object , . . . )
{
void * * arg_stack = EG ( argument_stack ) . top_element ;
va_list va ;
int retval ;
int quiet = flags & ZEND_PARSE_PARAMS_QUIET ;
* object = this_ptr ;
if ( ! * object ) {
zval * * parameter ;
if ( zend_get_parameters_ex ( 1 , & parameter ) ! = SUCCESS ) {
if ( ! quiet ) {
zend_error ( E_WARNING , " %s() expects an object of class %s as first parameter, none was given " ,
get_active_function_name ( TSRMLS_C ) , ce - > name ) ;
}
return FAILURE ;
} else {
2003-08-02 19:43:55 +08:00
if ( Z_TYPE_PP ( parameter ) = = IS_OBJECT & &
instanceof_function ( Z_OBJCE_PP ( parameter ) , ce TSRMLS_CC ) ) {
* object = * parameter ;
} else {
2003-02-03 07:30:14 +08:00
if ( ! quiet ) {
zend_error ( E_WARNING , " %s() expects parameter 1 to be %s, %s given " ,
get_active_function_name ( TSRMLS_C ) , ce - > name ,
zend_zval_type_name ( * parameter ) ) ;
}
return FAILURE ;
}
EG ( argument_stack ) . top_element + + ;
}
}
2003-03-14 04:41:58 +08:00
va_start ( va , object ) ;
2003-02-03 07:30:14 +08:00
retval = zend_parse_va_args ( num_args , type_spec , & va , flags TSRMLS_CC ) ;
va_end ( va ) ;
EG ( argument_stack ) . top_element = arg_stack ;
return retval ;
}
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 * ) ;
zval member ;
TSRMLS_FETCH ( ) ;
ZVAL_STRINGL ( & member , hash_key - > arKey , hash_key - > nKeyLength - 1 , 0 ) ;
obj_ht - > write_property ( obj , & member , * value TSRMLS_CC ) ;
}
return ZEND_HASH_APPLY_KEEP ;
}
/* This function should be called after the constructor has been called
* 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 ) ;
}
}
/* This function requires 'properties' to contain all props declared in the
* class and all props being public . If only a subset is given or the class
* 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
1999-11-22 02:11:10 +08:00
if ( ! class_type - > constants_updated ) {
2001-07-31 12:53:54 +08:00
zend_hash_apply_with_argument ( & class_type - > default_properties , ( apply_func_arg_t ) zval_update_constant , ( void * ) 1 TSRMLS_CC ) ;
1999-11-22 02:11:10 +08:00
class_type - > constants_updated = 1 ;
}
1999-12-28 03:07:33 +08:00
2001-08-12 02:04:07 +08:00
arg - > type = IS_OBJECT ;
2002-09-15 15:45:26 +08:00
if ( class_type - > create_object = = NULL ) {
2003-03-26 14:32:53 +08:00
arg - > value . obj = 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 ) ;
zend_hash_init ( object - > properties , 0 , NULL , ZVAL_PTR_DTOR , 0 ) ;
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 {
2002-02-14 17:20:51 +08:00
arg - > value . obj = 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 ) ;
return zend_hash_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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_NULL ( tmp ) ;
return zend_hash_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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_BOOL ( tmp , b ) ;
1999-10-04 19:42:46 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_RESOURCE ( tmp , r ) ;
return zend_hash_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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_DOUBLE ( tmp , d ) ;
1999-04-08 02:10:10 +08:00
2001-01-21 03:16:38 +08:00
return zend_hash_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 ;
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_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 ;
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
2001-01-21 03:16:38 +08:00
return zend_hash_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
{
2001-01-21 03:16:38 +08:00
return zend_hash_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
2001-07-11 17:33:41 +08:00
ZEND_API int add_index_long ( zval * arg , uint 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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_index_null ( zval * arg , uint 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
2001-07-11 17:33:41 +08:00
ZEND_API int add_index_bool ( zval * arg , uint index , int b )
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 ) ;
2001-01-23 23:30:18 +08:00
ZVAL_BOOL ( tmp , b ) ;
2001-01-21 03:16:38 +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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_index_resource ( zval * arg , uint index , int r )
1999-10-04 19:42:46 +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_RESOURCE ( tmp , r ) ;
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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_index_double ( zval * arg , uint index , double d )
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_DOUBLE ( tmp , d ) ;
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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_index_string ( zval * arg , uint index , char * str , 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_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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_index_stringl ( zval * arg , uint 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 ;
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
2001-07-11 17:33:41 +08:00
ZEND_API int add_index_zval ( zval * arg , uint 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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_LONG ( tmp , n ) ;
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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_NULL ( tmp ) ;
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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_BOOL ( tmp , b ) ;
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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_RESOURCE ( tmp , r ) ;
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 ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_DOUBLE ( tmp , d ) ;
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 ;
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_STRING ( tmp , str , duplicate ) ;
return zend_hash_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 ;
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
2001-01-21 03:16:38 +08:00
return zend_hash_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_index_long ( zval * arg , uint index , long l , void * * dest )
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_LONG ( tmp , l ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( 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_index_double ( zval * arg , uint index , double d , void * * dest )
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_DOUBLE ( tmp , d ) ;
return zend_hash_index_update ( Z_ARRVAL_P ( arg ) , index , ( 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_index_string ( zval * arg , uint 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 ;
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
}
2001-07-11 17:33:41 +08:00
ZEND_API int add_get_index_stringl ( zval * arg , uint 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 ;
2003-01-14 20:15:09 +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 ) ;
2003-01-14 23:12:35 +08:00
ZVAL_STRINGL ( & z_key , key , key_len - 1 , 0 ) ;
2001-01-21 03:16:38 +08:00
2003-01-14 20:15:09 +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 */
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 ;
2003-01-14 20:15:09 +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 ) ;
2003-01-14 23:12:35 +08:00
ZVAL_STRINGL ( & z_key , key , key_len - 1 , 0 ) ;
2003-01-14 20:15:09 +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 */
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 ;
2003-01-14 20:15:09 +08:00
zval z_key ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_NULL ( tmp ) ;
2003-01-14 23:12:35 +08:00
ZVAL_STRINGL ( & z_key , key , key_len - 1 , 0 ) ;
2003-01-14 20:15:09 +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 */
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 ;
2003-01-14 20:15:09 +08:00
zval z_key ;
2001-01-21 03:16:38 +08:00
MAKE_STD_ZVAL ( tmp ) ;
ZVAL_RESOURCE ( tmp , n ) ;
2003-01-14 23:12:35 +08:00
ZVAL_STRINGL ( & z_key , key , key_len - 1 , 0 ) ;
2001-08-07 11:17:33 +08:00
2003-01-14 20:15:09 +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 */
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 ;
2003-01-14 20:15:09 +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 ) ;
2003-01-14 23:12:35 +08:00
ZVAL_STRINGL ( & z_key , key , key_len - 1 , 0 ) ;
2001-08-07 11:17:33 +08:00
2003-01-14 20:15:09 +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 */
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 ;
2003-01-14 20:15:09 +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
2003-01-14 23:12:35 +08:00
ZVAL_STRINGL ( & z_key , key , key_len - 1 , 0 ) ;
2003-01-14 20:15:09 +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 */
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 ;
2003-01-14 20:15:09 +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 ) ;
2003-01-14 23:12:35 +08:00
ZVAL_STRINGL ( & z_key , key , key_len - 1 , 0 ) ;
2003-01-14 20:15:09 +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 */
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
{
2003-01-14 20:15:09 +08:00
zval z_key ;
2003-01-01 20:38:55 +08:00
2003-01-14 23:12:35 +08:00
ZVAL_STRINGL ( & z_key , key , key_len - 1 , 0 ) ;
2003-01-14 20:15:09 +08:00
Z_OBJ_HANDLER_P ( arg , write_property ) ( arg , & z_key , value TSRMLS_CC ) ;
return SUCCESS ;
2001-01-21 03:16:38 +08:00
}
1999-04-08 02:10:10 +08:00
2000-02-04 02:51:33 +08:00
ZEND_API int zend_startup_module ( zend_module_entry * module )
1999-04-08 02:10:10 +08:00
{
if ( module ) {
module - > module_number = zend_next_free_module ( ) ;
if ( module - > module_startup_func ) {
2001-07-27 18:10:39 +08:00
TSRMLS_FETCH ( ) ;
2000-02-05 23:11:24 +08:00
2001-07-27 18:10:39 +08:00
if ( module - > module_startup_func ( MODULE_PERSISTENT , module - > module_number TSRMLS_CC ) = = FAILURE ) {
2001-08-11 23:56:40 +08:00
zend_error ( E_CORE_ERROR , " Unable to start %s module " , module - > name ) ;
1999-04-08 02:10:10 +08:00
return FAILURE ;
}
}
module - > type = MODULE_PERSISTENT ;
1999-04-21 11:49:09 +08:00
zend_register_module ( module ) ;
1999-04-08 02:10:10 +08:00
}
return SUCCESS ;
}
/* registers all functions in *library_functions in the function hash */
2002-11-24 04:44:12 +08:00
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 ;
2003-01-10 22:41:53 +08:00
zend_function * ctor = NULL , * dtor = NULL , * clone = NULL ;
2003-03-20 05:07:49 +08:00
char * lowercase_name ;
2003-06-02 20:13:11 +08:00
int fname_len ;
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 ;
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 ;
internal_function - > pass_rest_by_reference = ptr - > arg_info [ 0 ] . pass_by_reference ;
} else {
internal_function - > arg_info = NULL ;
internal_function - > num_args = 0 ;
internal_function - > pass_rest_by_reference = 0 ;
}
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 ) ) {
2003-08-17 08:57:35 +08:00
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 ) ;
2003-08-24 19:07:30 +08:00
internal_function - > fn_flags | = ZEND_ACC_PUBLIC ;
} 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 ;
}
2003-08-17 08:57:35 +08:00
if ( ptr - > flags & ZEND_ACC_ABSTRACT ) {
if ( scope ) {
scope - > ce_flags | = ZEND_ACC_ABSTRACT ;
}
} else {
if ( ! internal_function - > handler ) {
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 .
*/
if ( ! strcmp ( ptr - > fname , scope - > name ) & & ! ctor ) {
ctor = reg_function ;
} else if ( ! strcmp ( ptr - > fname , ZEND_CONSTRUCTOR_FUNC_NAME ) ) {
ctor = reg_function ;
} else if ( ! strcmp ( ptr - > fname , ZEND_DESTRUCTOR_FUNC_NAME ) ) {
dtor = reg_function ;
} else if ( ! strcmp ( ptr - > fname , ZEND_CLONE_FUNC_NAME ) ) {
clone = reg_function ;
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 */
while ( ptr - > fname ) {
1999-05-28 20:06:59 +08:00
if ( zend_hash_exists ( target_function_table , ptr - > fname , strlen ( ptr - > fname ) + 1 ) ) {
2001-08-11 23:56:40 +08:00
zend_error ( error_type , " Function registration failed - duplicate name - %s " , 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 ;
2003-08-23 23:38:58 +08:00
if ( ctor ) {
ctor - > common . fn_flags | = ZEND_ACC_CTOR ;
2003-09-02 21:26:25 +08:00
if ( ctor - > common . fn_flags & ZEND_ACC_STATIC ) {
zend_error ( error_type , " Constructor %s::%s cannot be static " , ctor - > common . scope - > name , ctor - > common . function_name ) ;
}
2003-08-23 23:38:58 +08:00
}
if ( dtor ) {
dtor - > common . fn_flags | = ZEND_ACC_DTOR ;
2003-09-02 21:26:25 +08:00
if ( dtor - > common . fn_flags & ZEND_ACC_STATIC ) {
zend_error ( error_type , " Destructor %s::%s cannot be static " , dtor - > common . scope - > name , dtor - > common . function_name ) ;
}
2003-08-23 23:38:58 +08:00
}
2003-01-10 22:41:53 +08:00
}
1999-04-08 02:10:10 +08:00
return SUCCESS ;
}
/* count=-1 means erase all functions, otherwise,
* erase the first count functions
*/
2001-07-30 09:48:22 +08:00
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 + + ;
}
}
1999-04-21 11:49:09 +08:00
ZEND_API int zend_register_module ( zend_module_entry * module )
1999-04-08 02:10:10 +08:00
{
2001-07-30 09:48:22 +08:00
TSRMLS_FETCH ( ) ;
1999-04-08 02:10:10 +08:00
#if 0
2001-08-11 23:56:40 +08:00
zend_printf ( " %s: Registering module %d \n " , module - > name , module - > module_number ) ;
1999-04-08 02:10:10 +08:00
# endif
2002-11-24 04:44:12 +08:00
if ( module - > functions & & zend_register_functions ( NULL , module - > functions , NULL , module - > type TSRMLS_CC ) = = FAILURE ) {
2001-08-11 23:56:40 +08:00
zend_error ( E_CORE_WARNING , " %s: Unable to register functions, unable to load " , module - > name ) ;
1999-04-08 02:10:10 +08:00
return FAILURE ;
}
module - > module_started = 1 ;
2001-08-11 23:56:40 +08:00
return zend_hash_add ( & module_registry , module - > name , strlen ( module - > name ) + 1 , ( void * ) module , sizeof ( zend_module_entry ) , NULL ) ;
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 ) ;
2003-07-31 00:13:52 +08:00
if ( module - > request_shutdown_func ) {
2001-07-30 14:12:15 +08:00
module - > request_shutdown_func ( module - > type , module - > module_number TSRMLS_CC ) ;
2003-07-31 00:13:52 +08:00
}
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
}
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
# if HAVE_LIBDL
if ( module - > handle ) {
dlclose ( module - > handle ) ;
}
# 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 ;
}
/* for persistent modules - call request shutdown and flag NOT to erase
2000-04-25 00:04:13 +08:00
* for temporary modules - do nothing , and flag to erase
1999-04-08 02:10:10 +08:00
*/
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
{
2002-11-30 19:20:25 +08:00
switch ( module - > type ) {
2000-04-24 23:49:23 +08:00
case MODULE_PERSISTENT :
2000-04-25 00:04:13 +08:00
if ( module - > request_shutdown_func ) {
#if 0
2001-08-11 23:56:40 +08:00
zend_printf ( " %s: Request shutdown \n " , module - > name ) ;
2000-04-25 00:04:13 +08:00
# endif
2001-07-30 14:12:15 +08:00
module - > request_shutdown_func ( module - > type , module - > module_number TSRMLS_CC ) ;
2000-04-25 00:04:13 +08:00
}
1999-04-08 02:10:10 +08:00
return 0 ;
break ;
case MODULE_TEMPORARY :
return 1 ;
break ;
}
return 0 ;
}
/* return the next free module number */
int zend_next_free_module ( void )
{
return + + module_count ;
}
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 ) {
2000-11-03 03:27:55 +08:00
zend_do_inheritance ( register_class , parent_ce ) ;
2000-06-09 22:40:14 +08:00
}
return register_class ;
}
1999-04-08 02:10:10 +08:00
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
{
2002-03-12 18:08:47 +08:00
zend_class_entry * class_entry = malloc ( sizeof ( zend_class_entry ) ) ;
2003-05-22 06:57:51 +08:00
char * lowercase_name = malloc ( orig_class_entry - > name_length + 1 ) ;
2002-03-12 18:08:47 +08:00
* class_entry = * orig_class_entry ;
1999-04-08 02:10:10 +08:00
class_entry - > type = ZEND_INTERNAL_CLASS ;
2003-02-16 19:34:49 +08:00
zend_initialize_class_data ( class_entry , 0 TSRMLS_CC ) ;
2000-02-03 06:23:37 +08:00
1999-05-28 20:06:59 +08:00
if ( class_entry - > builtin_functions ) {
2002-11-24 04:44:12 +08:00
zend_register_functions ( class_entry , class_entry - > builtin_functions , & class_entry - > function_table , MODULE_PERSISTENT TSRMLS_CC ) ;
1999-05-28 20:06:59 +08:00
}
2000-02-03 06:23:37 +08:00
2003-05-22 06:57:51 +08:00
zend_str_tolower_copy ( lowercase_name , orig_class_entry - > name , class_entry - > name_length ) ;
2002-03-12 18:08:47 +08:00
zend_hash_update ( CG ( class_table ) , lowercase_name , class_entry - > name_length + 1 , & class_entry , sizeof ( zend_class_entry * ) , NULL ) ;
2001-12-01 16:46:02 +08:00
free ( lowercase_name ) ;
2002-03-12 18:08:47 +08:00
return class_entry ;
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
{
HashTable * symbol_table ;
va_list symbol_table_list ;
if ( num_symbol_tables < = 0 ) return FAILURE ;
symbol - > is_ref = is_ref ;
va_start ( symbol_table_list , num_symbol_tables ) ;
2001-04-28 02:53:25 +08:00
while ( num_symbol_tables - - > 0 ) {
1999-12-05 00:50:18 +08:00
symbol_table = va_arg ( symbol_table_list , HashTable * ) ;
2000-03-24 19:12:30 +08:00
zend_hash_update ( symbol_table , name , name_length + 1 , & symbol , sizeof ( zval * ) , NULL ) ;
1999-12-05 00:50:18 +08:00
zval_add_ref ( & symbol ) ;
}
va_end ( symbol_table_list ) ;
return SUCCESS ;
}
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 ) ) ;
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 ;
zend_register_internal_class ( disabled_class TSRMLS_CC ) ;
return 1 ;
}
2001-03-12 11:08:28 +08:00
zend_bool zend_is_callable ( zval * callable , zend_bool syntax_only , char * * callable_name )
2001-02-01 13:01:26 +08:00
{
char * lcname ;
2002-04-24 02:06:54 +08:00
zend_bool retval = 0 ;
2001-07-27 18:10:39 +08:00
TSRMLS_FETCH ( ) ;
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 :
2001-05-10 04:07:49 +08:00
if ( callable_name )
* callable_name = estrndup ( Z_STRVAL_P ( callable ) , Z_STRLEN_P ( callable ) ) ;
2001-03-12 11:08:28 +08:00
if ( syntax_only )
return 1 ;
2003-05-22 05:59:40 +08:00
lcname = zend_str_tolower_dup ( Z_STRVAL_P ( callable ) , Z_STRLEN_P ( callable ) ) ;
2001-03-12 11:08:28 +08:00
if ( zend_hash_exists ( EG ( function_table ) , lcname , Z_STRLEN_P ( callable ) + 1 ) )
2001-02-01 13:01:26 +08:00
retval = 1 ;
efree ( lcname ) ;
break ;
case IS_ARRAY :
{
zval * * method ;
zval * * obj ;
2002-03-12 18:08:47 +08:00
zend_class_entry * ce = NULL , * * pce ;
2002-04-24 02:06:54 +08:00
zend_uint callable_name_len ;
2001-02-01 13:01:26 +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 ;
callable_name_len = Z_STRLEN_PP ( obj ) + Z_STRLEN_PP ( method ) + sizeof ( " :: " ) ;
ptr = * callable_name = emalloc ( callable_name_len ) ;
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 ) ;
}
if ( syntax_only )
return 1 ;
2003-05-22 05:59:40 +08:00
lcname = zend_str_tolower_dup ( Z_STRVAL_PP ( obj ) , Z_STRLEN_PP ( obj ) ) ;
2003-06-09 18:55:37 +08:00
2003-07-01 04:22:35 +08:00
if ( EG ( active_op_array ) & & strcmp ( lcname , " self " ) = = 0 ) {
2003-06-09 18:55:37 +08:00
ce = EG ( active_op_array ) - > scope ;
2003-07-01 04:22:35 +08:00
} else if ( strcmp ( lcname , " parent " ) = = 0 & & EG ( active_op_array ) & & EG ( active_op_array ) - > scope ) {
2003-06-09 18:55:37 +08:00
ce = EG ( active_op_array ) - > scope - > parent ;
} else if ( zend_lookup_class ( lcname , Z_STRLEN_PP ( obj ) , & pce TSRMLS_CC ) = = SUCCESS ) {
2002-03-12 18:08:47 +08:00
ce = * pce ;
}
2001-03-12 11:08:28 +08:00
efree ( lcname ) ;
2001-03-13 00:27:26 +08:00
} else {
2002-02-07 22:08:43 +08:00
ce = Z_OBJCE_PP ( obj ) ; /* ??? */
2001-05-10 04:07:49 +08:00
if ( callable_name ) {
char * ptr ;
callable_name_len = ce - > name_length + Z_STRLEN_PP ( method ) + sizeof ( " :: " ) ;
ptr = * callable_name = emalloc ( callable_name_len ) ;
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 ) ;
}
if ( syntax_only )
return 1 ;
2001-03-13 00:27:26 +08:00
}
2001-05-10 04:07:49 +08:00
if ( ce ) {
2003-05-22 05:59:40 +08:00
lcname = zend_str_tolower_dup ( Z_STRVAL_PP ( method ) , Z_STRLEN_PP ( method ) ) ;
2003-07-03 17:18:41 +08:00
if ( zend_hash_exists ( & ce - > function_table , lcname , Z_STRLEN_PP ( method ) + 1 ) ) {
2001-05-10 04:07:49 +08:00
retval = 1 ;
2003-07-03 17:18:41 +08:00
}
/* check for __call too */
if ( retval = = 0 & & ce - > __call ! = 0 ) {
retval = 1 ;
}
2001-05-10 04:07:49 +08:00
efree ( lcname ) ;
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 ) ;
2003-07-03 17:18:41 +08:00
}
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 ) ) ;
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
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 ,
( void * * ) & module ) = = FAILURE ) {
return NULL ;
}
return module - > version ;
}
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 )
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 ) {
target_symbol_table = ce - > static_members ;
} 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-09-04 02:01:22 +08:00
} else {
zval_update_constant ( & property , ( void * ) 1 TSRMLS_CC ) ;
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 ;
2003-08-24 03:37:39 +08:00
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 ;
2003-08-24 03:37:39 +08:00
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 ;
mangle_property_name ( & prot_name , & prot_name_length , " * " , 1 , name , name_length , ce - > type & ZEND_INTERNAL_CLASS ) ;
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 ) ;
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 ;
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
}
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 ;
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
}
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 ) ;
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
}
ZEND_API void zend_update_property ( zend_class_entry * scope , zval * object , char * name , int name_length , zval * value TSRMLS_DC )
{
zval property ;
zend_class_entry * old_scope = EG ( scope ) ;
EG ( scope ) = scope ;
if ( ! Z_OBJ_HT_P ( object ) - > write_property ) {
zend_error ( E_CORE_ERROR , " Property %s of class %s cannot be updated " , Z_OBJCE_P ( object ) - > name , name ) ;
}
ZVAL_STRINGL ( & property , name , name_length , 0 ) ;
Z_OBJ_HT_P ( object ) - > write_property ( object , & property , value TSRMLS_CC ) ;
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 ) ;
}
ZEND_API void zend_update_property_long ( zend_class_entry * scope , zval * object , char * name , int name_length , long value TSRMLS_DC )
{
zval * tmp ;
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 ) ;
}
ZEND_API void zend_update_property_string ( zend_class_entry * scope , zval * object , char * name , int name_length , char * value TSRMLS_DC )
{
zval * tmp ;
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 ) ;
}
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 )
{
zval property , * value ;
zend_class_entry * old_scope = EG ( scope ) ;
EG ( scope ) = scope ;
if ( ! Z_OBJ_HT_P ( object ) - > read_property ) {
zend_error ( E_CORE_ERROR , " Property %s of class %s cannot be read " , Z_OBJCE_P ( object ) - > name , name ) ;
}
ZVAL_STRINGL ( & property , name , name_length , 0 ) ;
value = Z_OBJ_HT_P ( object ) - > read_property ( object , & property , silent TSRMLS_CC ) ;
EG ( scope ) = old_scope ;
return value ;
}
2003-02-01 09:49:15 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/