From d29a4fd2dd3b5d4cf6e80b602544d7b71d794e76 Mon Sep 17 00:00:00 2001 From: "Mark A. Hershberger" Date: Wed, 25 Mar 2009 00:36:21 -0400 Subject: Imported Upstream version 5.2.0 --- Zend/zend_API.c | 483 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 331 insertions(+), 152 deletions(-) (limited to 'Zend/zend_API.c') diff --git a/Zend/zend_API.c b/Zend/zend_API.c index a2c8c0031..8381f1187 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -5,7 +5,7 @@ | Copyright (c) 1998-2006 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | + | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.zend.com/license/2_00.txt. | | If you did not receive a copy of the Zend license and are unable to | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.c,v 1.296.2.27 2006/04/20 07:30:38 dmitry Exp $ */ +/* $Id: zend_API.c,v 1.296.2.27.2.23 2006/10/03 11:10:32 dmitry Exp $ */ #include "zend.h" #include "zend_execute.h" @@ -196,7 +196,7 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TS while (param_count-->0) { zval **param = (zval **) p-(arg_count--); zval_add_ref(param); - add_next_index_zval(argument_array, *param); + add_next_index_zval(argument_array, *param); } return SUCCESS; @@ -214,38 +214,35 @@ ZEND_API void zend_wrong_param_count(TSRMLS_D) /* Argument parsing API -- andrei */ -ZEND_API char *zend_zval_type_name(zval *arg) +ZEND_API char *zend_get_type_by_const(int type) { - switch (Z_TYPE_P(arg)) { - case IS_NULL: - return "null"; - + switch(type) { + case IS_BOOL: + return "boolean"; 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"; - + case IS_NULL: + return "null"; + case IS_ARRAY: + return "array"; default: return "unknown"; } } +ZEND_API char *zend_zval_type_name(zval *arg) +{ + return zend_get_type_by_const(Z_TYPE_P(arg)); +} + ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC) { if (Z_OBJ_HT_P(zobject)->get_class_entry) { @@ -262,7 +259,7 @@ ZEND_API int zend_get_object_classname(zval *object, char **class_name, zend_uin 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); - + *class_name = ce->name; *class_name_len = ce->name_length; return 1; @@ -270,6 +267,44 @@ ZEND_API int zend_get_object_classname(zval *object, char **class_name, zend_uin return 0; } +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; +} static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **spec TSRMLS_DC) { @@ -376,17 +411,12 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp *p = Z_STRVAL_PP(arg); *pl = Z_STRLEN_PP(arg); break; - case IS_OBJECT: { - if (Z_OBJ_HANDLER_PP(arg, cast_object)) { - SEPARATE_ZVAL_IF_NOT_REF(arg); - if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_STRING, 0 TSRMLS_CC) == SUCCESS) { - *pl = Z_STRLEN_PP(arg); - *p = Z_STRVAL_PP(arg); - break; - } + + case IS_OBJECT: + if (parse_arg_object_to_string(arg, p, pl, IS_STRING TSRMLS_CC) == SUCCESS) { + break; } - } - + case IS_ARRAY: case IS_RESOURCE: default: @@ -426,8 +456,9 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp } else { return "resource"; } - } else + } else { *p = *arg; + } } break; @@ -440,8 +471,9 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp } else { return "array"; } - } else + } else { *p = *arg; + } } break; @@ -469,8 +501,9 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp } else { return "object"; } - } else + } else { *p = *arg; + } } break; @@ -485,8 +518,10 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp } else { if (Z_TYPE_PP(arg) == IS_NULL && return_null) { *p = NULL; + } else if (ce) { + return ce->name; } else { - return ce ? ce->name : "object"; + return "object"; } } } @@ -497,6 +532,10 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp zend_class_entry **lookup, **pce = va_arg(*va, zend_class_entry **); zend_class_entry *ce_base = *pce; + if (return_null && Z_TYPE_PP(arg) == IS_NULL) { + *pce = NULL; + break; + } convert_to_string_ex(arg); if (zend_lookup_class(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &lookup TSRMLS_CC) == FAILURE) { *pce = NULL; @@ -514,7 +553,7 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp return ""; } } - if (!*pce && !return_null) { + if (!*pce) { 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", @@ -527,6 +566,22 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp } break; + 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"; + } + } + case 'z': { zval **p = va_arg(*va, zval **); @@ -562,7 +617,7 @@ static int zend_parse_arg(int arg_num, zval **arg, va_list *va, char **spec, int expected_type = zend_parse_arg_impl(arg_num, arg, va, spec TSRMLS_CC); if (expected_type) { - if (!quiet) { + if (!quiet && *expected_type) { char *space; char *class_name = get_active_class_name(&space TSRMLS_CC); @@ -572,7 +627,7 @@ static int zend_parse_arg(int arg_num, zval **arg, va_list *va, char **spec, int } return FAILURE; } - + return SUCCESS; } @@ -596,6 +651,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl case 'o': case 'O': case 'z': case 'Z': case 'C': case 'h': + case 'f': max_num_args++; break; @@ -646,7 +702,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl if (num_args > arg_count) { zend_error(E_WARNING, "%s(): could not obtain parameters for parsing", - get_active_function_name(TSRMLS_C)); + get_active_function_name(TSRMLS_C)); return FAILURE; } @@ -669,7 +725,7 @@ ZEND_API int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *t { va_list va; int retval; - + va_start(va, type_spec); retval = zend_parse_va_args(num_args, type_spec, &va, flags TSRMLS_CC); va_end(va); @@ -681,7 +737,7 @@ ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...) { va_list va; int retval; - + va_start(va, type_spec); retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC); va_end(va); @@ -786,7 +842,7 @@ static int zend_merge_property(zval **value, int num_args, va_list args, zend_ha } -/* This function should be called after the constructor has been called +/* 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) { @@ -826,7 +882,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC #else ALLOC_HASHTABLE(class_type->static_members); #endif - zend_hash_init(CE_STATIC_MEMBERS(class_type), 0, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(CE_STATIC_MEMBERS(class_type), zend_hash_num_elements(&class_type->default_static_members), NULL, ZVAL_PTR_DTOR, 0); 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) { @@ -846,7 +902,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)q, sizeof(zval*), NULL); } else { zval *q; - + ALLOC_ZVAL(q); *q = **p; INIT_PZVAL(q); @@ -865,7 +921,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC /* 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 + * 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(). */ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC) @@ -879,19 +935,19 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type } zend_update_class_constants(class_type TSRMLS_CC); - - arg->type = IS_OBJECT; + + Z_TYPE_P(arg) = IS_OBJECT; if (class_type->create_object == NULL) { - arg->value.obj = zend_objects_new(&object, class_type TSRMLS_CC); + Z_OBJVAL_P(arg) = zend_objects_new(&object, class_type TSRMLS_CC); if (properties) { object->properties = properties; } else { ALLOC_HASHTABLE_REL(object->properties); - zend_hash_init(object->properties, 0, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(object->properties, zend_hash_num_elements(&class_type->default_properties), 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 *)); } } else { - arg->value.obj = class_type->create_object(class_type TSRMLS_CC); + Z_OBJVAL_P(arg) = class_type->create_object(class_type TSRMLS_CC); } return SUCCESS; } @@ -920,24 +976,24 @@ ZEND_API int add_assoc_long_ex(zval *arg, char *key, uint key_len, long n) MAKE_STD_ZVAL(tmp); ZVAL_LONG(tmp, n); - + return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL); } ZEND_API int add_assoc_null_ex(zval *arg, char *key, uint key_len) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_NULL(tmp); - + return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL); } ZEND_API int add_assoc_bool_ex(zval *arg, char *key, uint key_len, int b) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_BOOL(tmp, b); @@ -947,10 +1003,10 @@ ZEND_API int add_assoc_bool_ex(zval *arg, char *key, uint key_len, int b) ZEND_API int add_assoc_resource_ex(zval *arg, char *key, uint key_len, int r) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_RESOURCE(tmp, r); - + return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL); } @@ -958,7 +1014,7 @@ ZEND_API int add_assoc_resource_ex(zval *arg, char *key, uint key_len, int r) ZEND_API int add_assoc_double_ex(zval *arg, char *key, uint key_len, double d) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_DOUBLE(tmp, d); @@ -969,7 +1025,7 @@ ZEND_API int add_assoc_double_ex(zval *arg, char *key, uint key_len, double d) ZEND_API int add_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, int duplicate) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_STRING(tmp, str, duplicate); @@ -980,7 +1036,7 @@ ZEND_API int add_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, ZEND_API int add_assoc_stringl_ex(zval *arg, char *key, uint key_len, char *str, uint length, int duplicate) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_STRINGL(tmp, str, length, duplicate); @@ -1017,10 +1073,10 @@ ZEND_API int add_index_null(zval *arg, ulong index) ZEND_API int add_index_bool(zval *arg, ulong index, int b) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_BOOL(tmp, b); - + return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL); } @@ -1028,10 +1084,10 @@ ZEND_API int add_index_bool(zval *arg, ulong index, int b) ZEND_API int add_index_resource(zval *arg, ulong index, int r) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_RESOURCE(tmp, r); - + return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL); } @@ -1039,10 +1095,10 @@ ZEND_API int add_index_resource(zval *arg, ulong index, int r) ZEND_API int add_index_double(zval *arg, ulong index, double d) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_DOUBLE(tmp, d); - + return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL); } @@ -1050,7 +1106,7 @@ ZEND_API int add_index_double(zval *arg, ulong index, double d) ZEND_API int add_index_string(zval *arg, ulong index, char *str, int duplicate) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_STRING(tmp, str, duplicate); @@ -1061,7 +1117,7 @@ ZEND_API int add_index_string(zval *arg, ulong index, char *str, int duplicate) ZEND_API int add_index_stringl(zval *arg, ulong index, char *str, uint length, int duplicate) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_STRINGL(tmp, str, length, duplicate); @@ -1078,10 +1134,10 @@ ZEND_API int add_index_zval(zval *arg, ulong index, zval *value) ZEND_API int add_next_index_long(zval *arg, long n) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_LONG(tmp, n); - + return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL); } @@ -1089,10 +1145,10 @@ ZEND_API int add_next_index_long(zval *arg, long n) ZEND_API int add_next_index_null(zval *arg) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_NULL(tmp); - + return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL); } @@ -1100,10 +1156,10 @@ ZEND_API int add_next_index_null(zval *arg) ZEND_API int add_next_index_bool(zval *arg, int b) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_BOOL(tmp, b); - + return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL); } @@ -1111,10 +1167,10 @@ ZEND_API int add_next_index_bool(zval *arg, int b) ZEND_API int add_next_index_resource(zval *arg, int r) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_RESOURCE(tmp, r); - + return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL); } @@ -1122,10 +1178,10 @@ ZEND_API int add_next_index_resource(zval *arg, int r) ZEND_API int add_next_index_double(zval *arg, double d) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_DOUBLE(tmp, d); - + return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL); } @@ -1161,10 +1217,10 @@ ZEND_API int add_next_index_zval(zval *arg, zval *value) ZEND_API int add_get_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, void **dest, int duplicate) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_STRING(tmp, str, duplicate); - + return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), dest); } @@ -1172,7 +1228,7 @@ ZEND_API int add_get_assoc_string_ex(zval *arg, char *key, uint key_len, char *s ZEND_API int add_get_assoc_stringl_ex(zval *arg, char *key, uint key_len, char *str, uint length, void **dest, int duplicate) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_STRINGL(tmp, str, length, duplicate); @@ -1183,10 +1239,10 @@ ZEND_API int add_get_assoc_stringl_ex(zval *arg, char *key, uint key_len, char * ZEND_API int add_get_index_long(zval *arg, ulong index, long l, void **dest) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_LONG(tmp, l); - + return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest); } @@ -1194,10 +1250,10 @@ ZEND_API int add_get_index_long(zval *arg, ulong index, long l, void **dest) ZEND_API int add_get_index_double(zval *arg, ulong index, double d, void **dest) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_DOUBLE(tmp, d); - + return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest); } @@ -1205,7 +1261,7 @@ ZEND_API int add_get_index_double(zval *arg, ulong index, double d, void **dest) ZEND_API int add_get_index_string(zval *arg, ulong index, char *str, void **dest, int duplicate) { zval *tmp; - + MAKE_STD_ZVAL(tmp); ZVAL_STRING(tmp, str, duplicate); @@ -1385,13 +1441,24 @@ ZEND_API int zend_startup_module_ex(zend_module_entry *module TSRMLS_DC) zend_error(E_CORE_WARNING, "Cannot load module '%s' because required module '%s' is not loaded", module->name, dep->name); module->module_started = 0; return FAILURE; - } + } efree(lcname); } ++dep; } } + /* 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 + } + if (module->module_startup_func) { EG(current_module) = module; if (module->module_startup_func(module->type, module->module_number TSRMLS_CC)==FAILURE) { @@ -1409,7 +1476,7 @@ static void zend_sort_modules(void *base, size_t count, size_t siz, compare_func Bucket **b1 = base; Bucket **b2; Bucket **end = b1 + count; - Bucket *tmp; + Bucket *tmp; zend_module_entry *m, *r; while (b1 < end) { @@ -1425,14 +1492,14 @@ try_again: if (strcasecmp(dep->name, r->name) == 0) { tmp = *b1; *b1 = *b2; - *b2 = tmp; + *b2 = tmp; goto try_again; } b2++; } } dep++; - } + } } b1++; } @@ -1450,7 +1517,7 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TS int name_len; char *lcname; zend_module_entry *module_ptr; - + if (!module) { return NULL; } @@ -1473,7 +1540,7 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TS /* TODO: Check version relationship */ zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name); return NULL; - } + } efree(lcname); } ++dep; @@ -1490,12 +1557,15 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TS } efree(lcname); module = module_ptr; + EG(current_module) = module; if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type TSRMLS_CC)==FAILURE) { + EG(current_module) = NULL; zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name); return NULL; } + EG(current_module) = NULL; return module; } @@ -1518,7 +1588,7 @@ ZEND_API void zend_check_magic_method_implementation(zend_class_entry *ce, zend_ 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) { - zend_error(error_type, "Destuctor %s::%s() cannot take arguments", ce->name, ZEND_DESTRUCTOR_FUNC_NAME); + zend_error(error_type, "Destructor %s::%s() cannot take arguments", ce->name, ZEND_DESTRUCTOR_FUNC_NAME); } 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) { @@ -1543,7 +1613,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr int count=0, unload=0; HashTable *target_function_table = function_table; int error_type; - zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL; + zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__tostring = NULL; char *lowercase_name; int fname_len; char *lc_class_name = NULL; @@ -1611,6 +1681,9 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr scope->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; } } + 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); + } } else { if (scope && (scope->ce_flags & ZEND_ACC_INTERFACE)) { efree(lc_class_name); @@ -1652,6 +1725,8 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr clone = reg_function; } 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; + } 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; } 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))) { @@ -1689,6 +1764,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr scope->destructor = dtor; scope->clone = clone; scope->__call = __call; + scope->__tostring = __tostring; scope->__get = __get; scope->__set = __set; scope->__unset = __unset; @@ -1720,6 +1796,12 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr } __call->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC; } + 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; + } 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); @@ -1749,7 +1831,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr return SUCCESS; } -/* count=-1 means erase all functions, otherwise, +/* count=-1 means erase all functions, otherwise, * erase the first count functions */ ZEND_API void zend_unregister_functions(zend_function_entry *functions, int count, HashTable *function_table TSRMLS_DC) @@ -1778,7 +1860,7 @@ ZEND_API void zend_unregister_functions(zend_function_entry *functions, int coun ZEND_API int zend_startup_module(zend_module_entry *module) { TSRMLS_FETCH(); - + if ((module = zend_register_internal_module(module TSRMLS_CC)) != NULL && zend_startup_module_ex(module TSRMLS_CC) == SUCCESS) { return SUCCESS; @@ -1790,7 +1872,7 @@ ZEND_API int zend_startup_module(zend_module_entry *module) ZEND_API int zend_get_module_started(char *module_name) { zend_module_entry *module; - + return (zend_hash_find(&module_registry, module_name, strlen(module_name)+1, (void**)&module) == SUCCESS && module->module_started) ? SUCCESS : FAILURE; } @@ -1810,6 +1892,18 @@ void module_destructor(zend_module_entry *module) #endif module->module_shutdown_func(module->type, module->module_number TSRMLS_CC); } + + /* 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 + } + module->module_started=0; if (module->functions) { zend_unregister_functions(module->functions, -1, NULL TSRMLS_CC); @@ -1817,9 +1911,9 @@ void module_destructor(zend_module_entry *module) #if HAVE_LIBDL || defined(HAVE_MACH_O_DYLD_H) #if !(defined(NETWARE) && defined(APACHE_1_BUILD)) - if (module->handle) { - DL_UNLOAD(module->handle); - } + if (module->handle) { + DL_UNLOAD(module->handle); + } #endif #endif } @@ -1915,24 +2009,14 @@ ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *cla ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...) { zend_class_entry *interface_entry; - int ce_num = class_entry->num_interfaces, impl_num; va_list interface_list; va_start(interface_list, num_interfaces); - if (class_entry->type & ZEND_INTERNAL_CLASS) { - class_entry->interfaces = realloc(class_entry->interfaces, sizeof(zend_class_entry*) * (class_entry->num_interfaces+num_interfaces)); - } else { - class_entry->interfaces = erealloc(class_entry->interfaces, sizeof(zend_class_entry*) * (class_entry->num_interfaces+num_interfaces)); - } - while (num_interfaces--) { interface_entry = va_arg(interface_list, zend_class_entry *); - class_entry->interfaces[class_entry->num_interfaces++] = interface_entry; - } - impl_num = class_entry->num_interfaces; - while(ce_num < impl_num) { - zend_do_implement_interface(class_entry, class_entry->interfaces[ce_num++] TSRMLS_CC); + zend_do_implement_interface(class_entry, interface_entry TSRMLS_CC); } + va_end(interface_list); } @@ -1951,21 +2035,21 @@ ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *or ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...) { - HashTable *symbol_table; - va_list symbol_table_list; + HashTable *symbol_table; + va_list symbol_table_list; - if (num_symbol_tables <= 0) return FAILURE; + if (num_symbol_tables <= 0) return FAILURE; - symbol->is_ref = is_ref; + symbol->is_ref = is_ref; - 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; + 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; } @@ -2013,13 +2097,14 @@ ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_ { zend_class_entry *disabled_class; disabled_class = (zend_class_entry *) emalloc(sizeof(zend_class_entry)); - + zend_str_tolower(class_name, class_name_length); 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; + disabled_class->name_length = class_name_length; zend_register_internal_class(disabled_class TSRMLS_CC); return 1; } @@ -2032,7 +2117,7 @@ static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, ze zend_function *fptr; zend_class_entry **pce; HashTable *ftable; - + *ce_ptr = NULL; *fptr_ptr = NULL; @@ -2153,7 +2238,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char ** zend_class_entry *ce = NULL; zval **method; zval **obj; - + if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2 && zend_hash_index_find(Z_ARRVAL_P(callable), 0, (void **) &obj) == SUCCESS && zend_hash_index_find(Z_ARRVAL_P(callable), 1, (void **) &method) == SUCCESS && @@ -2188,7 +2273,7 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char ** efree(lcname); } else { ce = Z_OBJCE_PP(obj); /* TBFixed: what if it's overloaded? */ - + *zobj_ptr_ptr = obj; if (callable_name) { @@ -2264,15 +2349,105 @@ ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRML } +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) +{ + zval *retval, ***org_params = NULL; + int result, org_count = 0; + + 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; +} + + 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) { + (void**)&module) == FAILURE) { return NULL; } - return module->version; + return module->version; } @@ -2346,7 +2521,9 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, char *name, int name property_info.doc_comment = doc_comment; property_info.doc_comment_len = doc_comment_len; - + + property_info.ce = ce; + zend_hash_update(&ce->properties_info, name, name_length + 1, &property_info, sizeof(zend_property_info), NULL); return SUCCESS; @@ -2355,7 +2532,7 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, char *name, int name ZEND_API int zend_declare_property_null(zend_class_entry *ce, char *name, int name_length, int access_type TSRMLS_DC) { zval *property; - + if (ce->type & ZEND_INTERNAL_CLASS) { property = malloc(sizeof(zval)); } else { @@ -2368,7 +2545,7 @@ ZEND_API int zend_declare_property_null(zend_class_entry *ce, char *name, int na 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; - + if (ce->type & ZEND_INTERNAL_CLASS) { property = malloc(sizeof(zval)); } else { @@ -2382,7 +2559,7 @@ ZEND_API int zend_declare_property_bool(zend_class_entry *ce, char *name, int na ZEND_API int zend_declare_property_long(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC) { zval *property; - + if (ce->type & ZEND_INTERNAL_CLASS) { property = malloc(sizeof(zval)); } else { @@ -2396,7 +2573,7 @@ ZEND_API int zend_declare_property_long(zend_class_entry *ce, char *name, int na 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; - + if (ce->type & ZEND_INTERNAL_CLASS) { property = malloc(sizeof(zval)); } else { @@ -2411,7 +2588,7 @@ ZEND_API int zend_declare_property_string(zend_class_entry *ce, char *name, int { zval *property; int len = strlen(value); - + if (ce->type & ZEND_INTERNAL_CLASS) { property = malloc(sizeof(zval)); ZVAL_STRINGL(property, zend_strndup(value, len), len, 0); @@ -2426,7 +2603,7 @@ ZEND_API int zend_declare_property_string(zend_class_entry *ce, char *name, int 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; - + if (ce->type & ZEND_INTERNAL_CLASS) { property = malloc(sizeof(zval)); ZVAL_STRINGL(property, zend_strndup(value, value_len), value_len, 0); @@ -2523,7 +2700,7 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char * { zval *property; zend_class_entry *old_scope = EG(scope); - + EG(scope) = scope; if (!Z_OBJ_HT_P(object)->write_property) { @@ -2531,7 +2708,7 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char * 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 updated", name, class_name); } MAKE_STD_ZVAL(property); @@ -2556,7 +2733,7 @@ ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, c ZEND_API void zend_update_property_bool(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; @@ -2567,7 +2744,7 @@ ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, c 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; @@ -2578,7 +2755,7 @@ ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, c ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC) { zval *tmp; - + ALLOC_ZVAL(tmp); tmp->is_ref = 0; tmp->refcount = 0; @@ -2589,7 +2766,7 @@ ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, 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; @@ -2600,7 +2777,7 @@ ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, 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; - + ALLOC_ZVAL(tmp); tmp->is_ref = 0; tmp->refcount = 0; @@ -2612,7 +2789,7 @@ ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, in { zval **property; zend_class_entry *old_scope = EG(scope); - + EG(scope) = scope; property = zend_std_get_static_property(scope, name, name_length, 0 TSRMLS_CC); EG(scope) = old_scope; @@ -2622,7 +2799,7 @@ ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, in if (*property != value) { if (PZVAL_IS_REF(*property)) { zval_dtor(*property); - (*property)->type = value->type; + Z_TYPE_PP(property) = Z_TYPE_P(value); (*property)->value = value->value; if (value->refcount > 0) { zval_copy_ctor(*property); @@ -2656,7 +2833,7 @@ ZEND_API int zend_update_static_property_null(zend_class_entry *scope, char *nam ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC) { zval *tmp; - + ALLOC_ZVAL(tmp); tmp->is_ref = 0; tmp->refcount = 0; @@ -2667,7 +2844,7 @@ ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char *nam ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC) { zval *tmp; - + ALLOC_ZVAL(tmp); tmp->is_ref = 0; tmp->refcount = 0; @@ -2678,7 +2855,7 @@ ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char *nam ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char *name, int name_length, double value TSRMLS_DC) { zval *tmp; - + ALLOC_ZVAL(tmp); tmp->is_ref = 0; tmp->refcount = 0; @@ -2689,7 +2866,7 @@ ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char *n ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char *name, int name_length, char *value TSRMLS_DC) { zval *tmp; - + ALLOC_ZVAL(tmp); tmp->is_ref = 0; tmp->refcount = 0; @@ -2700,7 +2877,7 @@ ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char *n 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; - + ALLOC_ZVAL(tmp); tmp->is_ref = 0; tmp->refcount = 0; @@ -2712,7 +2889,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *n { zval *property, *value; zend_class_entry *old_scope = EG(scope); - + EG(scope) = scope; if (!Z_OBJ_HT_P(object)->read_property) { @@ -2722,10 +2899,12 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *n 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); } + MAKE_STD_ZVAL(property); ZVAL_STRINGL(property, name, name_length, 1); - value = Z_OBJ_HT_P(object)->read_property(object, property, silent TSRMLS_CC); + value = Z_OBJ_HT_P(object)->read_property(object, property, silent?BP_VAR_IS:BP_VAR_R TSRMLS_CC); zval_ptr_dtor(&property); + EG(scope) = old_scope; return value; } @@ -2734,7 +2913,7 @@ ZEND_API zval *zend_read_static_property(zend_class_entry *scope, char *name, in { zval **property; zend_class_entry *old_scope = EG(scope); - + EG(scope) = scope; property = zend_std_get_static_property(scope, name, name_length, silent TSRMLS_CC); EG(scope) = old_scope; -- cgit v1.2.3