diff options
Diffstat (limited to 'Zend/zend_variables.c')
-rw-r--r-- | Zend/zend_variables.c | 249 |
1 files changed, 98 insertions, 151 deletions
diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index d3d5cf7680..c2594274dd 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -12,14 +12,12 @@ | obtain it through the world-wide-web, please send a note to | | license@zend.com so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Andi Gutmans <andi@zend.com> | - | Zeev Suraski <zeev@zend.com> | - | Dmitry Stogov <dmitry@zend.com> | + | Authors: Andi Gutmans <andi@php.net> | + | Zeev Suraski <zeev@php.net> | + | Dmitry Stogov <dmitry@php.net> | +----------------------------------------------------------------------+ */ -/* $Id$ */ - #include <stdio.h> #include "zend.h" #include "zend_API.h" @@ -28,114 +26,112 @@ #include "zend_constants.h" #include "zend_list.h" -ZEND_API void ZEND_FASTCALL _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC) +static void ZEND_FASTCALL zend_string_destroy(zend_string *str); +static void ZEND_FASTCALL zend_reference_destroy(zend_reference *ref); +static void ZEND_FASTCALL zend_empty_destroy(zend_reference *ref); + +#if ZEND_DEBUG +static void ZEND_FASTCALL zend_array_destroy_wrapper(zend_array *arr); +static void ZEND_FASTCALL zend_object_destroy_wrapper(zend_object *obj); +static void ZEND_FASTCALL zend_resource_destroy_wrapper(zend_resource *res); +static void ZEND_FASTCALL zend_ast_ref_destroy_wrapper(zend_ast_ref *ast); +#else +# define zend_array_destroy_wrapper zend_array_destroy +# define zend_object_destroy_wrapper zend_objects_store_del +# define zend_resource_destroy_wrapper zend_list_free +# define zend_ast_ref_destroy_wrapper zend_ast_ref_destroy +#endif + +typedef void (ZEND_FASTCALL *zend_rc_dtor_func_t)(zend_refcounted *p); + +static const zend_rc_dtor_func_t zend_rc_dtor_func[] = { + /* IS_UNDEF */ (zend_rc_dtor_func_t)zend_empty_destroy, + /* IS_NULL */ (zend_rc_dtor_func_t)zend_empty_destroy, + /* IS_FALSE */ (zend_rc_dtor_func_t)zend_empty_destroy, + /* IS_TRUE */ (zend_rc_dtor_func_t)zend_empty_destroy, + /* IS_LONG */ (zend_rc_dtor_func_t)zend_empty_destroy, + /* IS_DOUBLE */ (zend_rc_dtor_func_t)zend_empty_destroy, + /* IS_STRING */ (zend_rc_dtor_func_t)zend_string_destroy, + /* IS_ARRAY */ (zend_rc_dtor_func_t)zend_array_destroy_wrapper, + /* IS_OBJECT */ (zend_rc_dtor_func_t)zend_object_destroy_wrapper, + /* IS_RESOURCE */ (zend_rc_dtor_func_t)zend_resource_destroy_wrapper, + /* IS_REFERENCE */ (zend_rc_dtor_func_t)zend_reference_destroy, + /* IS_CONSTANT_AST */ (zend_rc_dtor_func_t)zend_ast_ref_destroy_wrapper +}; + +ZEND_API void ZEND_FASTCALL rc_dtor_func(zend_refcounted *p) { - switch (GC_TYPE(p)) { - case IS_STRING: - case IS_CONSTANT: { - zend_string *str = (zend_string*)p; - CHECK_ZVAL_STRING_REL(str); - zend_string_free(str); - break; - } - case IS_ARRAY: { - zend_array *arr = (zend_array*)p; - zend_array_destroy(arr); - break; - } - case IS_CONSTANT_AST: { - zend_ast_ref *ast = (zend_ast_ref*)p; + ZEND_ASSERT(GC_TYPE(p) <= IS_CONSTANT_AST); + zend_rc_dtor_func[GC_TYPE(p)](p); +} - zend_ast_destroy_and_free(ast->ast); - efree_size(ast, sizeof(zend_ast_ref)); - break; - } - case IS_OBJECT: { - zend_object *obj = (zend_object*)p; +static void ZEND_FASTCALL zend_string_destroy(zend_string *str) +{ + CHECK_ZVAL_STRING(str); + ZEND_ASSERT(!ZSTR_IS_INTERNED(str)); + ZEND_ASSERT(GC_REFCOUNT(str) == 0); + ZEND_ASSERT(!(GC_FLAGS(str) & IS_STR_PERSISTENT)); + efree(str); +} - zend_objects_store_del(obj); - break; - } - case IS_RESOURCE: { - zend_resource *res = (zend_resource*)p; +static void ZEND_FASTCALL zend_reference_destroy(zend_reference *ref) +{ + i_zval_ptr_dtor(&ref->val ZEND_FILE_LINE_CC); + efree_size(ref, sizeof(zend_reference)); +} - /* destroy resource */ - zend_list_free(res); - break; - } - case IS_REFERENCE: { - zend_reference *ref = (zend_reference*)p; +static void ZEND_FASTCALL zend_empty_destroy(zend_reference *ref) +{ +} - i_zval_ptr_dtor(&ref->val ZEND_FILE_LINE_RELAY_CC); - efree_size(ref, sizeof(zend_reference)); - break; - } - default: - break; - } +#if ZEND_DEBUG +static void ZEND_FASTCALL zend_array_destroy_wrapper(zend_array *arr) +{ + zend_array_destroy(arr); } -ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC) +static void ZEND_FASTCALL zend_object_destroy_wrapper(zend_object *obj) { - switch (Z_TYPE_P(zvalue)) { - case IS_STRING: - case IS_CONSTANT: - CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue)); - zend_string_release(Z_STR_P(zvalue)); - break; - case IS_ARRAY: - case IS_CONSTANT_AST: - case IS_OBJECT: - case IS_RESOURCE: - zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources"); - break; - case IS_REFERENCE: { - zend_reference *ref = (zend_reference*)Z_REF_P(zvalue); - - zval_internal_ptr_dtor(&ref->val); - free(ref); - break; - } - case IS_LONG: - case IS_DOUBLE: - case IS_FALSE: - case IS_TRUE: - case IS_NULL: - default: - break; - } + zend_objects_store_del(obj); +} + +static void ZEND_FASTCALL zend_resource_destroy_wrapper(zend_resource *res) +{ + zend_list_free(res); +} + +static void ZEND_FASTCALL zend_ast_ref_destroy_wrapper(zend_ast_ref *ast) +{ + zend_ast_ref_destroy(ast); +} +#endif + +ZEND_API void zval_ptr_dtor(zval *zval_ptr) /* {{{ */ +{ + i_zval_ptr_dtor(zval_ptr ZEND_FILE_LINE_CC); } +/* }}} */ -ZEND_API void _zval_internal_dtor_for_ptr(zval *zvalue ZEND_FILE_LINE_DC) +ZEND_API void zval_internal_ptr_dtor(zval *zval_ptr) /* {{{ */ { - switch (Z_TYPE_P(zvalue)) { - case IS_STRING: - case IS_CONSTANT: - CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue)); - zend_string_free(Z_STR_P(zvalue)); - break; - case IS_ARRAY: - case IS_CONSTANT_AST: - case IS_OBJECT: - case IS_RESOURCE: - zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources"); - break; - case IS_REFERENCE: { - zend_reference *ref = (zend_reference*)Z_REF_P(zvalue); - - zval_internal_ptr_dtor(&ref->val); - free(ref); - break; + if (Z_REFCOUNTED_P(zval_ptr)) { + zend_refcounted *ref = Z_COUNTED_P(zval_ptr); + + if (GC_DELREF(ref) == 0) { + if (Z_TYPE_P(zval_ptr) == IS_STRING) { + zend_string *str = (zend_string*)ref; + + CHECK_ZVAL_STRING(str); + ZEND_ASSERT(!ZSTR_IS_INTERNED(str)); + ZEND_ASSERT((GC_FLAGS(str) & IS_STR_PERSISTENT)); + free(str); + } else { + zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects, resources or reference"); } - case IS_LONG: - case IS_DOUBLE: - case IS_FALSE: - case IS_TRUE: - case IS_NULL: - default: - break; + } } } +/* }}} */ /* This function should only be used as a copy constructor, i.e. it * should only be called AFTER a zval has been copied to another @@ -152,66 +148,17 @@ ZEND_API void zval_add_ref(zval *p) } } -ZEND_API void zval_add_ref_unref(zval *p) -{ - if (Z_REFCOUNTED_P(p)) { - if (Z_ISREF_P(p)) { - ZVAL_COPY(p, Z_REFVAL_P(p)); - } else { - Z_ADDREF_P(p); - } - } -} - -ZEND_API void ZEND_FASTCALL _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC) +ZEND_API void ZEND_FASTCALL zval_copy_ctor_func(zval *zvalue) { if (EXPECTED(Z_TYPE_P(zvalue) == IS_ARRAY)) { ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue))); } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) { - CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue)); + ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue))); + CHECK_ZVAL_STRING(Z_STR_P(zvalue)); ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0)); - } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT)) { - CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue)); - Z_STR_P(zvalue) = zend_string_dup(Z_STR_P(zvalue), 0); - } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_CONSTANT_AST)) { - zend_ast *copy = zend_ast_copy(Z_ASTVAL_P(zvalue)); - ZVAL_NEW_AST(zvalue, copy); } } - -ZEND_API size_t zend_print_variable(zval *var) -{ - return zend_print_zval(var, 0); -} - - -ZEND_API void _zval_dtor_wrapper(zval *zvalue) -{ - zval_dtor(zvalue); -} - - -#if ZEND_DEBUG -ZEND_API void _zval_internal_dtor_wrapper(zval *zvalue) -{ - zval_internal_dtor(zvalue); -} - - -ZEND_API void _zval_ptr_dtor_wrapper(zval *zval_ptr) -{ - - i_zval_ptr_dtor(zval_ptr ZEND_FILE_LINE_CC); -} - - -ZEND_API void _zval_internal_ptr_dtor_wrapper(zval *zval_ptr) -{ - zval_internal_ptr_dtor(zval_ptr); -} -#endif - /* * Local variables: * tab-width: 4 |