From: Marcus Boerger Date: Tue, 9 May 2006 23:53:23 +0000 (+0000) Subject: - MFH as discussed X-Git-Tag: php-5.2.0RC1~632 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=637a40423cd7632b2800814c2ba3ad9b95bbd2f4;p=php - MFH as discussed . zend_exception_get_default() -> zend_exception_get_default(TSRMLS_D) . zend_get_error_exception() -> zend_get_error_exception(TSRMLS_D) . added E_RECOVERABLE_ERROR . added ZEND_TOSTRING_FUNC_NAME . added __tostring function cache to zend_class_entry . added ZEND_NAMED_ME . modified ZEND_ME_MAPPING to support method flags . added ZEND_MN . method entries now use prefix "zim_" instead of "zif_" . drop EG(ze1_compatibility_mode) . changed cast handler, now without (int should_free): typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type TSRMLS_DC); . changed get_iterator, now receives whether value is by ref: zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); . added zend_objects_store_add_ref_by_handle . added zend_objects_store_del_ref_by_handle . convert_to_explicit_type(pzv, type) --- diff --git a/Zend/zend.c b/Zend/zend.c index c6a9ec703c..66628e182b 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -77,7 +77,6 @@ static ZEND_INI_MH(OnUpdateErrorReporting) ZEND_INI_BEGIN() ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting) - STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals) #ifdef ZEND_MULTIBYTE STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) #endif @@ -221,19 +220,13 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop case IS_OBJECT: { TSRMLS_FETCH(); -#if 0 + /* Standard PHP objects */ if (Z_OBJ_HT_P(expr) == &std_object_handlers || !Z_OBJ_HT_P(expr)->cast_object) { - if (zend_std_cast_object_tostring(expr, expr_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) { + if (zend_std_cast_object_tostring(expr, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) { break; } zend_error(E_NOTICE, "Object of class %s could not be converted to string", Z_OBJCE_P(expr)->name); - } -#endif - if (Z_OBJ_HANDLER_P(expr, cast_object)) { - if(Z_OBJ_HANDLER_P(expr, cast_object)(expr, expr_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) { - break; - } } else { if(Z_OBJ_HANDLER_P(expr, get)) { zval *z = Z_OBJ_HANDLER_P(expr, get)(expr TSRMLS_CC); diff --git a/Zend/zend.h b/Zend/zend.h index 45a9e75742..189740a915 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -258,7 +258,6 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore # define zend_error_noreturn zend_error #endif - /* * zval */ @@ -320,7 +319,7 @@ struct _zend_class_entry { char type; char *name; zend_uint name_length; - struct _zend_class_entry *parent; + struct _zend_class_entry *parent; int refcount; zend_bool constants_updated; zend_uint ce_flags; @@ -341,6 +340,7 @@ struct _zend_class_entry { union _zend_function *__unset; union _zend_function *__isset; union _zend_function *__call; + union _zend_function *__tostring; union _zend_function *serialize_func; union _zend_function *unserialize_func; @@ -348,7 +348,7 @@ struct _zend_class_entry { /* handlers */ zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC); - zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object TSRMLS_DC); + zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* a class implements this interface */ /* serializer callbacks */ @@ -363,7 +363,7 @@ struct _zend_class_entry { zend_uint line_end; char *doc_comment; zend_uint doc_comment_len; - + struct _zend_module_entry *module; }; @@ -384,7 +384,7 @@ typedef struct _zend_utility_functions { char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC); } zend_utility_functions; - + typedef struct _zend_utility_values { char *import_use_extension; uint import_use_extension_length; @@ -430,7 +430,6 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length); #define OE_IS_OBJECT (1<<1) #define OE_IS_METHOD (1<<2) - int zend_startup(zend_utility_functions *utility_functions, char **extensions, int start_builtin_functions); void zend_shutdown(TSRMLS_D); void zend_register_standard_ini_entries(TSRMLS_D); @@ -562,7 +561,7 @@ END_EXTERN_C() #define INIT_PZVAL(z) \ (z)->refcount = 1; \ - (z)->is_ref = 0; + (z)->is_ref = 0; #define INIT_ZVAL(z) z = zval_used_for_init; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 0a9b8213a0..02bbd82671 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -154,25 +154,6 @@ ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_arr while (param_count-->0) { zval **value = (zval**)(p-arg_count); - if (EG(ze1_compatibility_mode) && Z_TYPE_PP(value) == IS_OBJECT) { - zval *value_ptr; - char *class_name; - zend_uint class_name_len; - int dup; - - dup = zend_get_object_classname(*value, &class_name, &class_name_len TSRMLS_CC); - - ALLOC_ZVAL(value_ptr); - *value_ptr = **value; - INIT_PZVAL(value_ptr); - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - if(!dup) { - efree(class_name); - } - value_ptr->value.obj = Z_OBJ_HANDLER_PP(value, clone_obj)(*value TSRMLS_CC); - zval_ptr_dtor(value); - *value = value_ptr; - } *(argument_array++) = value; arg_count--; } @@ -196,7 +177,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; @@ -262,7 +243,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; @@ -376,17 +357,18 @@ 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) { + if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, IS_STRING TSRMLS_CC) == SUCCESS) { *pl = Z_STRLEN_PP(arg); *p = Z_STRVAL_PP(arg); break; } } } - + case IS_ARRAY: case IS_RESOURCE: default: @@ -426,8 +408,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 +423,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 +453,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; @@ -572,7 +557,7 @@ static int zend_parse_arg(int arg_num, zval **arg, va_list *va, char **spec, int } return FAILURE; } - + return SUCCESS; } @@ -669,7 +654,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 +666,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 +771,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) { @@ -846,7 +831,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 +850,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,10 +864,10 @@ 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 { @@ -891,7 +876,7 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type 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 +905,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 +932,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 +943,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 +954,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 +965,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 +1002,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 +1013,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 +1024,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 +1035,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 +1046,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 +1063,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 +1074,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 +1085,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 +1096,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 +1107,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 +1146,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 +1157,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 +1168,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 +1179,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 +1190,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,7 +1370,7 @@ 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; @@ -1409,7 +1394,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 +1410,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 +1435,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 +1458,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 +1475,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; } @@ -1543,7 +1531,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; @@ -1652,6 +1640,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 +1679,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 +1711,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 +1746,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 +1775,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 +1787,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; } @@ -1817,9 +1814,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 } @@ -1924,7 +1921,7 @@ ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int } 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; @@ -1951,21 +1948,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,7 +2010,7 @@ 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; @@ -2032,7 +2029,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 +2150,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 +2185,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) { @@ -2269,10 +2266,10 @@ 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; } @@ -2355,7 +2352,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 +2365,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 +2379,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 +2393,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 +2408,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 +2423,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 +2520,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 +2528,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 +2553,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 +2564,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 +2575,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 +2586,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 +2597,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 +2609,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 +2619,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 +2653,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 +2664,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 +2675,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 +2686,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 +2697,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 +2709,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 +2719,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); zval_ptr_dtor(&property); + EG(scope) = old_scope; return value; } @@ -2734,7 +2733,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; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 280d313f0d..0a894e20c3 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -42,9 +42,10 @@ typedef struct _zend_function_entry { } zend_function_entry; #define ZEND_FN(name) zif_##name +#define ZEND_MN(name) zim_##name #define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS) #define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name)) -#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name)) +#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name)) #define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags }, @@ -53,11 +54,12 @@ typedef struct _zend_function_entry { #define ZEND_DEP_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, ZEND_ACC_DEPRECATED) #define ZEND_FALIAS(name, alias, arg_info) ZEND_FENTRY(name, ZEND_FN(alias), arg_info, 0) #define ZEND_DEP_FALIAS(name, alias, arg_info) ZEND_FENTRY(name, ZEND_FN(alias), arg_info, ZEND_ACC_DEPRECATED) -#define ZEND_ME(classname, name, arg_info, flags) ZEND_FENTRY(name, ZEND_FN(classname##_##name), arg_info, flags) +#define ZEND_NAMED_ME(zend_name, name, arg_info, flags) ZEND_FENTRY(zend_name, name, arg_info, flags) +#define ZEND_ME(classname, name, arg_info, flags) ZEND_FENTRY(name, ZEND_MN(classname##_##name), arg_info, flags) #define ZEND_ABSTRACT_ME(classname, name, arg_info) ZEND_FENTRY(name, NULL, arg_info, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT) #define ZEND_MALIAS(classname, name, alias, arg_info, flags) \ - ZEND_FENTRY(name, ZEND_FN(classname##_##alias), arg_info, flags) -#define ZEND_ME_MAPPING(name, func_name, arg_types) ZEND_NAMED_FE(name, ZEND_FN(func_name), arg_types) + ZEND_FENTRY(name, ZEND_MN(classname##_##alias), arg_info, flags) +#define ZEND_ME_MAPPING(name, func_name, arg_types, flags) ZEND_NAMED_ME(name, ZEND_FN(func_name), arg_types, flags) #define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 }, #define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref, 0, 0 }, @@ -116,8 +118,6 @@ typedef struct _zend_function_entry { #endif - - #define INIT_CLASS_ENTRY(class_container, class_name, functions) INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, NULL, NULL, NULL) #define INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \ @@ -128,21 +128,26 @@ typedef struct _zend_function_entry { class_container.constructor = NULL; \ class_container.destructor = NULL; \ class_container.clone = NULL; \ - class_container.create_object = NULL; \ + class_container.serialize = NULL; \ + class_container.unserialize = NULL; \ + class_container.create_object = NULL; \ class_container.interface_gets_implemented = NULL; \ - class_container.__call = handle_fcall; \ - class_container.__get = handle_propget; \ - class_container.__set = handle_propset; \ - class_container.__unset = handle_propunset; \ - class_container.__isset = handle_propisset; \ - class_container.serialize = NULL; \ - class_container.unserialize = NULL; \ - class_container.parent = NULL; \ - class_container.num_interfaces = 0; \ - class_container.interfaces = NULL; \ - class_container.get_iterator = NULL; \ - class_container.iterator_funcs.funcs = NULL; \ - class_container.module = NULL; \ + class_container.__call = handle_fcall; \ + class_container.__tostring = NULL; \ + class_container.__get = handle_propget; \ + class_container.__set = handle_propset; \ + class_container.__unset = handle_propunset; \ + class_container.__isset = handle_propisset; \ + class_container.serialize_func = NULL; \ + class_container.unserialize_func = NULL; \ + class_container.serialize = NULL; \ + class_container.unserialize = NULL; \ + class_container.parent = NULL; \ + class_container.num_interfaces = 0; \ + class_container.interfaces = NULL; \ + class_container.get_iterator = NULL; \ + class_container.iterator_funcs.funcs = NULL; \ + class_container.module = NULL; \ } #define INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset) \ @@ -347,7 +352,7 @@ ZEND_API int add_property_zval_ex(zval *arg, char *key, uint key_len, zval *valu #define add_property_null(__arg, __key) add_property_null_ex(__arg, __key, strlen(__key) + 1 TSRMLS_CC) #define add_property_bool(__arg, __key, __b) add_property_bool_ex(__arg, __key, strlen(__key)+1, __b TSRMLS_CC) #define add_property_resource(__arg, __key, __r) add_property_resource_ex(__arg, __key, strlen(__key)+1, __r TSRMLS_CC) -#define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key)+1, __d TSRMLS_CC) +#define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key)+1, __d TSRMLS_CC) #define add_property_string(__arg, __key, __str, __duplicate) add_property_string_ex(__arg, __key, strlen(__key)+1, __str, __duplicate TSRMLS_CC) #define add_property_stringl(__arg, __key, __str, __length, __duplicate) add_property_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate TSRMLS_CC) #define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key)+1, __value TSRMLS_CC) @@ -405,28 +410,28 @@ END_EXTERN_C() #define CHECK_ZVAL_STRING_REL(z) #endif -#define ZVAL_RESOURCE(z, l) { \ - (z)->type = IS_RESOURCE; \ - (z)->value.lval = l; \ +#define ZVAL_RESOURCE(z, l) { \ + Z_TYPE_P(z) = IS_RESOURCE; \ + Z_LVAL_P(z) = l; \ } -#define ZVAL_BOOL(z, b) { \ - (z)->type = IS_BOOL; \ - (z)->value.lval = ((b) != 0); \ +#define ZVAL_BOOL(z, b) { \ + Z_TYPE_P(z) = IS_BOOL; \ + Z_LVAL_P(z) = ((b) != 0); \ } -#define ZVAL_NULL(z) { \ - (z)->type = IS_NULL; \ +#define ZVAL_NULL(z) { \ + Z_TYPE_P(z) = IS_NULL; \ } -#define ZVAL_LONG(z, l) { \ - (z)->type = IS_LONG; \ - (z)->value.lval = l; \ +#define ZVAL_LONG(z, l) { \ + Z_TYPE_P(z) = IS_LONG; \ + Z_LVAL_P(z) = l; \ } -#define ZVAL_DOUBLE(z, d) { \ - (z)->type = IS_DOUBLE; \ - (z)->value.dval = d; \ +#define ZVAL_DOUBLE(z, d) { \ + Z_TYPE_P(z) = IS_DOUBLE; \ + Z_DVAL_P(z) = d; \ } #define ZVAL_STRING(z, s, duplicate) { \ @@ -576,8 +581,8 @@ END_EXTERN_C() zend_declare_property(class_ptr, _name, namelen, value, mask TSRMLS_CC); \ } -#define HASH_OF(p) ((p)->type==IS_ARRAY ? (p)->value.ht : (((p)->type==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p) TSRMLS_CC) : NULL))) -#define ZVAL_IS_NULL(z) ((z)->type==IS_NULL) +#define HASH_OF(p) (Z_TYPE_P(p)==IS_ARRAY ? Z_ARRVAL_P(p) : ((Z_TYPE_P(p)==IS_OBJECT ? Z_OBJ_HT_P(p)->get_properties((p) TSRMLS_CC) : NULL))) +#define ZVAL_IS_NULL(z) (Z_TYPE_P(z)==IS_NULL) /* For compatibility */ #define ZEND_MINIT ZEND_MODULE_STARTUP_N @@ -593,7 +598,7 @@ END_EXTERN_C() #define ZEND_MINFO_FUNCTION ZEND_MODULE_INFO_D END_EXTERN_C() - + #endif /* ZEND_API_H */ diff --git a/Zend/zend_arg_defs.c b/Zend/zend_arg_defs.c index be0601c9c8..721ca127f8 100644 --- a/Zend/zend_arg_defs.c +++ b/Zend/zend_arg_defs.c @@ -50,4 +50,3 @@ ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO(all_args_by_ref, 1) ZEND_END_ARG_INFO(); - diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index f4a432d028..3d24311310 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -276,7 +276,7 @@ ZEND_FUNCTION(func_get_args) ZEND_NAMED_FUNCTION(zend_if_strlen) { zval **str; - + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); } @@ -374,7 +374,7 @@ ZEND_FUNCTION(each) ulong num_key; zval **inserted_pointer; HashTable *target_hash; - + if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &array) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); } @@ -455,7 +455,7 @@ ZEND_FUNCTION(define) zval **var, **val, **non_cs; int case_sensitive; zend_constant c; - + switch (ZEND_NUM_ARGS()) { case 2: if (zend_get_parameters_ex(2, &var, &val)==FAILURE) { @@ -468,7 +468,7 @@ ZEND_FUNCTION(define) RETURN_FALSE; } convert_to_long_ex(non_cs); - if ((*non_cs)->value.lval) { + if (Z_LVAL_PP(non_cs)) { case_sensitive = 0; } else { case_sensitive = CONST_CS; @@ -479,7 +479,7 @@ ZEND_FUNCTION(define) break; } - switch ((*val)->type) { + switch (Z_TYPE_PP(val)) { case IS_LONG: case IS_DOUBLE: case IS_STRING: @@ -515,7 +515,7 @@ ZEND_FUNCTION(defined) { zval **var; zval c; - + if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &var)==FAILURE) { ZEND_WRONG_PARAM_COUNT(); } @@ -539,7 +539,7 @@ ZEND_FUNCTION(get_class) char *name = ""; zend_uint name_len = 0; int dup; - + if (!ZEND_NUM_ARGS()) { if (EG(scope)) { RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1); @@ -623,13 +623,13 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass) zend_error(E_WARNING, "Unknown class passed as parameter"); RETURN_FALSE; } - instance_ce = *the_ce; + instance_ce = *the_ce; } else if (Z_TYPE_PP(obj) != IS_OBJECT) { RETURN_FALSE; } else { instance_ce = NULL; } - + /* TBI!! new object handlers */ if (Z_TYPE_PP(obj) == IS_OBJECT && !HAS_CLASS_ENTRY(**obj)) { RETURN_FALSE; @@ -724,7 +724,7 @@ static void add_class_vars(zend_class_entry *ce, HashTable *properties, zval *re if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || Z_TYPE_P(prop_copy) == IS_CONSTANT) { zval_update_constant(&prop_copy, 0 TSRMLS_CC); } - + add_assoc_zval(return_value, prop_name, prop_copy); } } @@ -773,7 +773,7 @@ ZEND_FUNCTION(get_object_vars) ZEND_WRONG_PARAM_COUNT(); } - if ((*obj)->type != IS_OBJECT) { + if (Z_TYPE_PP(obj) != IS_OBJECT) { RETURN_FALSE; } if (Z_OBJ_HT_PP(obj)->get_properties == NULL) { @@ -870,7 +870,7 @@ ZEND_FUNCTION(method_exists) zval **klass, **method_name; char *lcname; zend_class_entry * ce, **pce; - + if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &klass, &method_name)==FAILURE) { ZEND_WRONG_PARAM_COUNT(); } @@ -962,7 +962,7 @@ ZEND_FUNCTION(property_exists) } RETURN_BOOL(EG(scope) == ce); RETURN_FALSE; - + case IS_OBJECT: if (Z_OBJ_HANDLER_PP(object, has_property) && Z_OBJ_HANDLER_PP(object, has_property)(*object, *property, 2 TSRMLS_CC)) { RETURN_TRUE; @@ -1086,7 +1086,7 @@ ZEND_FUNCTION(leak) leakbytes = (*leak)->value.lval; } } - + emalloc(leakbytes); } /* }}} */ @@ -1170,7 +1170,7 @@ ZEND_FUNCTION(set_error_handler) zend_bool had_orig_error_handler=0; char *error_handler_name = NULL; long error_type = E_ALL | E_STRICT; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &error_handler, &error_type) == FAILURE) { return; } @@ -1333,7 +1333,7 @@ ZEND_FUNCTION(get_declared_interfaces) { zend_uint mask = ZEND_ACC_INTERFACE; zend_uint comply = 1; - + if (ZEND_NUM_ARGS() != 0) { ZEND_WRONG_PARAM_COUNT(); } @@ -1358,7 +1358,7 @@ static int copy_function_name(zend_function *func, int num_args, va_list args, z } else if (func->type == ZEND_USER_FUNCTION) { add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1); } - + return 0; } @@ -1369,26 +1369,26 @@ ZEND_FUNCTION(get_defined_functions) { zval *internal; zval *user; - + if (ZEND_NUM_ARGS() != 0) { ZEND_WRONG_PARAM_COUNT(); } - + MAKE_STD_ZVAL(internal); MAKE_STD_ZVAL(user); - + array_init(internal); array_init(user); array_init(return_value); - + zend_hash_apply_with_arguments(EG(function_table), (apply_func_args_t) copy_function_name, 2, internal, user); - - if (zend_hash_add(return_value->value.ht, "internal", sizeof("internal"), (void **)&internal, sizeof(zval *), NULL) == FAILURE) { + + if (zend_hash_add(Z_ARRVAL_P(return_value), "internal", sizeof("internal"), (void **)&internal, sizeof(zval *), NULL) == FAILURE) { zend_error(E_WARNING, "Cannot add internal functions to return value from get_defined_functions()"); RETURN_FALSE; } - - if (zend_hash_add(return_value->value.ht, "user", sizeof("user"), (void **)&user, sizeof(zval *), NULL) == FAILURE) { + + if (zend_hash_add(Z_ARRVAL_P(return_value), "user", sizeof("user"), (void **)&user, sizeof(zval *), NULL) == FAILURE) { zend_error(E_WARNING, "Cannot add user functions to return value from get_defined_functions()"); RETURN_FALSE; } @@ -1399,12 +1399,12 @@ ZEND_FUNCTION(get_defined_functions) /* {{{ proto array get_defined_vars(void) Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */ ZEND_FUNCTION(get_defined_vars) -{ +{ zval *tmp; - + array_init(return_value); - - zend_hash_copy(return_value->value.ht, EG(active_symbol_table), + + zend_hash_copy(Z_ARRVAL_P(return_value), EG(active_symbol_table), (copy_ctor_func_t)zval_add_ref, &tmp, sizeof(zval *)); } /* }}} */ @@ -1568,7 +1568,7 @@ ZEND_FUNCTION(get_defined_constants) modules = ecalloc(zend_hash_num_elements(&module_registry) + 2, sizeof(zval *)); module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *)); - + module_names[0] = "internal"; zend_hash_internal_pointer_reset_ex(&module_registry, &pos); while (zend_hash_get_current_data_ex(&module_registry, (void *) &module, &pos) != FAILURE) { @@ -1620,7 +1620,7 @@ static zval *debug_backtrace_get_args(void ***curpos TSRMLS_DC) zval *arg_array, **arg; int arg_count = (ulong) *p; - *curpos -= (arg_count+2); + *curpos -= (arg_count+2); MAKE_STD_ZVAL(arg_array); array_init(arg_array); @@ -1717,7 +1717,7 @@ ZEND_FUNCTION(debug_print_backtrace) arg_array = NULL; skip = ptr; - /* skip internal handler */ + /* skip internal handler */ if (!skip->op_array && skip->prev_execute_data && skip->prev_execute_data->opline && @@ -1744,7 +1744,7 @@ ZEND_FUNCTION(debug_print_backtrace) } else { zend_uint class_name_len; int dup; - + dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC); if(!dup) { free_class_name = class_name; @@ -1764,7 +1764,7 @@ ZEND_FUNCTION(debug_print_backtrace) arg_array = debug_backtrace_get_args(&cur_arg_pos TSRMLS_CC); frames_on_stack--; } - } + } } else { /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */ zend_bool build_filename_arg = 1; @@ -1774,7 +1774,7 @@ ZEND_FUNCTION(debug_print_backtrace) function_name = "unknown"; build_filename_arg = 0; } else - switch (ptr->opline->op2.u.constant.value.lval) { + switch (Z_LVAL(ptr->opline->op2.u.constant)) { case ZEND_EVAL: function_name = "eval"; build_filename_arg = 0; @@ -1927,7 +1927,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int } else { zend_uint class_name_len; int dup; - + dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC); add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, dup); @@ -1948,7 +1948,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int add_assoc_zval_ex(stack_frame, "args", sizeof("args"), debug_backtrace_get_args(&cur_arg_pos TSRMLS_CC)); frames_on_stack--; } - } + } } else { /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */ zend_bool build_filename_arg = 1; @@ -1988,7 +1988,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int MAKE_STD_ZVAL(arg_array); array_init(arg_array); - + /* include_filename always points to the last filename of the last last called-fuction. if we have called include in the frame above - this is the file we have included. */ @@ -2017,7 +2017,7 @@ ZEND_FUNCTION(debug_backtrace) if (ZEND_NUM_ARGS()) { ZEND_WRONG_PARAM_COUNT(); } - + zend_fetch_debug_backtrace(return_value, 1, 1 TSRMLS_CC); } /* }}} */ @@ -2066,7 +2066,7 @@ ZEND_FUNCTION(get_extension_funcs) RETURN_FALSE; } efree(lcname); - + if (!(func = module->functions)) { RETURN_FALSE; } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 096af0c2ff..e6ccf2e310 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -118,8 +118,8 @@ int zend_auto_global_disable_jit(char *varname, zend_uint varname_length TSRMLS_ static void init_compiler_declarables(TSRMLS_D) { - CG(declarables).ticks.type = IS_LONG; - CG(declarables).ticks.value.lval = 0; + Z_TYPE(CG(declarables).ticks) = IS_LONG; + Z_LVAL(CG(declarables).ticks) = 0; } @@ -245,7 +245,7 @@ static int lookup_cv(zend_op_array *op_array, char* name, int name_len) i = op_array->last_var; op_array->last_var++; if (op_array->last_var > op_array->size_var) { - op_array->size_var += 16; /* FIXME */ + op_array->size_var += 16; /* FIXME */ op_array->vars = erealloc(op_array->vars, op_array->size_var*sizeof(zend_compiled_variable)); } op_array->vars[i].name = name; /* estrndup(name, name_len); */ @@ -297,7 +297,7 @@ void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *o if (last_op_number > 0) { zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1]; - + switch (last_op->opcode) { case ZEND_FETCH_OBJ_RW: last_op->opcode = op; @@ -549,8 +549,8 @@ void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) while (last_op_number - n > 0) { zend_op *last_op; - - last_op = &CG(active_op_array)->opcodes[last_op_number-(n+1)]; + + last_op = &CG(active_op_array)->opcodes[last_op_number-n-1]; if (last_op->result.op_type == IS_VAR && last_op->result.u.var == variable->u.var) { @@ -623,7 +623,7 @@ void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC) opline->opcode = ZEND_ASSIGN_REF; if (zend_is_function_or_method_call(rvar)) { - opline->extended_value = ZEND_RETURNS_FUNCTION; + opline->extended_value = ZEND_RETURNS_FUNCTION; } else { opline->extended_value = 0; } @@ -685,7 +685,7 @@ void zend_do_while_end(znode *while_token, znode *close_bracket_token TSRMLS_DC) opline->op1.u.opline_num = while_token->u.opline_num; SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); - + /* update while's conditional jmp */ CG(active_op_array)->opcodes[close_bracket_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); @@ -824,7 +824,7 @@ void zend_do_if_after_statement(znode *closing_bracket_token, unsigned char init } zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr); zend_llist_add_element(jmp_list_ptr, &if_end_op_number); - + CG(active_op_array)->opcodes[closing_bracket_token->u.opline_num].op2.u.opline_num = if_end_op_number+1; SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); @@ -878,7 +878,7 @@ void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC) le = fetch_list_ptr->head; /* TODO: $foo->x->y->z = 1 should fetch "x" and "y" for R or RW, not just W */ - + if (le) { opline_ptr = (zend_op *)le->data; if (opline_is_fetch_this(opline_ptr TSRMLS_CC)) { @@ -1040,21 +1040,21 @@ void zend_do_free(znode *op1 TSRMLS_DC) } } else if (op1->op_type == IS_CONST) { zval_dtor(&op1->u.constant); - } + } } int zend_do_verify_access_types(znode *current_access_type, znode *new_modifier) { - if ((current_access_type->u.constant.value.lval & ZEND_ACC_PPP_MASK) - && (new_modifier->u.constant.value.lval & ZEND_ACC_PPP_MASK) - && ((current_access_type->u.constant.value.lval & ZEND_ACC_PPP_MASK) != (new_modifier->u.constant.value.lval & ZEND_ACC_PPP_MASK))) { + if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_PPP_MASK) + && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_PPP_MASK) + && ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_PPP_MASK) != (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_PPP_MASK))) { zend_error(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed"); } - if (((current_access_type->u.constant.value.lval | new_modifier->u.constant.value.lval) & (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) == (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) { + if (((Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant)) & (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) == (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) { zend_error(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member"); } - return (current_access_type->u.constant.value.lval | new_modifier->u.constant.value.lval); + return (Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant)); } @@ -1069,15 +1069,18 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n if (is_method) { if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) { - if ((fn_flags_znode->u.constant.value.lval & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) { + if ((Z_LVAL(fn_flags_znode->u.constant) & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) { zend_error(E_COMPILE_ERROR, "Access type for interface method %s::%s() must be omitted", CG(active_class_entry)->name, function_name->u.constant.value.str.val); } - fn_flags_znode->u.constant.value.lval |= ZEND_ACC_ABSTRACT; /* propagates to the rest of the parser */ + Z_LVAL(fn_flags_znode->u.constant) |= ZEND_ACC_ABSTRACT; /* propagates to the rest of the parser */ } - fn_flags = fn_flags_znode->u.constant.value.lval; /* must be done *after* the above check */ + fn_flags = Z_LVAL(fn_flags_znode->u.constant); /* must be done *after* the above check */ } else { fn_flags = 0; } + if ((fn_flags & ZEND_ACC_STATIC) && (fn_flags & ZEND_ACC_ABSTRACT) && !(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) { + zend_error(E_COMPILE_ERROR, "Static function %s%s%s() cannot be abstract", is_method ? CG(active_class_entry)->name : "", is_method ? "::" : "", Z_STRVAL(function_name->u.constant)); + } function_token->u.op_array = CG(active_op_array); lcname = zend_str_tolower_dup(name, name_len); @@ -1149,6 +1152,8 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n CG(active_class_entry)->__unset = (zend_function *) CG(active_op_array); } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)))) { CG(active_class_entry)->__isset = (zend_function *) CG(active_op_array); + } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)))) { + CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array); } else if (!(fn_flags & ZEND_ACC_STATIC)) { CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC; } @@ -1179,11 +1184,11 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); } - + { /* Push a seperator to the switch and foreach stacks */ zend_switch_entry switch_entry; - + switch_entry.cond.op_type = IS_UNUSED; switch_entry.default_case = 0; switch_entry.control_var = 0; @@ -1325,18 +1330,18 @@ int zend_do_begin_function_call(znode *function_name TSRMLS_DC) switch (function->type) { case ZEND_USER_FUNCTION: { zend_op_array *op_array = (zend_op_array *) function; - + zend_stack_push(&CG(function_call_stack), (void *) &op_array, sizeof(zend_function *)); } break; case ZEND_INTERNAL_FUNCTION: { zend_internal_function *internal_function = (zend_internal_function *) function; - + zend_stack_push(&CG(function_call_stack), (void *) &internal_function, sizeof(zend_function *)); } break; } - zend_do_extended_fcall_begin(TSRMLS_C); + zend_do_extended_fcall_begin(TSRMLS_C); return 0; } @@ -1350,7 +1355,7 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_variable_parse(TSRMLS_C); - + last_op_number = get_next_op_number(CG(active_op_array))-1; last_op = &CG(active_op_array)->opcodes[last_op_number]; @@ -1361,7 +1366,7 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) if (last_op->opcode == ZEND_FETCH_OBJ_R) { last_op->opcode = ZEND_INIT_METHOD_CALL; - left_bracket->u.constant.value.lval = ZEND_INIT_FCALL_BY_NAME; + Z_LVAL(left_bracket->u.constant) = ZEND_INIT_FCALL_BY_NAME; } else { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_INIT_FCALL_BY_NAME; @@ -1371,9 +1376,9 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) } zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); - zend_do_extended_fcall_begin(TSRMLS_C); + zend_do_extended_fcall_begin(TSRMLS_C); } - + void zend_do_clone(znode *result, znode *expr TSRMLS_DC) { @@ -1401,7 +1406,7 @@ void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC) SET_UNUSED(opline->op1); zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); - zend_do_extended_fcall_begin(TSRMLS_C); + zend_do_extended_fcall_begin(TSRMLS_C); } @@ -1487,13 +1492,13 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n void zend_do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC) { zend_op *opline; - + if (is_method && function_name && function_name->op_type == IS_UNUSED) { /* clone */ - if (argument_list->u.constant.value.lval != 0) { + if (Z_LVAL(argument_list->u.constant) != 0) { zend_error(E_WARNING, "Clone method does not require arguments"); } - opline = &CG(active_op_array)->opcodes[function_name->u.constant.value.lval]; + opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)]; } else { opline = get_next_op(CG(active_op_array) TSRMLS_CC); if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) { @@ -1504,14 +1509,14 @@ void zend_do_end_function_call(znode *function_name, znode *result, znode *argum SET_UNUSED(opline->op1); } } - + opline->result.u.var = get_temporary_variable(CG(active_op_array)); opline->result.op_type = IS_VAR; *result = opline->result; SET_UNUSED(opline->op2); zend_stack_del_top(&CG(function_call_stack)); - opline->extended_value = argument_list->u.constant.value.lval; + opline->extended_value = Z_LVAL(argument_list->u.constant); } @@ -1522,7 +1527,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) zend_function **function_ptr_ptr, *function_ptr; int send_by_reference; int send_function = 0; - + zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr); function_ptr = *function_ptr_ptr; @@ -1542,7 +1547,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) op = (param->op_type & (IS_VAR|IS_CV))?ZEND_SEND_REF:ZEND_SEND_VAL; send_by_reference = 0; } else { - send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0; + send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0; } } else { send_by_reference = 0; @@ -1612,11 +1617,11 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) static int generate_free_switch_expr(zend_switch_entry *switch_entry TSRMLS_DC) { zend_op *opline; - + if (switch_entry->cond.op_type != IS_VAR && switch_entry->cond.op_type != IS_TMP_VAR) { return (switch_entry->cond.op_type == IS_UNUSED); } - + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_SWITCH_FREE; @@ -1633,7 +1638,7 @@ static int generate_free_foreach_copy(zend_op *foreach_copy TSRMLS_DC) /* If we reach the seperator then stop applying the stack */ if (foreach_copy->result.op_type == IS_UNUSED && foreach_copy->op1.op_type == IS_UNUSED) { return 1; - } + } opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -1650,14 +1655,14 @@ static int generate_free_foreach_copy(zend_op *foreach_copy TSRMLS_DC) SET_UNUSED(opline->op2); opline->extended_value = 0; } - + return 0; } void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) { zend_op *opline; - + if (do_end_vparse) { if (CG(active_op_array)->return_reference && !zend_is_function_or_method_call(expr)) { zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); @@ -1677,7 +1682,7 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_RETURN; - + if (expr) { opline->op1 = *expr; } else { @@ -1687,7 +1692,7 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) if (do_end_vparse) { if (zend_is_function_or_method_call(expr)) { - opline->extended_value = ZEND_RETURNS_FUNCTION; + opline->extended_value = ZEND_RETURNS_FUNCTION; } else { opline->extended_value = 0; } @@ -1746,7 +1751,7 @@ void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, { long catch_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline; - + if (catch_op_number > 0) { opline = &CG(active_op_array)->opcodes[catch_op_number-1]; if (opline->opcode == ZEND_FETCH_CLASS) { @@ -1772,7 +1777,7 @@ void zend_do_end_catch(znode *try_token TSRMLS_DC) void zend_do_throw(znode *expr TSRMLS_DC) { zend_op *opline; - + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_THROW; opline->op1 = *expr; @@ -1829,6 +1834,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) if (!ce->__call) { ce->__call = ce->parent->__call; } + if (!ce->__tostring) { + ce->__tostring = ce->parent->__tostring; + } if (!ce->clone) { ce->clone = ce->parent->clone; } @@ -1850,7 +1858,7 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) } return; } - + if (zend_hash_find(&ce->parent->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), (void **)&function)==SUCCESS) { /* inherit parent's constructor */ zend_hash_update(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), function, sizeof(zend_function), NULL); @@ -2024,7 +2032,7 @@ static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_f child->common.prototype = parent->common.prototype; } - + if (child->common.prototype) { if (!zend_do_perform_implementation_check(child, child->common.prototype)) { zend_error(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with that of %s::%s()", ZEND_FN_SCOPE_NAME(child), child->common.function_name, ZEND_FN_SCOPE_NAME(child->common.prototype), child->common.prototype->common.function_name); @@ -2227,7 +2235,7 @@ static zend_bool do_inherit_constant_check(HashTable *child_constants_table, zva if (*old_constant != *parent_constant) { zend_error(E_COMPILE_ERROR, "Cannot inherit previously-inherited constant %s from interface %s", hash_key->arKey, iface->name); } - return 0; + return 0; } return 1; } @@ -2273,7 +2281,7 @@ ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, zend_b return SUCCESS; } } - + ZEND_API zend_class_entry *do_bind_class(zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC) { @@ -2452,7 +2460,7 @@ void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC) } opline->op1 = *expr1; SET_UNUSED(opline->op2); - + op_token->u.opline_num = next_op_number; *expr1 = opline->result; @@ -2487,7 +2495,7 @@ void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC) } opline->op1 = *expr1; SET_UNUSED(opline->op2); - + op_token->u.opline_num = next_op_number; *expr1 = opline->result; @@ -2540,8 +2548,8 @@ void zend_do_brk_cont(zend_uchar op, znode *expr TSRMLS_DC) if (expr) { opline->op2 = *expr; } else { - opline->op2.u.constant.type = IS_LONG; - opline->op2.u.constant.value.lval = 1; + Z_TYPE(opline->op2.u.constant) = IS_LONG; + Z_LVAL(opline->op2.u.constant) = 1; INIT_PZVAL(&opline->op2.u.constant); opline->op2.op_type = IS_CONST; } @@ -2568,7 +2576,7 @@ void zend_do_switch_end(znode *case_list TSRMLS_DC) { zend_op *opline; zend_switch_entry *switch_entry_ptr; - + zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr); /* add code to jmp to default case */ @@ -2628,7 +2636,7 @@ void zend_do_case_before_statement(znode *case_list, znode *case_token, znode *c zval_copy_ctor(&opline->op1.u.constant); } result = opline->result; - + next_op_number = get_next_op_number(CG(active_op_array)); opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_JMPZ; @@ -2736,7 +2744,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod opline->op2.op_type = IS_CONST; opline->op2.u.constant.type = IS_STRING; opline->op2.u.constant.refcount = 1; - + if (doing_inheritance) { opline->extended_value = parent_class_name->u.var; opline->opcode = ZEND_DECLARE_INHERITED_CLASS; @@ -2836,7 +2844,7 @@ void zend_do_implements_interface(znode *interface_znode TSRMLS_DC) } break; } - + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_ADD_INTERFACE; opline->op1 = CG(implementing_class); @@ -2849,7 +2857,7 @@ ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, char *src { char *prop_name; int prop_name_length; - + prop_name_length = 1 + src1_length + 1 + src2_length; prop_name = pemalloc(prop_name_length + 1, internal); prop_name[0] = '\0'; @@ -2917,7 +2925,7 @@ void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_ty *property = value->u.constant; } else { INIT_PZVAL(property); - property->type = IS_NULL; + Z_TYPE_P(property) = IS_NULL; } if (CG(doc_comment)) { @@ -2935,11 +2943,11 @@ void zend_do_declare_property(znode *var_name, znode *value, zend_uint access_ty void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC) { zval *property; - + if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { zend_error(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); } - + ALLOC_ZVAL(property); *property = value->u.constant; @@ -2957,9 +2965,9 @@ void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS zend_op opline; zend_llist *fetch_list_ptr; zend_op *opline_ptr=NULL; - + zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr); - + if (fetch_list_ptr->count == 1) { zend_llist_element *le; @@ -3066,7 +3074,7 @@ void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) { zend_op *opline; unsigned char *ptr = NULL; - + new_token->u.opline_num = get_next_op_number(CG(active_op_array)); opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_NEW; @@ -3074,7 +3082,7 @@ void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) opline->result.u.var = get_temporary_variable(CG(active_op_array)); opline->op1 = *class_type; SET_UNUSED(opline->op2); - + zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *)); } @@ -3134,7 +3142,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con if (constant_container || !zend_constant_ct_subst(result, &constant_name->u.constant TSRMLS_CC)) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); - + opline->opcode = ZEND_FETCH_CONSTANT; opline->result.op_type = IS_TMP_VAR; opline->result.u.var = get_temporary_variable(CG(active_op_array)); @@ -3338,8 +3346,8 @@ void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) opline->result.u.var = get_temporary_variable(CG(active_op_array)); opline->op1 = last_container; opline->op2.op_type = IS_CONST; - opline->op2.u.constant.type = IS_LONG; - opline->op2.u.constant.value.lval = *((int *) dimension->data); + Z_TYPE(opline->op2.u.constant) = IS_LONG; + Z_LVAL(opline->op2.u.constant) = *((int *) dimension->data); INIT_PZVAL(&opline->op2.u.constant); opline->extended_value = ZEND_FETCH_ADD_LOCK; last_container = opline->result; @@ -3462,7 +3470,7 @@ void zend_do_include_or_eval(int type, znode *result, znode *op1 TSRMLS_DC) opline->result.u.var = get_temporary_variable(CG(active_op_array)); opline->op1 = *op1; SET_UNUSED(opline->op2); - opline->op2.u.constant.value.lval = type; + Z_LVAL(opline->op2.u.constant) = type; *result = opline->result; } zend_do_extended_fcall_end(TSRMLS_C); @@ -3514,7 +3522,7 @@ void zend_do_unset(znode *variable TSRMLS_DC) break; } - } + } } @@ -3525,7 +3533,7 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC zend_do_end_variable_parse(BP_VAR_IS, 0 TSRMLS_CC); zend_check_writable_variable(variable); - + if (variable->op_type == IS_CV) { last_op = get_next_op(CG(active_op_array) TSRMLS_CC); last_op->opcode = ZEND_ISSET_ISEMPTY_VAR; @@ -3538,7 +3546,7 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC last_op->result.u.var = get_temporary_variable(CG(active_op_array)); } else { last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1]; - + switch (last_op->opcode) { case ZEND_FETCH_IS: last_op->opcode = ZEND_ISSET_ISEMPTY_VAR; @@ -3641,7 +3649,7 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno void zend_do_foreach_fetch(znode *foreach_token, znode *open_brackets_token, znode *as_token TSRMLS_DC) { zend_op *opline; - + /* save the location of FE_FETCH */ as_token->u.opline_num = get_next_op_number(CG(active_op_array)); @@ -3828,8 +3836,8 @@ void zend_do_exit(znode *result, znode *message TSRMLS_DC) SET_UNUSED(opline->op2); result->op_type = IS_CONST; - result->u.constant.type = IS_BOOL; - result->u.constant.value.lval = 1; + Z_TYPE(result->u.constant) = IS_BOOL; + Z_LVAL(result->u.constant) = 1; } void zend_do_begin_silence(znode *strudel_token TSRMLS_DC) @@ -3859,7 +3867,7 @@ void zend_do_begin_qm_op(znode *cond, znode *qm_token TSRMLS_DC) { int jmpz_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline; - + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_JMPZ; @@ -3902,7 +3910,7 @@ void zend_do_qm_false(znode *result, znode *false_value, znode *qm_token, znode opline->result = *qm_token; opline->op1 = *false_value; SET_UNUSED(opline->op2); - + CG(active_op_array)->opcodes[colon_token->u.opline_num].op1.u.opline_num = get_next_op_number(CG(active_op_array)); *result = opline->result; @@ -3914,11 +3922,11 @@ void zend_do_qm_false(znode *result, znode *false_value, znode *qm_token, znode void zend_do_extended_info(TSRMLS_D) { zend_op *opline; - + if (!CG(extended_info)) { return; } - + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_EXT_STMT; @@ -3930,11 +3938,11 @@ void zend_do_extended_info(TSRMLS_D) void zend_do_extended_fcall_begin(TSRMLS_D) { zend_op *opline; - + if (!CG(extended_info)) { return; } - + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_EXT_FCALL_BEGIN; @@ -3946,11 +3954,11 @@ void zend_do_extended_fcall_begin(TSRMLS_D) void zend_do_extended_fcall_end(TSRMLS_D) { zend_op *opline; - + if (!CG(extended_info)) { return; } - + opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_EXT_FCALL_END; @@ -3961,7 +3969,7 @@ void zend_do_extended_fcall_end(TSRMLS_D) void zend_do_ticks(TSRMLS_D) { - if (CG(declarables).ticks.value.lval) { + if (Z_LVAL(CG(declarables).ticks)) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_TICKS; @@ -4013,7 +4021,7 @@ again: CG(increment_lineno) = 0; } - zendlval->u.constant.type = IS_LONG; + Z_TYPE(zendlval->u.constant) = IS_LONG; retval = lex_scan(&zendlval->u.constant TSRMLS_CC); switch (retval) { case T_COMMENT: @@ -4038,7 +4046,7 @@ again: case EOF: return EOF; } - + INIT_PZVAL(&zendlval->u.constant); zendlval->op_type = IS_CONST; return retval; @@ -4090,6 +4098,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify ce->__unset = NULL; ce->__isset = NULL; ce->__call = NULL; + ce->__tostring = NULL; ce->create_object = NULL; ce->get_iterator = NULL; ce->iterator_funcs.funcs = NULL; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 4ceaf18988..4bb9fd9845 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -226,9 +226,9 @@ struct _zend_op_array { typedef struct _zend_internal_function { /* Common elements */ zend_uchar type; - char *function_name; + char * function_name; zend_class_entry *scope; - zend_uint fn_flags; + zend_uint fn_flags; union _zend_function *prototype; zend_uint num_args; zend_uint required_num_args; @@ -238,6 +238,7 @@ typedef struct _zend_internal_function { /* END of common elements */ void (*handler)(INTERNAL_FUNCTION_PARAMETERS); + struct _zend_module_entry *module; } zend_internal_function; #define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name : "") @@ -257,7 +258,7 @@ typedef union _zend_function { zend_bool pass_rest_by_reference; unsigned char return_reference; } common; - + zend_op_array op_array; zend_internal_function internal_function; } zend_function; @@ -507,7 +508,7 @@ ZEND_API void function_add_ref(zend_function *function); /* helper functions in zend_language_scanner.l */ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); -ZEND_API zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC); +ZEND_API zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC); ZEND_API zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC); ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...); ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC); @@ -705,9 +706,10 @@ END_EXTERN_C() #define ZEND_DESTRUCTOR_FUNC_NAME "__destruct" #define ZEND_GET_FUNC_NAME "__get" #define ZEND_SET_FUNC_NAME "__set" -#define ZEND_UNSET_FUNC_NAME "__unset" -#define ZEND_ISSET_FUNC_NAME "__isset" +#define ZEND_UNSET_FUNC_NAME "__unset" +#define ZEND_ISSET_FUNC_NAME "__isset" #define ZEND_CALL_FUNC_NAME "__call" +#define ZEND_TOSTRING_FUNC_NAME "__tostring" #define ZEND_AUTOLOAD_FUNC_NAME "__autoload" #endif /* ZEND_COMPILE_H */ diff --git a/Zend/zend_errors.h b/Zend/zend_errors.h index c7c893239d..8322b74216 100644 --- a/Zend/zend_errors.h +++ b/Zend/zend_errors.h @@ -34,8 +34,9 @@ #define E_USER_WARNING (1<<9L) #define E_USER_NOTICE (1<<10L) #define E_STRICT (1<<11L) +#define E_RECOVERABLE_ERROR (1<<12L) -#define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE) +#define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_RECOVERABLE_ERROR) #define E_CORE (E_CORE_ERROR | E_CORE_WARNING) #endif /* ZEND_ERRORS_H */ diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 4ea7ba6229..aca3ea9310 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -81,8 +81,8 @@ static zend_object_value zend_default_exception_new_ex(zend_class_entry *class_t zend_object *object; zval *trace; - obj.value.obj = zend_objects_new(&object, class_type TSRMLS_CC); - obj.value.obj.handlers = &default_exception_handlers; + Z_OBJVAL(obj) = zend_objects_new(&object, class_type TSRMLS_CC); + Z_OBJ_HT(obj) = &default_exception_handlers; ALLOC_HASHTABLE(object->properties); zend_hash_init(object->properties, 0, NULL, ZVAL_PTR_DTOR, 0); @@ -97,7 +97,7 @@ static zend_object_value zend_default_exception_new_ex(zend_class_entry *class_t zend_update_property_long(default_exception_ce, &obj, "line", sizeof("line")-1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); zend_update_property(default_exception_ce, &obj, "trace", sizeof("trace")-1, trace TSRMLS_CC); - return obj.value.obj; + return Z_OBJVAL(obj); } static zend_object_value zend_default_exception_new(zend_class_entry *class_type TSRMLS_DC) @@ -171,7 +171,7 @@ ZEND_METHOD(error_exception, __construct) } zend_update_property_long(default_exception_ce, object, "severity", sizeof("severity")-1, severity TSRMLS_CC); - + if (argc >= 4) { zend_update_property_string(default_exception_ce, object, "file", sizeof("file")-1, filename TSRMLS_CC); if (argc < 5) { @@ -271,7 +271,7 @@ ZEND_METHOD(error_exception, getSeverity) #define TRACE_APPEND_STRL(val, vallen) \ { \ - int l = vallen; \ + int l = vallen; \ *str = (char*)erealloc(*str, *len + l + 1); \ memcpy((*str) + *len, val, l); \ *len += l; \ @@ -372,7 +372,7 @@ static int _build_trace_args(zval **arg, int num_args, va_list args, zend_hash_k if(!dup) { efree(class_name); } - + TRACE_APPEND_STR("), "); break; } @@ -434,7 +434,7 @@ ZEND_METHOD(exception, getTraceAsString) zval *trace; char *res = estrdup(""), **str = &res, *s_tmp; int res_len = 0, *len = &res_len, num = 0; - + trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC); zend_hash_apply_with_arguments(Z_ARRVAL_P(trace), (apply_func_args_t)_build_trace_string, 3, str, len, &num); @@ -448,12 +448,12 @@ ZEND_METHOD(exception, getTraceAsString) } /* }}} */ -static int zend_spprintf(char **message, int max_len, char *format, ...) +int zend_spprintf(char **message, int max_len, char *format, ...) { va_list arg; int len; - va_start(arg, format); + va_start(arg, format); len = zend_vspprintf(message, max_len, format, arg); va_end(arg); return len; @@ -524,9 +524,9 @@ ZEND_METHOD(exception, __toString) /* All functions that may be used in uncaught exception handlers must be final * and must not throw exceptions. Otherwise we would need a facility to handle - * such exceptions in that handler. + * such exceptions in that handler. * Also all getXY() methods are final because thy serve as read only access to - * their corresponding properties, no more, no less. If after all you need to + * their corresponding properties, no more, no less. If after all you need to * override somthing then it is method __toString(). * And never try to change the state of exceptions and never implement anything * that gives the user anything to accomplish this. @@ -571,7 +571,7 @@ void zend_register_default_exception(TSRMLS_D) INIT_CLASS_ENTRY(ce, "Exception", default_exception_functions); default_exception_ce = zend_register_internal_class(&ce TSRMLS_CC); - default_exception_ce->create_object = zend_default_exception_new; + default_exception_ce->create_object = zend_default_exception_new; memcpy(&default_exception_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); default_exception_handlers.clone_obj = NULL; @@ -584,16 +584,16 @@ void zend_register_default_exception(TSRMLS_D) INIT_CLASS_ENTRY(ce, "ErrorException", error_exception_functions); error_exception_ce = zend_register_internal_class_ex(&ce, default_exception_ce, NULL TSRMLS_CC); - error_exception_ce->create_object = zend_error_exception_new; + error_exception_ce->create_object = zend_error_exception_new; zend_declare_property_long(error_exception_ce, "severity", sizeof("severity")-1, E_ERROR, ZEND_ACC_PROTECTED TSRMLS_CC); } -ZEND_API zend_class_entry *zend_exception_get_default(void) +ZEND_API zend_class_entry *zend_exception_get_default(TSRMLS_D) { return default_exception_ce; } -ZEND_API zend_class_entry *zend_get_error_exception(void) +ZEND_API zend_class_entry *zend_get_error_exception(TSRMLS_D) { return error_exception_ce; } @@ -613,7 +613,7 @@ ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *messa exception_ce = default_exception_ce; } object_init_ex(ex, exception_ce); - + if (message) { zend_update_property_string(default_exception_ce, ex, "message", sizeof("message")-1, message TSRMLS_CC); @@ -633,7 +633,7 @@ ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long cod char *message; zval *zexception; - va_start(arg, format); + va_start(arg, format); zend_vspprintf(&message, 0, format, arg); va_end(arg); zexception = zend_throw_exception(exception_ce, message, code TSRMLS_CC); @@ -652,7 +652,7 @@ ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, char static void zend_error_va(int type, const char *file, uint lineno, const char *format, ...) { va_list args; - + va_start(args, format); zend_error_cb(type, file, lineno, format, args); va_end(args); @@ -666,7 +666,7 @@ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC) zval *str, *file, *line; EG(exception) = NULL; - + zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &str); if (!EG(exception)) { if (Z_TYPE_P(str) != IS_STRING) { @@ -676,7 +676,7 @@ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC) } } zval_ptr_dtor(&str); - + if (EG(exception)) { /* do the best we can to inform about the inner exception */ if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) { @@ -686,7 +686,7 @@ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC) file = NULL; line = NULL; } - zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE_P(EG(exception))->name, ce_exception->name); + zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %v in exception handling during call to %v::__tostring()", Z_OBJCE_P(EG(exception))->name, ce_exception->name); } str = zend_read_property(default_exception_ce, exception, "string", sizeof("string")-1, 1 TSRMLS_CC); @@ -704,7 +704,7 @@ ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC) { zend_class_entry *exception_ce; - if (exception == NULL || exception->type != IS_OBJECT) { + if (exception == NULL || Z_TYPE_P(exception) != IS_OBJECT) { zend_error(E_ERROR, "Need to supply an object when throwing an exception"); } diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h index 998fff438e..fabe56252c 100644 --- a/Zend/zend_exceptions.h +++ b/Zend/zend_exceptions.h @@ -30,11 +30,11 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC); void zend_register_default_exception(TSRMLS_D); -ZEND_API zend_class_entry *zend_exception_get_default(void); -ZEND_API zend_class_entry *zend_get_error_exception(void); +ZEND_API zend_class_entry *zend_exception_get_default(TSRMLS_D); +ZEND_API zend_class_entry *zend_get_error_exception(TSRMLS_D); ZEND_API void zend_register_default_classes(TSRMLS_D); -/* exception_ce NULL or zend_exception_get_default() or a derived class +/* exception_ce NULL or zend_exception_get_default() or a derived class * message NULL or the message of the exception */ ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC); ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...); @@ -48,6 +48,9 @@ extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC); /* show an exception using zend_error(E_ERROR,...) */ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC); +/* do not export, in php it's available thru spprintf directly */ +int zend_spprintf(char **message, int max_len, char *format, ...); + END_EXTERN_C() #endif diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d87e46cbeb..6a8104ea9b 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -34,6 +34,7 @@ #include "zend_fast_cache.h" #include "zend_ini.h" #include "zend_exceptions.h" +#include "zend_interfaces.h" #include "zend_vm.h" #define _CONST_CODE 0 @@ -123,16 +124,16 @@ static inline void zend_pzval_unlock_free_func(zval *z) #define INIT_PZVAL_COPY(z,v) \ (z)->value = (v)->value; \ - (z)->type = (v)->type; \ + Z_TYPE_P(z) = Z_TYPE_P(v); \ (z)->refcount = 1; \ - (z)->is_ref = 0; + (z)->is_ref = 0; #define MAKE_REAL_ZVAL_PTR(val) \ do { \ zval *_tmp; \ ALLOC_ZVAL(_tmp); \ _tmp->value = (val)->value; \ - _tmp->type = (val)->type; \ + Z_TYPE_P(_tmp) = Z_TYPE_P(val); \ _tmp->refcount = 1; \ _tmp->is_ref = 0; \ val = _tmp; \ @@ -199,7 +200,7 @@ static inline zval *_get_zval_ptr_var(znode *node, temp_variable *Ts, zend_free_ static inline zval *_get_zval_ptr_cv(znode *node, temp_variable *Ts, int type TSRMLS_DC) { zval ***ptr = &CV_OF(node->u.var); - + if (!*ptr) { zend_compiled_variable *cv = &CV_DEF_OF(node->u.var); if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { @@ -267,7 +268,7 @@ static inline zval **_get_zval_ptr_ptr_var(znode *node, temp_variable *Ts, zend_ static inline zval **_get_zval_ptr_ptr_cv(znode *node, temp_variable *Ts, int type TSRMLS_DC) { zval ***ptr = &CV_OF(node->u.var); - + if (!*ptr) { zend_compiled_variable *cv = &CV_DEF_OF(node->u.var); if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) { @@ -445,7 +446,7 @@ static inline void make_real_object(zval **object_ptr TSRMLS_DC) } } -static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg TSRMLS_DC) +static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg TSRMLS_DC) { zend_arg_info *cur_arg_info; zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data; @@ -453,7 +454,7 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv if (!zf->common.arg_info || arg_num>zf->common.num_args) { - return; + return 1; } cur_arg_info = &zf->common.arg_info[arg_num-1]; @@ -464,76 +465,81 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv if (cur_arg_info->class_name) { if (!arg) { if (ptr && ptr->op_array) { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must be an object of class %s, called in %s on line %d and defined", arg_num, fclass, fsep, fname, cur_arg_info->class_name, ptr->op_array->filename, ptr->opline->lineno); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must be an object of class %s, called in %s on line %d and defined", arg_num, fclass, fsep, fname, cur_arg_info->class_name, ptr->op_array->filename, ptr->opline->lineno); } else { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must be an object of class %s", arg_num, fclass, fsep, fname, cur_arg_info->class_name); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must be an object of class %s", arg_num, fclass, fsep, fname, cur_arg_info->class_name); } + return 0; } switch (Z_TYPE_P(arg)) { case IS_NULL: if (!cur_arg_info->allow_null) { if (ptr && ptr->op_array) { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must not be null, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must not be null, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno); } else { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must not be null", arg_num, fclass, fsep, fname); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must not be null", arg_num, fclass, fsep, fname); } + return 0; } break; case IS_OBJECT: { zend_class_entry *ce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC); if (!instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) { char *error_msg; - - if (ce->ce_flags & ZEND_ACC_INTERFACE) { + if (ce->ce_flags & ZEND_ACC_INTERFACE) { error_msg = "implement interface"; } else { error_msg = "be an instance of"; } if (ptr && ptr->op_array) { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must %s %s, called in %s on line %d and defined", arg_num, fclass, fsep, fname, error_msg, ce->name, ptr->op_array->filename, ptr->opline->lineno); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must %s %s, called in %s on line %d and defined", arg_num, fclass, fsep, fname, error_msg, ce->name, ptr->op_array->filename, ptr->opline->lineno); } else { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must %s %s", arg_num, fclass, fsep, fname, error_msg, ce->name); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must %s %s", arg_num, fclass, fsep, fname, error_msg, ce->name); } + return 0; } } break; default: if (ptr && ptr->op_array) { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must be an object of class %s, called in %s on line %d and defined", arg_num, fclass, fsep, fname, cur_arg_info->class_name, ptr->op_array->filename, ptr->opline->lineno); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must be an object of class %s, called in %s on line %d and defined", arg_num, fclass, fsep, fname, cur_arg_info->class_name, ptr->op_array->filename, ptr->opline->lineno); } else { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must be an object of class %s", arg_num, fclass, fsep, fname, cur_arg_info->class_name); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must be an object of class %s", arg_num, fclass, fsep, fname, cur_arg_info->class_name); } - break; + return 0; } } else if (cur_arg_info->array_type_hint) { if (!arg) { - if(ptr && ptr->op_array) { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must be an array, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno); + if (ptr && ptr->op_array) { + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must be an array, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno); } else { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must be an array", arg_num, fclass, fsep, fname); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must be an array", arg_num, fclass, fsep, fname); } + return 0; } switch (Z_TYPE_P(arg)) { case IS_NULL: if (!cur_arg_info->allow_null) { if (ptr && ptr->op_array) { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must not be null, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must not be null, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno); } else { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must not be null", arg_num, fclass, fsep, fname); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must not be null", arg_num, fclass, fsep, fname); } + return 0; } break; case IS_ARRAY: break; - default: + default: if (ptr && ptr->op_array) { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must be an array, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must be an array, called in %s on line %d and defined", arg_num, fclass, fsep, fname, ptr->op_array->filename, ptr->opline->lineno); } else { - zend_error_noreturn(E_ERROR, "Argument %d passed to %s%s%s() must be an array", arg_num, fclass, fsep, fname); + zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must be an array", arg_num, fclass, fsep, fname); } - break; + return 0; } } + return 1; } @@ -557,8 +563,8 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */ object = *object_ptr; - - if (object->type != IS_OBJECT || (opcode == ZEND_ASSIGN_OBJ && !Z_OBJ_HT_P(object)->write_property)) { + + if (Z_TYPE_P(object) != IS_OBJECT || (opcode == ZEND_ASSIGN_OBJ && !Z_OBJ_HT_P(object)->write_property)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); FREE_OP(free_op2); if (!RETURN_VALUE_UNUSED(result)) { @@ -568,30 +574,11 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode FREE_OP(free_value); return; } - + /* here we are sure we are dealing with an object */ /* separate our value if necessary */ - if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) { - zval *orig_value = value; - char *class_name; - zend_uint class_name_len; - int dup; - - ALLOC_ZVAL(value); - *value = *orig_value; - value->is_ref = 0; - value->refcount = 0; - dup = zend_get_object_classname(orig_value, &class_name, &class_name_len TSRMLS_CC); - if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) { - zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); - } - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - value->value.obj = Z_OBJ_HANDLER_P(orig_value, clone_obj)(orig_value TSRMLS_CC); - if(!dup) { - efree(class_name); - } - } else if (value_op->op_type == IS_TMP_VAR) { + if (value_op->op_type == IS_TMP_VAR) { zval *orig_value = value; ALLOC_ZVAL(value); @@ -607,7 +594,7 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode value->refcount = 0; zval_copy_ctor(value); } - + value->refcount++; if (opcode == ZEND_ASSIGN_OBJ) { @@ -625,7 +612,7 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode } Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC); } - + if (result && !RETURN_VALUE_UNUSED(result)) { T(result->u.var).var.ptr = value; T(result->u.var).var.ptr_ptr = &T(result->u.var).var.ptr; /* this is so that we could use it in FETCH_DIM_R, etc. - see bug #27876 */ @@ -646,7 +633,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2 zend_free_op free_op1; zval **variable_ptr_ptr = get_zval_ptr_ptr(op1, Ts, &free_op1, BP_VAR_W); zval *variable_ptr; - + if (!variable_ptr_ptr) { temp_variable *T = &T(op1->u.var); @@ -702,7 +689,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2 */ } while (0); /* zval_ptr_dtor(&T->str_offset.str); Nuke this line if it doesn't cause a leak */ - + /* T(result->u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr); */ if (!RETURN_VALUE_UNUSED(result)) { T(result->u.var).var.ptr_ptr = &value; @@ -734,59 +721,11 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2 goto done_setting_var; } - if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) { - char *class_name; - zend_uint class_name_len; - int dup; - - dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC); - - if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) { - zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); - } else if (PZVAL_IS_REF(variable_ptr)) { - if (variable_ptr != value) { - zend_uint refcount = variable_ptr->refcount; - zval garbage; - - if (type != IS_TMP_VAR) { - value->refcount++; - } - garbage = *variable_ptr; - *variable_ptr = *value; - variable_ptr->refcount = refcount; - variable_ptr->is_ref = 1; - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC); - if (type != IS_TMP_VAR) { - value->refcount--; - } - zendi_zval_dtor(garbage); - } - } else { - if (variable_ptr != value) { - value->refcount++; - variable_ptr->refcount--; - if (variable_ptr->refcount == 0) { - zendi_zval_dtor(*variable_ptr); - } else { - ALLOC_ZVAL(variable_ptr); - *variable_ptr_ptr = variable_ptr; - } - *variable_ptr = *value; - INIT_PZVAL(variable_ptr); - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC); - zval_ptr_dtor(&value); - } - } - if (!dup) { - efree(class_name); - } - } else if (PZVAL_IS_REF(variable_ptr)) { + if (PZVAL_IS_REF(variable_ptr)) { if (variable_ptr!=value) { zend_uint refcount = variable_ptr->refcount; zval garbage; - + if (type!=IS_TMP_VAR) { value->refcount++; } @@ -812,7 +751,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2 variable_ptr->refcount++; } else if (PZVAL_IS_REF(value)) { zval tmp; - + tmp = *value; zval_copy_ctor(&tmp); tmp.refcount=1; @@ -859,13 +798,13 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2 } (*variable_ptr_ptr)->is_ref=0; } - + done_setting_var: if (result && !RETURN_VALUE_UNUSED(result)) { T(result->u.var).var.ptr_ptr = variable_ptr_ptr; PZVAL_LOCK(*variable_ptr_ptr); AI_USE_PTR(T(result->u.var).var); - } + } FREE_OP_VAR_PTR(free_op1); } @@ -874,32 +813,9 @@ static inline void zend_receive(zval **variable_ptr_ptr, zval *value TSRMLS_DC) { zval *variable_ptr = *variable_ptr_ptr; - if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) { - char *class_name; - zend_uint class_name_len; - int dup; - - dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC); - - if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) { - zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); - } else { - variable_ptr->refcount--; - ALLOC_ZVAL(variable_ptr); - *variable_ptr_ptr = variable_ptr; - *variable_ptr = *value; - INIT_PZVAL(variable_ptr); - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC); - } - if (!dup) { - efree(class_name); - } - } else { - variable_ptr->refcount--; - *variable_ptr_ptr = value; - value->refcount++; - } + variable_ptr->refcount--; + *variable_ptr_ptr = value; + value->refcount++; } /* Utility Functions for Extensions */ @@ -992,14 +908,14 @@ fetch_string_dim: zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", dim->value.lval, dim->value.lval); /* Fall Through */ case IS_DOUBLE: - case IS_BOOL: + case IS_BOOL: case IS_LONG: { long index; - if (dim->type == IS_DOUBLE) { - index = (long)dim->value.dval; + if (Z_TYPE_P(dim) == IS_DOUBLE) { + index = (long)Z_DVAL_P(dim); } else { - index = dim->value.lval; + index = Z_LVAL_P(dim); } if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) { switch (type) { @@ -1024,7 +940,7 @@ fetch_string_dim: } } break; - default: + default: zend_error(E_WARNING, "Illegal offset type"); switch (type) { case BP_VAR_R: @@ -1048,7 +964,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container if (!container_ptr) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - + container = *container_ptr; if (container == EG(error_zval_ptr)) { @@ -1078,7 +994,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container } } - switch (container->type) { + switch (Z_TYPE_P(container)) { zval **retval; case IS_ARRAY: @@ -1090,13 +1006,13 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container zval *new_zval = &EG(uninitialized_zval); new_zval->refcount++; - if (zend_hash_next_index_insert(container->value.ht, &new_zval, sizeof(zval *), (void **) &retval) == FAILURE) { + if (zend_hash_next_index_insert(Z_ARRVAL_P(container), &new_zval, sizeof(zval *), (void **) &retval) == FAILURE) { zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); retval = &EG(error_zval_ptr); - new_zval->refcount--; + new_zval->refcount--; } } else { - retval = zend_fetch_dimension_address_inner(container->value.ht, dim, type TSRMLS_CC); + retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC); } if (result) { result->var.ptr_ptr = retval; @@ -1121,7 +1037,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); } - if (dim->type != IS_LONG) { + if (Z_TYPE_P(dim) != IS_LONG) { tmp = *dim; zval_copy_ctor(&tmp); convert_to_long(&tmp); @@ -1141,7 +1057,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container container = *container_ptr; result->str_offset.str = container; PZVAL_LOCK(container); - result->str_offset.offset = dim->value.lval; + result->str_offset.offset = Z_LVAL_P(dim); result->var.ptr_ptr = NULL; if (type == BP_VAR_R || type == BP_VAR_IS) { AI_USE_PTR(result->var); @@ -1155,19 +1071,19 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container zend_error_noreturn(E_ERROR, "Cannot use object as array"); } else { zval *overloaded_result; - + if (dim_is_tmp_var) { zval *orig = dim; MAKE_REAL_ZVAL_PTR(dim); ZVAL_NULL(orig); - } + } overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC); if (overloaded_result) { switch (type) { case BP_VAR_RW: case BP_VAR_W: - if (overloaded_result->type != IS_OBJECT + if (Z_TYPE_P(overloaded_result) != IS_OBJECT && !overloaded_result->is_ref) { zend_error_noreturn(E_ERROR, "Objects used as arrays in post/pre increment/decrement must return values by reference"); } @@ -1193,7 +1109,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container return; } break; - default: { + default: { switch (type) { case BP_VAR_UNSET: zend_error(E_WARNING, "Cannot unset offset in a non-array variable"); @@ -1224,7 +1140,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC) { zval *container; - + container = *container_ptr; if (container == EG(error_zval_ptr)) { if (result) { @@ -1248,8 +1164,8 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_ break; } } - - if (container->type != IS_OBJECT) { + + if (Z_TYPE_P(container) != IS_OBJECT) { if (result) { if (type == BP_VAR_R || type == BP_VAR_IS) { result->var.ptr_ptr = &EG(uninitialized_zval_ptr); @@ -1260,14 +1176,14 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_ } return; } - + if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) { zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr TSRMLS_CC); - if(NULL == ptr_ptr) { + if (NULL == ptr_ptr) { zval *ptr; if (Z_OBJ_HT_P(container)->read_property && - (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, BP_VAR_W TSRMLS_CC)) != NULL) { + (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, BP_VAR_W TSRMLS_CC)) != NULL) { if (result) { result->var.ptr = ptr; result->var.ptr_ptr = &result->var.ptr; @@ -1289,10 +1205,10 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_ result->var.ptr_ptr = &EG(error_zval_ptr); } } - + if (result) { PZVAL_LOCK(*result->var.ptr_ptr); - } + } } static inline zend_brk_cont_element* zend_brk_cont(zval *nest_levels_zval, int array_offset, zend_op_array *op_array, temp_variable *Ts TSRMLS_DC) @@ -1347,7 +1263,7 @@ static int zend_check_symbol(zval **pz TSRMLS_DC) } else if (Z_TYPE_PP(pz) == IS_ARRAY) { zend_hash_apply(Z_ARRVAL_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC); } else if (Z_TYPE_PP(pz) == IS_OBJECT) { - + /* OBJ-TBI - doesn't support new object model! */ zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC); } @@ -1369,13 +1285,13 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v } #define ZEND_VM_NEXT_OPCODE() \ - CHECK_SYMBOL_TABLES() \ - EX(opline)++; \ - ZEND_VM_CONTINUE() + CHECK_SYMBOL_TABLES() \ + EX(opline)++; \ + ZEND_VM_CONTINUE() #define ZEND_VM_SET_OPCODE(new_op) \ - CHECK_SYMBOL_TABLES() \ - EX(opline) = new_op + CHECK_SYMBOL_TABLES() \ + EX(opline) = new_op #define ZEND_VM_JMP(new_op) \ CHECK_SYMBOL_TABLES() \ @@ -1383,21 +1299,21 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v ZEND_VM_CONTINUE() #define ZEND_VM_INC_OPCODE() \ - if (!EG(exception)) { \ - CHECK_SYMBOL_TABLES() \ - EX(opline)++; \ - } + if (!EG(exception)) { \ + CHECK_SYMBOL_TABLES() \ + EX(opline)++; \ + } #define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \ - free_alloca(EX(CVs)); \ - if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \ - free_alloca(EX(Ts)); \ - } else { \ - efree(EX(Ts)); \ - } \ - EG(in_execution) = EX(original_in_execution); \ - EG(current_execute_data) = EX(prev_execute_data); \ - ZEND_VM_RETURN() + free_alloca(EX(CVs)); \ + if (EX(op_array)->T < TEMP_VAR_STACK_LIMIT) { \ + free_alloca(EX(Ts)); \ + } else { \ + efree(EX(Ts)); \ + } \ + EG(in_execution) = EX(original_in_execution); \ + EG(current_execute_data) = EX(prev_execute_data); \ + ZEND_VM_RETURN() #include "zend_vm_execute.h" diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 02afc64c01..b3b084bd66 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -24,8 +24,8 @@ #include "zend_compile.h" #include "zend_hash.h" -#include "zend_variables.h" #include "zend_operators.h" +#include "zend_variables.h" typedef union _temp_variable { zval tmp_var; @@ -73,28 +73,28 @@ static inline int i_zend_is_true(zval *op) { int result; - switch (op->type) { + switch (Z_TYPE_P(op)) { case IS_NULL: result = 0; break; case IS_LONG: case IS_BOOL: case IS_RESOURCE: - result = (op->value.lval?1:0); + result = (Z_LVAL_P(op)?1:0); break; case IS_DOUBLE: - result = (op->value.dval ? 1 : 0); + result = (Z_DVAL_P(op) ? 1 : 0); break; case IS_STRING: - if (op->value.str.len == 0 - || (op->value.str.len==1 && op->value.str.val[0]=='0')) { + if (Z_STRLEN_P(op) == 0 + || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) { result = 0; } else { result = 1; } break; case IS_ARRAY: - result = (zend_hash_num_elements(op->value.ht)?1:0); + result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0); break; case IS_OBJECT: if(IS_ZEND_STD_OBJECT(*op)) { @@ -102,7 +102,7 @@ static inline int i_zend_is_true(zval *op) if (Z_OBJ_HT_P(op)->cast_object) { zval tmp; - if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL, 0 TSRMLS_CC) == SUCCESS) { + if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL TSRMLS_CC) == SUCCESS) { result = Z_LVAL(tmp); break; } @@ -116,15 +116,8 @@ static inline int i_zend_is_true(zval *op) break; } } - - if(EG(ze1_compatibility_mode)) { - result = (zend_hash_num_elements(Z_OBJPROP_P(op))?1:0); - } else { - result = 1; - } - } else { - result = 1; } + result = 1; break; default: result = 0; @@ -191,7 +184,7 @@ void zend_shutdown_timeout_thread(); /* The following tries to resolve the classname of a zval of type object. * Since it is slow it should be only used in error messages. */ -#define Z_OBJ_CLASS_NAME_P(zval) ((zval) && (zval)->type == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name : "") +#define Z_OBJ_CLASS_NAME_P(zval) ((zval) && Z_TYPE_P(zval) == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name : "") ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data_ptr, zend_uint var); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 71fe9d807e..2d0f35eebf 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -155,8 +155,8 @@ void init_executor(TSRMLS_D) ALLOC_ZVAL(globals); globals->refcount=1; globals->is_ref=1; - globals->type = IS_ARRAY; - globals->value.ht = &EG(symbol_table); + Z_TYPE_P(globals) = IS_ARRAY; + Z_ARRVAL_P(globals) = &EG(symbol_table); zend_hash_update(&EG(symbol_table), "GLOBALS", sizeof("GLOBALS"), &globals, sizeof(zval *), NULL); } EG(active_symbol_table) = &EG(symbol_table); @@ -395,13 +395,6 @@ ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) zval_dtor(*zval_ptr); safe_free_zval_ptr_rel(*zval_ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC); } else if ((*zval_ptr)->refcount == 1) { - if ((*zval_ptr)->type == IS_OBJECT) { - TSRMLS_FETCH(); - - if (EG(ze1_compatibility_mode)) { - return; - } - } (*zval_ptr)->is_ref = 0; } } @@ -435,7 +428,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) zend_bool inline_change = (zend_bool) (unsigned long) arg; zval const_value; - if (p->type == IS_CONSTANT) { + if (Z_TYPE_P(p) == IS_CONSTANT) { int refcount; zend_uchar is_ref; @@ -462,7 +455,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) p->refcount = refcount; p->is_ref = is_ref; - } else if (p->type == IS_CONSTANT_ARRAY) { + } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { zval **element, *new_val; char *str_index; uint str_index_len; @@ -470,23 +463,23 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) SEPARATE_ZVAL_IF_NOT_REF(pp); p = *pp; - p->type = IS_ARRAY; + Z_TYPE_P(p) = IS_ARRAY; /* First go over the array and see if there are any constant indices */ - zend_hash_internal_pointer_reset(p->value.ht); - while (zend_hash_get_current_data(p->value.ht, (void **) &element)==SUCCESS) { + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element)==SUCCESS) { if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { - zend_hash_move_forward(p->value.ht); + zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; - if (zend_hash_get_current_key_ex(p->value.ht, &str_index, &str_index_len, &num_index, 0, NULL)!=HASH_KEY_IS_STRING) { - zend_hash_move_forward(p->value.ht); + if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL)!=HASH_KEY_IS_STRING) { + zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } if (!zend_get_constant(str_index, str_index_len-1, &const_value TSRMLS_CC)) { zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); - zend_hash_move_forward(p->value.ht); + zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } @@ -509,26 +502,26 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) zval_ptr_dtor(element); *element = new_val; - switch (const_value.type) { + switch (Z_TYPE(const_value)) { case IS_STRING: - zend_symtable_update_current_key(p->value.ht, const_value.value.str.val, const_value.value.str.len+1); + zend_symtable_update_current_key(Z_ARRVAL_P(p), const_value.value.str.val, const_value.value.str.len+1); break; case IS_BOOL: case IS_LONG: - zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_LONG, NULL, 0, const_value.value.lval); + zend_hash_update_current_key(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value)); break; case IS_DOUBLE: - zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_LONG, NULL, 0, (long)const_value.value.dval); + zend_hash_update_current_key(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, (long)Z_DVAL(const_value)); break; case IS_NULL: - zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_STRING, "", 1, 0); + zend_hash_update_current_key(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0); break; } - zend_hash_move_forward(p->value.ht); + zend_hash_move_forward(Z_ARRVAL_P(p)); zval_dtor(&const_value); } - zend_hash_apply_with_argument(p->value.ht, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC); - zend_hash_internal_pointer_reset(p->value.ht); + zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC); + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } return 0; } @@ -631,13 +624,13 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS *fci->retval_ptr_ptr = NULL; if (!fci_cache || !fci_cache->initialized) { - if (fci->function_name->type==IS_ARRAY) { /* assume array($obj, $name) couple */ + if (Z_TYPE_P(fci->function_name)==IS_ARRAY) { /* assume array($obj, $name) couple */ zval **tmp_object_ptr, **tmp_real_function_name; - if (zend_hash_index_find(fci->function_name->value.ht, 0, (void **) &tmp_object_ptr)==FAILURE) { + if (zend_hash_index_find(Z_ARRVAL_P(fci->function_name), 0, (void **) &tmp_object_ptr)==FAILURE) { return FAILURE; } - if (zend_hash_index_find(fci->function_name->value.ht, 1, (void **) &tmp_real_function_name)==FAILURE) { + if (zend_hash_index_find(Z_ARRVAL_P(fci->function_name), 1, (void **) &tmp_real_function_name)==FAILURE) { return FAILURE; } fci->function_name = *tmp_real_function_name; @@ -693,7 +686,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (found == FAILURE) { zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(fci->object_pp)); } - if (scope && EG(This) && + if (scope && EG(This) && instanceof_function(Z_OBJCE_P(EG(This)), scope TSRMLS_CC) && instanceof_function(scope, *ce TSRMLS_CC)) { fci->object_pp = &EG(This); @@ -816,7 +809,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS fci->object_pp = fci_cache->object_pp; EX(object) = fci->object_pp ? *fci->object_pp : NULL; } - + if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) { if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) { zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name); @@ -1023,7 +1016,7 @@ ZEND_API int zend_lookup_class_ex(char *name, int name_length, int use_autoload, ZVAL_STRINGL(class_name_ptr, name, name_length, 1); args[0] = &class_name_ptr; - + fcall_info.size = sizeof(fcall_info); fcall_info.function_table = EG(function_table); fcall_info.function_name = &autoload_function; @@ -1490,9 +1483,9 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC); - if (ai.cnt) { - zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", - ce->name, ai.cnt, + if (ai.cnt) { + zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", + ce->name, ai.cnt, ai.cnt > 1 ? "s" : "", DISPLAY_ABSTRACT_FN(0), DISPLAY_ABSTRACT_FN(1), diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index 34d0636d2c..3a5be9ecf6 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -78,7 +78,7 @@ int zend_load_extension(char *path) new_extension->name); DL_UNLOAD(handle); return FAILURE; - } + } } else if (ZTS_V!=extension_version_info->thread_safe) { fprintf(stderr, "Cannot load %s - it %s thread safe, whereas Zend %s\n", new_extension->name, @@ -229,10 +229,10 @@ ZEND_API zend_extension *zend_get_extension(char *extension_name) * Support for dynamic loading of MH_BUNDLEs on Darwin / Mac OS X * */ - + #if HAVE_MACH_O_DYLD_H -void *zend_mh_bundle_load(char* bundle_path) +void *zend_mh_bundle_load(char* bundle_path) { NSObjectFileImage bundle_image; NSModule bundle_handle; @@ -242,17 +242,17 @@ void *zend_mh_bundle_load(char* bundle_path) if (NSCreateObjectFileImageFromFile(bundle_path, &bundle_image) != NSObjectFileImageSuccess) { return NULL; } - + bundle_handle = NSLinkModule(bundle_image, bundle_path, NSLINKMODULE_OPTION_PRIVATE); NSDestroyObjectFileImage(bundle_image); - + /* call the init function of the bundle */ bundle_init_nssymbol = NSLookupSymbolInModule(bundle_handle, "__init"); if (bundle_init_nssymbol != NULL) { bundle_init = NSAddressOfSymbol(bundle_init_nssymbol); bundle_init(); } - + return bundle_handle; } @@ -260,14 +260,14 @@ int zend_mh_bundle_unload(void *bundle_handle) { NSSymbol bundle_fini_nssymbol; void (*bundle_fini)(void); - + /* call the fini function of the bundle */ bundle_fini_nssymbol = NSLookupSymbolInModule(bundle_handle, "__fini"); if (bundle_fini_nssymbol != NULL) { bundle_fini = NSAddressOfSymbol(bundle_fini_nssymbol); bundle_fini(); } - + return (int) NSUnLinkModule(bundle_handle, NULL); } diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 21080e72a8..9fa0e1fd51 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -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 | @@ -25,9 +25,9 @@ #include "zend_compile.h" /* The first number is the engine version and the rest is the date. - * This way engine 2 API no. is always greater than engine 1 API no.. + * This way engine 2/3 API no. is always greater than engine 1 API no.. */ -#define ZEND_EXTENSION_API_NO 220051025 +#define ZEND_EXTENSION_API_NO 220060510 typedef struct _zend_extension_version_info { int zend_extension_api_no; @@ -72,7 +72,7 @@ struct _zend_extension { op_array_handler_func_t op_array_handler; - statement_handler_func_t statement_handler; + statement_handler_func_t statement_handler; fcall_begin_handler_func_t fcall_begin_handler; fcall_end_handler_func_t fcall_end_handler; diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 8ae125f6ea..21efa16e0c 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -201,7 +201,6 @@ struct _zend_executor_globals { zend_function *autoload_func; zend_bool bailout_set; zend_bool full_tables_cleanup; - zend_bool ze1_compatibility_mode; /* for extended information support */ zend_bool no_extensions; diff --git a/Zend/zend_globals_macros.h b/Zend/zend_globals_macros.h index 3dd3dddf2f..6115bd5a62 100644 --- a/Zend/zend_globals_macros.h +++ b/Zend/zend_globals_macros.h @@ -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 | diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index cee89e11d7..b5e9ab6999 100755 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -29,7 +29,7 @@ ZEND_API zend_class_entry *zend_ce_iterator; ZEND_API zend_class_entry *zend_ce_arrayaccess; ZEND_API zend_class_entry *zend_ce_serializable; -/* {{{ zend_call_method +/* {{{ zend_call_method Only returns the returned zval if retval_ptr != NULL */ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC) { @@ -107,7 +107,7 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend /* iterator interface, c-level functions used by engine */ /* {{{ zend_user_it_new_iterator */ -static zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) +ZEND_API zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) { zval *retval; @@ -117,7 +117,7 @@ static zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS /* }}} */ /* {{{ zend_user_it_dtor */ -static void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC) +ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC) { zend_user_iterator *iter = (zend_user_iterator*)_iter; @@ -141,14 +141,14 @@ static void zend_user_it_dtor(zend_object_iterator *_iter TSRMLS_DC) /* }}} */ /* {{{ zend_user_it_valid */ -static int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC) +ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC) { if (_iter) { zend_user_iterator *iter = (zend_user_iterator*)_iter; zval *object = (zval*)iter->it.data; zval *more; int result; - + zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more); if (more) { result = i_zend_is_true(more); @@ -161,7 +161,7 @@ static int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC) /* }}} */ /* {{{ zend_user_it_get_current_data */ -static void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC) +ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC) { zend_user_iterator *iter = (zend_user_iterator*)_iter; zval *object = (zval*)iter->it.data; @@ -184,7 +184,7 @@ static int zend_user_it_get_current_key_default(zend_object_iterator *_iter, cha /* }}} */ /* {{{ zend_user_it_get_current_key */ -static int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) +ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) { zend_user_iterator *iter = (zend_user_iterator*)_iter; zval *object = (zval*)iter->it.data; @@ -216,7 +216,7 @@ static int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_ case IS_DOUBLE: case IS_RESOURCE: - case IS_BOOL: + case IS_BOOL: case IS_LONG: { if (retval->type == IS_DOUBLE) { *int_key = (long)retval->value.dval; @@ -231,7 +231,7 @@ static int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_ /* }}} */ /* {{{ zend_user_it_move_forward */ -static void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC) +ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC) { zend_user_iterator *iter = (zend_user_iterator*)_iter; zval *object = (zval*)iter->it.data; @@ -242,7 +242,7 @@ static void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC) /* }}} */ /* {{{ zend_user_it_rewind */ -static void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC) +ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC) { zend_user_iterator *iter = (zend_user_iterator*)_iter; zval *object = (zval*)iter->it.data; @@ -263,9 +263,15 @@ zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = { }; /* {{{ zend_user_it_get_iterator */ -static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) +static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) { - zend_user_iterator *iterator = emalloc(sizeof(zend_user_iterator)); + zend_user_iterator *iterator; + + if (by_ref) { + zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); + } + + iterator = emalloc(sizeof(zend_user_iterator)); object->refcount++; iterator->it.data = (void*)object; @@ -277,25 +283,24 @@ static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zva /* }}} */ /* {{{ zend_user_it_get_new_iterator */ -static zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) +ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) { zval *iterator = zend_user_it_new_iterator(ce, object TSRMLS_CC); zend_object_iterator *new_iterator; zend_class_entry *ce_it = iterator && Z_TYPE_P(iterator) == IS_OBJECT ? Z_OBJCE_P(iterator) : NULL; - if (!ce || !ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && iterator == object)) { - if (!EG(exception)) - { + if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && iterator == object)) { + if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Objects returned by %s::getIterator() must be traversable or implement interface Iterator", ce ? ce->name : Z_OBJCE_P(object)->name); } - if (iterator) - { + if (iterator) { zval_ptr_dtor(&iterator); } return NULL; } - new_iterator = ce_it->get_iterator(ce_it, iterator TSRMLS_CC); + + new_iterator = ce_it->get_iterator(ce_it, iterator, by_ref TSRMLS_CC); zval_ptr_dtor(&iterator); return new_iterator; } @@ -336,7 +341,7 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr } else if (class_type->get_iterator != zend_user_it_get_new_iterator) { /* c-level get_iterator cannot be changed (exception being only Traversable is implmented) */ if (class_type->num_interfaces) { - for (i = 0; i < (int)class_type->num_interfaces; i++) { + for (i = 0; i < class_type->num_interfaces; i++) { if (class_type->interfaces[i] == zend_ce_iterator) { return FAILURE; } @@ -428,7 +433,7 @@ int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len } if (result == FAILURE) { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name); + zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%v::serialize() must return a string or NULL", ce->name); } return result; } @@ -440,14 +445,14 @@ int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned ch zval * zdata; object_init_ex(*object, ce); - + MAKE_STD_ZVAL(zdata); ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1); zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata); - + zval_ptr_dtor(&zdata); - + if (EG(exception)) { return FAILURE; } else { @@ -498,7 +503,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_get, 0, 0, 1) /* actually this ZEND_END_ARG_INFO(); static -ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_value, 0, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_value, 0, 0, 2) ZEND_ARG_INFO(0, offset) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO(); @@ -518,7 +523,7 @@ ZEND_END_ARG_INFO(); zend_function_entry zend_funcs_serializable[] = { ZEND_ABSTRACT_ME(serializable, serialize, NULL) - ZEND_FENTRY(unserialize, NULL, arginfo_serializable_serialize, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR) + ZEND_FENTRY(unserialize, NULL, arginfo_serializable_serialize, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR) {NULL, NULL, NULL} }; /* }}} */ @@ -544,9 +549,9 @@ ZEND_API void zend_register_interfaces(TSRMLS_D) REGISTER_ITERATOR_INTERFACE(iterator, Iterator); REGISTER_ITERATOR_IMPLEMENT(iterator, traversable); - + REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess); - + REGISTER_ITERATOR_INTERFACE(serializable, Serializable) } /* }}} */ diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c index 9621e3b160..8baa3ce3a9 100755 --- a/Zend/zend_iterators.c +++ b/Zend/zend_iterators.c @@ -64,11 +64,11 @@ static void iter_wrapper_dtor(void *object, zend_object_handle handle TSRMLS_DC) ZEND_API zval *zend_iterator_wrap(zend_object_iterator *iter TSRMLS_DC) { zval *wrapped; - + MAKE_STD_ZVAL(wrapped); Z_TYPE_P(wrapped) = IS_OBJECT; - wrapped->value.obj.handle = zend_objects_store_put(iter, iter_wrapper_dtor, NULL, NULL TSRMLS_CC); - wrapped->value.obj.handlers = &iterator_object_handlers; + Z_OBJ_HANDLE_P(wrapped) = zend_objects_store_put(iter, iter_wrapper_dtor, NULL, NULL TSRMLS_CC); + Z_OBJ_HT_P(wrapped) = &iterator_object_handlers; return wrapped; } @@ -86,14 +86,13 @@ ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap( return ZEND_ITER_PLAIN_OBJECT; } return ZEND_ITER_INVALID; - - + case IS_ARRAY: if (HASH_OF(array_ptr)) { return ZEND_ITER_PLAIN_ARRAY; } return ZEND_ITER_INVALID; - + default: return ZEND_ITER_INVALID; } diff --git a/Zend/zend_iterators.h b/Zend/zend_iterators.h index b74e291bd1..664e2ca42a 100755 --- a/Zend/zend_iterators.h +++ b/Zend/zend_iterators.h @@ -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 | @@ -31,7 +31,7 @@ typedef struct _zend_object_iterator zend_object_iterator; typedef struct _zend_object_iterator_funcs { /* release all resources associated with this iterator instance */ void (*dtor)(zend_object_iterator *iter TSRMLS_DC); - + /* check for end of iteration (FAILURE or SUCCESS if data is valid) */ int (*valid)(zend_object_iterator *iter TSRMLS_DC); @@ -46,7 +46,7 @@ typedef struct _zend_object_iterator_funcs { /* rewind to start of data (optional, may be NULL) */ void (*rewind)(zend_object_iterator *iter TSRMLS_DC); - + /* invalidate current value/key (optional, may be NULL) */ void (*invalidate_current)(zend_object_iterator *iter TSRMLS_DC); } zend_object_iterator_funcs; @@ -57,11 +57,8 @@ struct _zend_object_iterator { ulong index; /* private to fe_reset/fe_fetch opcodes */ }; -typedef zval *(*zend_object_new_iterator_t)(zend_class_entry *ce, zval *object TSRMLS_DC); - typedef struct _zend_class_iterator_funcs { zend_object_iterator_funcs *funcs; - zend_object_new_iterator_t new_iterator; union _zend_function *zf_new_iterator; union _zend_function *zf_valid; union _zend_function *zf_current; diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h index 57a38a82bb..12f61d9441 100644 --- a/Zend/zend_modules.h +++ b/Zend/zend_modules.h @@ -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 | diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 2ab4813cbc..1f57ecf851 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ @@ -46,7 +46,7 @@ enable accessors to change properties array. if we have __call and method which is not part of the class function table is - called, we cal __call handler. + called, we cal __call handler. */ static HashTable *zend_std_get_properties(zval *object TSRMLS_DC) @@ -60,13 +60,13 @@ static zval *zend_std_call_getter(zval *object, zval *member TSRMLS_DC) { zval *retval = NULL; zend_class_entry *ce = Z_OBJCE_P(object); - + /* __get handler is called with one argument: property name it should return whether the call was successfull or not */ - + SEPARATE_ARG_IF_REF(member); zend_call_method_with_1_params(&object, ce, &ce->__get, ZEND_GET_FUNC_NAME, &retval, member); @@ -112,11 +112,11 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value TSRMLS_D static void zend_std_call_unsetter(zval *object, zval *member TSRMLS_DC) { zend_class_entry *ce = Z_OBJCE_P(object); - + /* __unset handler is called with one argument: property name */ - + SEPARATE_ARG_IF_REF(member); zend_call_method_with_1_params(&object, ce, &ce->__unset, ZEND_UNSET_FUNC_NAME, NULL, member); @@ -128,13 +128,13 @@ static zval *zend_std_call_issetter(zval *object, zval *member TSRMLS_DC) { zval *retval = NULL; zend_class_entry *ce = Z_OBJCE_P(object); - + /* __isset handler is called with one argument: property name it should return whether the property is set or not */ - + SEPARATE_ARG_IF_REF(member); zend_call_method_with_1_params(&object, ce, &ce->__isset, ZEND_ISSET_FUNC_NAME, &retval, member); @@ -334,7 +334,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) if (rv) { retval = &rv; } else { - retval = &EG(uninitialized_zval_ptr); + retval = &EG(uninitialized_zval_ptr); } } else { if (!silent) { @@ -427,7 +427,7 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) { zend_class_entry *ce = Z_OBJCE_P(object); zval *retval; - + if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) { if(offset == NULL) { /* [] construct */ @@ -480,7 +480,7 @@ static int zend_std_has_dimension(zval *object, zval *offset, int check_empty TS zend_class_entry *ce = Z_OBJCE_P(object); zval *retval; int result; - + if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) { SEPARATE_ARG_IF_REF(offset); zend_call_method_with_1_params(&object, ce, NULL, "offsetexists", &retval, offset); @@ -512,7 +512,7 @@ static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC zval tmp_member; zval **retval; zend_property_info *property_info; - + zobj = Z_OBJ_P(object); if (member->type != IS_STRING) { @@ -524,7 +524,7 @@ static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC #if DEBUG_OBJECT_HANDLERS fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member)); -#endif +#endif property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC); @@ -558,7 +558,7 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) zend_object *zobj; zval *tmp_member = NULL; zend_property_info *property_info; - + zobj = Z_OBJ_P(object); if (member->type != IS_STRING) { @@ -571,7 +571,7 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) } property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__unset != NULL) TSRMLS_CC); - + if (!property_info || zend_hash_del(zobj->properties, property_info->name, property_info->name_length+1) == FAILURE) { zend_guard *guard; @@ -594,7 +594,7 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) static void zend_std_unset_dimension(zval *object, zval *offset TSRMLS_DC) { zend_class_entry *ce = Z_OBJCE_P(object); - + if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) { SEPARATE_ARG_IF_REF(offset); zend_call_method_with_1_params(&object, ce, NULL, "offsetunset", NULL, offset); @@ -611,7 +611,7 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) zval *method_name_ptr, *method_args_ptr; zval *method_result_ptr = NULL; zend_class_entry *ce = Z_OBJCE_P(this_ptr); - + ALLOC_ZVAL(method_args_ptr); INIT_PZVAL(method_args_ptr); array_init(method_args_ptr); @@ -640,7 +640,7 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) RETVAL_ZVAL(method_result_ptr, 0, 1); } } - + /* now destruct all auxiliaries */ zval_ptr_dtor(&method_args_ptr); zval_ptr_dtor(&method_name_ptr); @@ -740,6 +740,7 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method if (zobj->ce->__call) { zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function)); call_user_call->type = ZEND_INTERNAL_FUNCTION; + call_user_call->module = zobj->ce->module; call_user_call->handler = zend_std_call_user_call; call_user_call->arg_info = NULL; call_user_call->num_args = 0; @@ -774,7 +775,7 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method /* Ensure that if we're calling a private function, we're allowed to do so. */ - updated_fbc = zend_check_private_int(fbc, object->value.obj.handlers->get_class_entry(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC); + updated_fbc = zend_check_private_int(fbc, Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC); if (!updated_fbc) { zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); } @@ -812,7 +813,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f /* Ensure that if we're calling a private function, we're allowed to do so. */ - updated_fbc = zend_check_private_int(fbc, EG(scope), function_name_strval, function_name_strlen TSRMLS_CC); + updated_fbc = zend_check_private_int(fbc, EG(scope), function_name_strval, function_name_strlen TSRMLS_CC); if (!updated_fbc) { zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : ""); } @@ -866,7 +867,7 @@ ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *propert zend_error(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name); } } - + return retval; } @@ -889,7 +890,7 @@ static union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC) } else if (constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) { /* Ensure that if we're calling a private function, we're allowed to do so. */ - if (object->value.obj.handlers->get_class_entry(object TSRMLS_CC) != EG(scope)) { + if (Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC) != EG(scope)) { zend_error(E_ERROR, "Call to private %s::%s() from context '%s'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : ""); } } else if ((constructor->common.fn_flags & ZEND_ACC_PROTECTED)) { @@ -911,7 +912,7 @@ int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC); static int zend_std_compare_objects(zval *o1, zval *o2 TSRMLS_DC) { zend_object *zobj1, *zobj2; - + zobj1 = Z_OBJ_P(o1); zobj2 = Z_OBJ_P(o2); @@ -928,11 +929,11 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists zval **value; zval *tmp_member = NULL; zend_property_info *property_info; - + zobj = Z_OBJ_P(object); - if (member->type != IS_STRING) { - ALLOC_ZVAL(tmp_member); + if (member->type != IS_STRING) { + ALLOC_ZVAL(tmp_member); *tmp_member = *member; INIT_PZVAL(tmp_member); zval_copy_ctor(tmp_member); @@ -942,7 +943,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists #if DEBUG_OBJECT_HANDLERS fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member)); -#endif +#endif property_info = zend_get_property_info(zobj->ce, member, 1 TSRMLS_CC); @@ -1024,32 +1025,53 @@ int zend_std_object_get_class_name(zval *object, char **class_name, zend_uint *c return SUCCESS; } -ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC) +ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC) { - zval fname, *retval; - + zval *retval; + zend_class_entry *ce; + switch (type) { case IS_STRING: - if (!zend_hash_exists(&Z_OBJCE_P(readobj)->function_table, "__tostring", sizeof("__tostring"))) { - return FAILURE; - } - ZVAL_STRING(&fname, "__tostring", 0); - if (call_user_function_ex(NULL, &readobj, &fname, &retval, 0, NULL, 0, NULL TSRMLS_CC) == SUCCESS) { - if (retval) { - if (Z_TYPE_P(retval) != IS_STRING) { - zend_error(E_ERROR, "Method %s::__toString() must return a string value", Z_OBJCE_P(readobj)->name); + ce = Z_OBJCE_P(readobj); + if (ce->__tostring && + zend_call_method_with_0_params(&readobj, ce, &ce->__tostring, "__tostring", &retval)) { + if (EG(exception)) { + zval_ptr_dtor(&retval); + zend_error(E_ERROR, "Method %s::__toString() must not throw an exception", ce->name); + return FAILURE; + } + if (Z_TYPE_P(retval) == IS_STRING) { + INIT_PZVAL(writeobj); + ZVAL_ZVAL(writeobj, retval, 1, 1); + if (Z_TYPE_P(writeobj) != type) { + convert_to_explicit_type(writeobj, type); } + return SUCCESS; } else { - MAKE_STD_ZVAL(retval); - ZVAL_STRINGL(retval, "", 0, 1); + zval_ptr_dtor(&retval); + INIT_PZVAL(writeobj); + ZVAL_EMPTY_STRING(writeobj); + zend_error(E_RECOVERABLE_ERROR, "Method %s::__toString() must return a string value", ce->name); + return SUCCESS; } - *writeobj = *retval; - zval_copy_ctor(writeobj); - INIT_PZVAL(writeobj); - zval_ptr_dtor(&retval); - return SUCCESS; } - break; + return FAILURE; + case IS_BOOL: + INIT_PZVAL(writeobj); + ZVAL_BOOL(writeobj, 1); + return SUCCESS; + case IS_LONG: + ce = Z_OBJCE_P(readobj); + zend_error(E_NOTICE, "Object of class %s could not be converted to int", ce->name); + INIT_PZVAL(writeobj); + ZVAL_LONG(writeobj, 1); + return SUCCESS; + case IS_DOUBLE: + ce = Z_OBJCE_P(readobj); + zend_error(E_NOTICE, "Object of class %s could not be converted to double", ce->name); + INIT_PZVAL(writeobj); + ZVAL_DOUBLE(writeobj, 1); + return SUCCESS; default: break; } @@ -1061,7 +1083,7 @@ ZEND_API zend_object_handlers std_object_handlers = { zend_objects_store_add_ref, /* add_ref */ zend_objects_store_del_ref, /* del_ref */ zend_objects_clone_obj, /* clone_obj */ - + zend_std_read_property, /* read_property */ zend_std_write_property, /* write_property */ zend_std_read_dimension, /* read_dimension */ @@ -1080,7 +1102,7 @@ ZEND_API zend_object_handlers std_object_handlers = { zend_std_object_get_class, /* get_class_entry */ zend_std_object_get_class_name, /* get_class_name */ zend_std_compare_objects, /* compare_objects */ - NULL, /* cast_object */ + zend_std_cast_object_tostring, /* cast_object */ NULL, /* count_elements */ }; diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 7053cccb49..85b7e85ab0 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ @@ -97,7 +97,10 @@ typedef zend_object_value (*zend_object_clone_obj_t)(zval *object TSRMLS_DC); typedef zend_class_entry *(*zend_object_get_class_entry_t)(zval *object TSRMLS_DC); typedef int (*zend_object_get_class_name_t)(zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC); typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC); -typedef int (*zend_object_cast_t)(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC); + +/* Cast an object to some other type + */ +typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type TSRMLS_DC); /* updates *count to hold the number of elements present and returns SUCCESS. * Returns FAILURE if the object does not have any sense of overloaded dimensions */ @@ -139,10 +142,10 @@ ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *propert ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len TSRMLS_DC); ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC); -ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type, int should_free TSRMLS_DC); +ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC); -#define IS_ZEND_STD_OBJECT(z) ((z).type == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL)) +#define IS_ZEND_STD_OBJECT(z) (Z_TYPE(z) == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL)) #define HAS_CLASS_ENTRY(z) (Z_OBJ_HT(z)->get_class_entry != NULL) ZEND_API int zend_check_private(union _zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC); diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 6e2c472713..bb8672592f 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -151,11 +151,8 @@ static void zval_add_ref_or_clone(zval **p) ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object_value new_obj_val, zend_object *old_object, zend_object_handle handle TSRMLS_DC) { - if (EG(ze1_compatibility_mode)) { - zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref_or_clone, (void *) NULL /* Not used anymore */, sizeof(zval *)); - } else { - zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref, (void *) NULL /* Not used anymore */, sizeof(zval *)); - } + zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref, (void *) NULL /* Not used anymore */, sizeof(zval *)); + if (old_object->ce->clone) { zval *new_obj; diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 3da112708e..83e7b5ff03 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ @@ -97,7 +97,7 @@ ZEND_API zend_object_handle zend_objects_store_put(void *object, zend_objects_st { zend_object_handle handle; struct _store_object *obj; - + if (EG(objects_store).free_list_head != -1) { handle = EG(objects_store).free_list_head; EG(objects_store).free_list_head = EG(objects_store).object_buckets[handle].bucket.free_list.next; @@ -135,6 +135,14 @@ ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC) #endif } +/* + * Add a reference to an objects store entry given the object handle. + */ +ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC) +{ + EG(objects_store).object_buckets[handle].bucket.obj.refcount++; +} + #define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST() \ EG(objects_store).object_buckets[handle].bucket.free_list.next = EG(objects_store).free_list_head; \ EG(objects_store).free_list_head = handle; \ @@ -143,28 +151,38 @@ ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC) ZEND_API void zend_objects_store_del_ref(zval *zobject TSRMLS_DC) { zend_object_handle handle; + + handle = Z_OBJ_HANDLE_P(zobject); + + zobject->refcount++; + zend_objects_store_del_ref_by_handle(handle TSRMLS_CC); + zobject->refcount--; +} + +/* + * Delete a reference to an objects store entry given the object handle. + */ +ZEND_API void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC) +{ struct _store_object *obj; if (!EG(objects_store).object_buckets) { return; } - handle = Z_OBJ_HANDLE_P(zobject); obj = &EG(objects_store).object_buckets[handle].bucket.obj; /* Make sure we hold a reference count during the destructor call otherwise, when the destructor ends the storage might be freed when the refcount reaches 0 a second time - */ + */ if (EG(objects_store).object_buckets[handle].valid) { if (obj->refcount == 1) { if (!EG(objects_store).object_buckets[handle].destructor_called) { EG(objects_store).object_buckets[handle].destructor_called = 1; if (obj->dtor) { - zobject->refcount++; obj->dtor(obj->object, handle TSRMLS_CC); - zobject->refcount--; } } if (obj->refcount == 1) { @@ -195,16 +213,16 @@ ZEND_API zend_object_value zend_objects_store_clone_obj(zval *zobject TSRMLS_DC) zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); obj = &EG(objects_store).object_buckets[handle].bucket.obj; - + if (obj->clone == NULL) { zend_error(E_CORE_ERROR, "Trying to clone uncloneable object of class %s", Z_OBJCE_P(zobject)->name); - } + } obj->clone(obj->object, &new_object TSRMLS_CC); retval.handle = zend_objects_store_put(new_object, obj->dtor, obj->free_storage, obj->clone TSRMLS_CC); retval.handlers = Z_OBJ_HT_P(zobject); - + return retval; } @@ -215,6 +233,14 @@ ZEND_API void *zend_object_store_get_object(zval *zobject TSRMLS_DC) return EG(objects_store).object_buckets[handle].bucket.obj.object; } +/* + * Retrieve an entry from the objects store given the object handle. + */ +ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC) +{ + return EG(objects_store).object_buckets[handle].bucket.obj.object; +} + /* zend_object_store_set_object: * It is ONLY valid to call this function from within the constructor of an * overloaded object. Its purpose is to set the object pointer for the object @@ -274,10 +300,10 @@ ZEND_API zval *zend_object_create_proxy(zval *object, zval *member TSRMLS_DC) zval_add_ref(&pobj->object); MAKE_STD_ZVAL(retval); - retval->type = IS_OBJECT; + Z_TYPE_P(retval) = IS_OBJECT; Z_OBJ_HANDLE_P(retval) = zend_objects_store_put(pobj, NULL, (zend_objects_free_object_storage_t) zend_objects_proxy_free_storage, (zend_objects_store_clone_t) zend_objects_proxy_clone TSRMLS_CC); Z_OBJ_HT_P(retval) = &zend_object_proxy_handlers; - + return retval; } @@ -312,7 +338,7 @@ ZEND_API zend_object_handlers *zend_get_std_object_handlers() static zend_object_handlers zend_object_proxy_handlers = { ZEND_OBJECTS_STORE_HANDLERS, - + NULL, /* read_property */ NULL, /* write_property */ NULL, /* read dimension */ diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index f4c505d21a..f465f2c46a 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -1,4 +1,4 @@ -/* +/* +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ @@ -64,8 +64,11 @@ ZEND_API zend_object_handle zend_objects_store_put(void *object, zend_objects_st ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC); ZEND_API void zend_objects_store_del_ref(zval *object TSRMLS_DC); +ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC); +ZEND_API void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC); ZEND_API zend_object_value zend_objects_store_clone_obj(zval *object TSRMLS_DC); ZEND_API void *zend_object_store_get_object(zval *object TSRMLS_DC); +ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC); /* See comment in zend_objects_API.c before you use this */ ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC); ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC); diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 1fa014eff1..cb207b1809 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -266,10 +266,16 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) } -#define convert_object_to_type(op, ctype, conv_func) \ +#define convert_object_to_type(op, ctype, conv_func) \ if (Z_OBJ_HT_P(op)->cast_object) { \ - if (Z_OBJ_HT_P(op)->cast_object(op, op, ctype, 1 TSRMLS_CC) == SUCCESS) { \ - op->type = ctype; \ + zval dst; \ + if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) { \ + zend_error(E_RECOVERABLE_ERROR, \ + "Object of class %s could not be converted to " # ctype, Z_OBJCE_P(op)->name); \ + } else { \ + zval_dtor(op); \ + Z_TYPE_P(op) = ctype; \ + op->value = dst.value; \ } \ } else { \ if(Z_OBJ_HT_P(op)->get) { \ @@ -333,14 +339,7 @@ ZEND_API void convert_to_long_base(zval *op, int base) return; } - if (EG(ze1_compatibility_mode)) { - HashTable *ht = Z_OBJPROP_P(op); - if (ht) { - retval = (zend_hash_num_elements(ht)?1:0); - } - } else { - zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name); - } + zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name); zval_dtor(op); ZVAL_LONG(op, retval); return; @@ -399,15 +398,7 @@ ZEND_API void convert_to_double(zval *op) return; } - if (EG(ze1_compatibility_mode)) { - HashTable *ht = Z_OBJPROP_P(op); - if (ht) { - retval = (zend_hash_num_elements(ht)?1.0:0.0); - } - } else { - zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name); - } - + zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name); zval_dtor(op); ZVAL_DOUBLE(op, retval); break; @@ -424,17 +415,23 @@ ZEND_API void convert_to_double(zval *op) ZEND_API void convert_to_null(zval *op) { - if (op->type == IS_OBJECT) { + if (Z_TYPE_P(op) == IS_OBJECT) { if (Z_OBJ_HT_P(op)->cast_object) { + zval *org; TSRMLS_FETCH(); - if (Z_OBJ_HT_P(op)->cast_object(op, op, IS_NULL, 1 TSRMLS_CC) == SUCCESS) { + + ALLOC_ZVAL(org); + *org = *op; + if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) { + zval_dtor(org); return; } + *op = *org; } } zval_dtor(op); - op->type = IS_NULL; + Z_TYPE_P(op) = IS_NULL; } @@ -488,13 +485,6 @@ ZEND_API void convert_to_boolean(zval *op) return; } - if (EG(ze1_compatibility_mode)) { - HashTable *ht = Z_OBJPROP_P(op); - if (ht) { - retval = (zend_hash_num_elements(ht)?1:0); - } - } - zval_dtor(op); ZVAL_BOOL(op, retval); break; @@ -1296,7 +1286,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) op1 = op1_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC); } else if (!op2_obj && Z_OBJ_HT_P(op1)->cast_object) { ALLOC_INIT_ZVAL(op1_free); - if (Z_OBJ_HT_P(op1)->cast_object(op1, op1_free, Z_TYPE_P(op2), 0 TSRMLS_CC) == FAILURE) { + if (Z_OBJ_HT_P(op1)->cast_object(op1, op1_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) { op2_free = NULL; ZVAL_BOOL(result, 0); COMPARE_RETURN_AND_FREE(FAILURE); @@ -1313,7 +1303,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) op2 = op2_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC); } else if (!op1_obj && Z_OBJ_HT_P(op2)->cast_object) { ALLOC_INIT_ZVAL(op2_free); - if (Z_OBJ_HT_P(op2)->cast_object(op2, op2_free, Z_TYPE_P(op1), 0 TSRMLS_CC) == FAILURE) { + if (Z_OBJ_HT_P(op2)->cast_object(op2, op2_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) { ZVAL_BOOL(result, 0); COMPARE_RETURN_AND_FREE(FAILURE); } @@ -1461,15 +1451,7 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) break; case IS_OBJECT: if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) { - if (EG(ze1_compatibility_mode)) { - zend_compare_objects(result, op1, op2 TSRMLS_CC); - /* comparison returns 0 in case of equality and - * 1 in case of ineqaulity, we need to reverse it - */ - result->value.lval = !result->value.lval; - } else { - result->value.lval = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)); - } + result->value.lval = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)); } else { result->value.lval = 0; } diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 94b00ec25b..cf21c87c71 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -24,6 +24,7 @@ #include #include +#include #ifdef HAVE_IEEEFP_H #include @@ -75,7 +76,7 @@ static inline zend_bool is_numeric_string(char *str, int length, long *lval, dou if (!length) { return 0; } - + /* handle hex numbers */ if (length>=2 && str[0]=='0' && (str[1]=='x' || str[1]=='X')) { conv_base=16; @@ -148,14 +149,14 @@ zend_memnstr(char *haystack, char *needle, int needle_len, char *end) return p; } } - + if (p == NULL) { return NULL; } - + p++; } - + return NULL; } @@ -225,6 +226,41 @@ END_EXTERN_C() convert_to_##lower_type(*ppzv); \ } +#define convert_to_explicit_type(pzv, type) \ + do { \ + switch (type) { \ + case IS_NULL: \ + convert_to_null(pzv); \ + break; \ + case IS_LONG: \ + convert_to_long(pzv); \ + break; \ + case IS_DOUBLE: \ + convert_to_double(pzv); \ + break; \ + case IS_BOOL: \ + convert_to_boolean(pzv); \ + break; \ + case IS_ARRAY: \ + convert_to_array(pzv); \ + break; \ + case IS_OBJECT: \ + convert_to_object(pzv); \ + break; \ + case IS_STRING: \ + convert_to_string(pzv); \ + break; \ + default: \ + assert(0); \ + break; \ + } \ + } while (0); \ + +#define convert_to_explicit_type_ex(ppzv, str_type) \ + if (Z_TYPE_PP(ppzv) != str_type) { \ + SEPARATE_ZVAL_IF_NOT_REF(ppzv); \ + convert_to_explicit_type(*ppzv, str_type); \ + } #define convert_to_boolean_ex(ppzv) convert_to_ex_master(ppzv, boolean, BOOL) #define convert_to_long_ex(ppzv) convert_to_ex_master(ppzv, long, LONG) @@ -235,7 +271,7 @@ END_EXTERN_C() #define convert_to_null_ex(ppzv) convert_to_ex_master(ppzv, null, NULL) #define convert_scalar_to_number_ex(ppzv) \ - if ((*ppzv)->type!=IS_LONG && (*ppzv)->type!=IS_DOUBLE) { \ + if (Z_TYPE_PP(ppzv)!=IS_LONG && Z_TYPE_PP(ppzv)!=IS_DOUBLE) { \ if (!(*ppzv)->is_ref) { \ SEPARATE_ZVAL(ppzv); \ } \ @@ -250,8 +286,8 @@ END_EXTERN_C() #define Z_STRLEN(zval) (zval).value.str.len #define Z_ARRVAL(zval) (zval).value.ht #define Z_OBJVAL(zval) (zval).value.obj -#define Z_OBJ_HANDLE(zval) (zval).value.obj.handle -#define Z_OBJ_HT(zval) (zval).value.obj.handlers +#define Z_OBJ_HANDLE(zval) Z_OBJVAL(zval).handle +#define Z_OBJ_HT(zval) Z_OBJVAL(zval).handlers #define Z_OBJCE(zval) zend_get_class_entry(&(zval) TSRMLS_CC) #define Z_OBJPROP(zval) Z_OBJ_HT((zval))->get_properties(&(zval) TSRMLS_CC) #define Z_OBJ_HANDLER(zval, hf) Z_OBJ_HT((zval))->hf @@ -269,7 +305,7 @@ END_EXTERN_C() #define Z_OBJVAL_P(zval_p) Z_OBJVAL(*zval_p) #define Z_OBJ_HANDLE_P(zval_p) Z_OBJ_HANDLE(*zval_p) #define Z_OBJ_HT_P(zval_p) Z_OBJ_HT(*zval_p) -#define Z_OBJ_HANDLER_P(zval_p, h) Z_OBJ_HANDLER(*zval_p, h) +#define Z_OBJ_HANDLER_P(zval_p, h) Z_OBJ_HANDLER(*zval_p, h) #define Z_LVAL_PP(zval_pp) Z_LVAL(**zval_pp) #define Z_BVAL_PP(zval_pp) Z_BVAL(**zval_pp) @@ -283,7 +319,7 @@ END_EXTERN_C() #define Z_OBJVAL_PP(zval_pp) Z_OBJVAL(**zval_pp) #define Z_OBJ_HANDLE_PP(zval_p) Z_OBJ_HANDLE(**zval_p) #define Z_OBJ_HT_PP(zval_p) Z_OBJ_HT(**zval_p) -#define Z_OBJ_HANDLER_PP(zval_p, h) Z_OBJ_HANDLER(**zval_p, h) +#define Z_OBJ_HANDLER_PP(zval_p, h) Z_OBJ_HANDLER(**zval_p, h) #define Z_TYPE(zval) (zval).type #define Z_TYPE_P(zval_p) Z_TYPE(*zval_p) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 60851b418a..ccafc5245d 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -888,7 +888,7 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY) zval *z = GET_OP1_ZVAL_PTR(BP_VAR_R); if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && - zend_std_cast_object_tostring(z, &z_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) { + zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); } else { @@ -2043,25 +2043,7 @@ ZEND_VM_C_LABEL(return_by_value): retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); - if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) { - zval *ret; - char *class_name; - zend_uint class_name_len; - int dup; - - ALLOC_ZVAL(ret); - INIT_PZVAL_COPY(ret, retval_ptr); - dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC); - if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) { - zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); - } - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC); - *EG(return_value_ptr_ptr) = ret; - if (!dup) { - efree(class_name); - } - } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */ + if (!IS_OP1_TMP_FREE()) { /* Not a temp var */ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF || (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) { zval *ret; @@ -3035,7 +3017,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) } if (ce && ce->get_iterator) { - iter = ce->get_iterator(ce, array_ptr TSRMLS_CC); + iter = ce->get_iterator(ce, array_ptr, 0 TSRMLS_CC); if (iter && !EG(exception)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index be4a32c838..e257a7575f 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1398,7 +1398,7 @@ static int ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *z = &opline->op1.u.constant; if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && - zend_std_cast_object_tostring(z, &z_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) { + zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); } else { @@ -1682,25 +1682,7 @@ return_by_value: retval_ptr = &opline->op1.u.constant; - if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) { - zval *ret; - char *class_name; - zend_uint class_name_len; - int dup; - - ALLOC_ZVAL(ret); - INIT_PZVAL_COPY(ret, retval_ptr); - dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC); - if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) { - zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); - } - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC); - *EG(return_value_ptr_ptr) = ret; - if (!dup) { - efree(class_name); - } - } else if (!0) { /* Not a temp var */ + if (!0) { /* Not a temp var */ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF || (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) { zval *ret; @@ -2118,7 +2100,7 @@ static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } if (ce && ce->get_iterator) { - iter = ce->get_iterator(ce, array_ptr TSRMLS_CC); + iter = ce->get_iterator(ce, array_ptr, 0 TSRMLS_CC); if (iter && !EG(exception)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); @@ -3826,7 +3808,7 @@ static int ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *z = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && - zend_std_cast_object_tostring(z, &z_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) { + zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); } else { @@ -4106,25 +4088,7 @@ return_by_value: retval_ptr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) { - zval *ret; - char *class_name; - zend_uint class_name_len; - int dup; - - ALLOC_ZVAL(ret); - INIT_PZVAL_COPY(ret, retval_ptr); - dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC); - if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) { - zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); - } - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC); - *EG(return_value_ptr_ptr) = ret; - if (!dup) { - efree(class_name); - } - } else if (!1) { /* Not a temp var */ + if (!1) { /* Not a temp var */ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF || (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) { zval *ret; @@ -4549,7 +4513,7 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } if (ce && ce->get_iterator) { - iter = ce->get_iterator(ce, array_ptr TSRMLS_CC); + iter = ce->get_iterator(ce, array_ptr, 0 TSRMLS_CC); if (iter && !EG(exception)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); @@ -6748,7 +6712,7 @@ static int ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *z = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && - zend_std_cast_object_tostring(z, &z_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) { + zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); } else { @@ -7022,25 +6986,7 @@ return_by_value: retval_ptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) { - zval *ret; - char *class_name; - zend_uint class_name_len; - int dup; - - ALLOC_ZVAL(ret); - INIT_PZVAL_COPY(ret, retval_ptr); - dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC); - if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) { - zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); - } - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC); - *EG(return_value_ptr_ptr) = ret; - if (!dup) { - efree(class_name); - } - } else if (!0) { /* Not a temp var */ + if (!0) { /* Not a temp var */ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF || (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) { zval *ret; @@ -7562,7 +7508,7 @@ static int ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } if (ce && ce->get_iterator) { - iter = ce->get_iterator(ce, array_ptr TSRMLS_CC); + iter = ce->get_iterator(ce, array_ptr, 0 TSRMLS_CC); if (iter && !EG(exception)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC); @@ -18874,7 +18820,7 @@ static int ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *z = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && - zend_std_cast_object_tostring(z, &z_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) { + zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); } else { @@ -19142,25 +19088,7 @@ return_by_value: retval_ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); - if (EG(ze1_compatibility_mode) && Z_TYPE_P(retval_ptr) == IS_OBJECT) { - zval *ret; - char *class_name; - zend_uint class_name_len; - int dup; - - ALLOC_ZVAL(ret); - INIT_PZVAL_COPY(ret, retval_ptr); - dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC); - if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) { - zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name); - } - zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name); - ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC); - *EG(return_value_ptr_ptr) = ret; - if (!dup) { - efree(class_name); - } - } else if (!0) { /* Not a temp var */ + if (!0) { /* Not a temp var */ if (EG(active_op_array)->return_reference == ZEND_RETURN_REF || (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0)) { zval *ret; @@ -19674,7 +19602,7 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } if (ce && ce->get_iterator) { - iter = ce->get_iterator(ce, array_ptr TSRMLS_CC); + iter = ce->get_iterator(ce, array_ptr, 0 TSRMLS_CC); if (iter && !EG(exception)) { array_ptr = zend_iterator_wrap(iter TSRMLS_CC);