zend_variables.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.00 of the Zend license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.zend.com/license/2_00.txt. |
  11. | If you did not receive a copy of the Zend license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@zend.com so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Andi Gutmans <andi@php.net> |
  16. | Zeev Suraski <zeev@php.net> |
  17. | Dmitry Stogov <dmitry@php.net> |
  18. +----------------------------------------------------------------------+
  19. */
  20. #include <stdio.h>
  21. #include "zend.h"
  22. #include "zend_API.h"
  23. #include "zend_ast.h"
  24. #include "zend_globals.h"
  25. #include "zend_constants.h"
  26. #include "zend_list.h"
  27. #if ZEND_DEBUG
  28. static void ZEND_FASTCALL zend_string_destroy(zend_string *str);
  29. #else
  30. # define zend_string_destroy _efree
  31. #endif
  32. static void ZEND_FASTCALL zend_reference_destroy(zend_reference *ref);
  33. static void ZEND_FASTCALL zend_empty_destroy(zend_reference *ref);
  34. typedef void (ZEND_FASTCALL *zend_rc_dtor_func_t)(zend_refcounted *p);
  35. static const zend_rc_dtor_func_t zend_rc_dtor_func[] = {
  36. /* IS_UNDEF */ (zend_rc_dtor_func_t)zend_empty_destroy,
  37. /* IS_NULL */ (zend_rc_dtor_func_t)zend_empty_destroy,
  38. /* IS_FALSE */ (zend_rc_dtor_func_t)zend_empty_destroy,
  39. /* IS_TRUE */ (zend_rc_dtor_func_t)zend_empty_destroy,
  40. /* IS_LONG */ (zend_rc_dtor_func_t)zend_empty_destroy,
  41. /* IS_DOUBLE */ (zend_rc_dtor_func_t)zend_empty_destroy,
  42. /* IS_STRING */ (zend_rc_dtor_func_t)zend_string_destroy,
  43. /* IS_ARRAY */ (zend_rc_dtor_func_t)zend_array_destroy,
  44. /* IS_OBJECT */ (zend_rc_dtor_func_t)zend_objects_store_del,
  45. /* IS_RESOURCE */ (zend_rc_dtor_func_t)zend_list_free,
  46. /* IS_REFERENCE */ (zend_rc_dtor_func_t)zend_reference_destroy,
  47. /* IS_CONSTANT_AST */ (zend_rc_dtor_func_t)zend_ast_ref_destroy
  48. };
  49. ZEND_API void ZEND_FASTCALL rc_dtor_func(zend_refcounted *p)
  50. {
  51. ZEND_ASSERT(GC_TYPE(p) <= IS_CONSTANT_AST);
  52. zend_rc_dtor_func[GC_TYPE(p)](p);
  53. }
  54. #if ZEND_DEBUG
  55. static void ZEND_FASTCALL zend_string_destroy(zend_string *str)
  56. {
  57. CHECK_ZVAL_STRING(str);
  58. ZEND_ASSERT(!ZSTR_IS_INTERNED(str));
  59. ZEND_ASSERT(GC_REFCOUNT(str) == 0);
  60. ZEND_ASSERT(!(GC_FLAGS(str) & IS_STR_PERSISTENT));
  61. efree(str);
  62. }
  63. #endif
  64. static void ZEND_FASTCALL zend_reference_destroy(zend_reference *ref)
  65. {
  66. ZEND_ASSERT(!ZEND_REF_HAS_TYPE_SOURCES(ref));
  67. i_zval_ptr_dtor(&ref->val);
  68. efree_size(ref, sizeof(zend_reference));
  69. }
  70. static void ZEND_FASTCALL zend_empty_destroy(zend_reference *ref)
  71. {
  72. }
  73. ZEND_API void zval_ptr_dtor(zval *zval_ptr) /* {{{ */
  74. {
  75. i_zval_ptr_dtor(zval_ptr);
  76. }
  77. /* }}} */
  78. ZEND_API void zval_internal_ptr_dtor(zval *zval_ptr) /* {{{ */
  79. {
  80. if (Z_REFCOUNTED_P(zval_ptr)) {
  81. zend_refcounted *ref = Z_COUNTED_P(zval_ptr);
  82. if (GC_DELREF(ref) == 0) {
  83. if (Z_TYPE_P(zval_ptr) == IS_STRING) {
  84. zend_string *str = (zend_string*)ref;
  85. CHECK_ZVAL_STRING(str);
  86. ZEND_ASSERT(!ZSTR_IS_INTERNED(str));
  87. ZEND_ASSERT((GC_FLAGS(str) & IS_STR_PERSISTENT));
  88. free(str);
  89. } else {
  90. zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects, resources or reference");
  91. }
  92. }
  93. }
  94. }
  95. /* }}} */
  96. /* This function should only be used as a copy constructor, i.e. it
  97. * should only be called AFTER a zval has been copied to another
  98. * location using ZVAL_COPY_VALUE. Do not call it before copying,
  99. * otherwise a reference may be leaked. */
  100. ZEND_API void zval_add_ref(zval *p)
  101. {
  102. if (Z_REFCOUNTED_P(p)) {
  103. if (Z_ISREF_P(p) && Z_REFCOUNT_P(p) == 1) {
  104. ZVAL_COPY(p, Z_REFVAL_P(p));
  105. } else {
  106. Z_ADDREF_P(p);
  107. }
  108. }
  109. }
  110. ZEND_API void ZEND_FASTCALL zval_copy_ctor_func(zval *zvalue)
  111. {
  112. if (EXPECTED(Z_TYPE_P(zvalue) == IS_ARRAY)) {
  113. ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue)));
  114. } else if (EXPECTED(Z_TYPE_P(zvalue) == IS_STRING)) {
  115. ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue)));
  116. CHECK_ZVAL_STRING(Z_STR_P(zvalue));
  117. ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0));
  118. } else {
  119. ZEND_UNREACHABLE();
  120. }
  121. }