summaryrefslogtreecommitdiff
path: root/Zend/zend_variables.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_variables.c')
-rw-r--r--Zend/zend_variables.c249
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