diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 5cee47fc413..b4deb62f825 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -40,6 +40,9 @@ void copy_zend_constant(zend_constant *c) c->name = zend_strndup(c->name, c->name_len); if (!(c->flags & CONST_PERSISTENT)) { zval_copy_ctor(&c->value); + if (c->flags & CONST_EFREE_PERSISTENT) { /* persist_alloc()'d data */ + persist_alloc(&c->value); + } } } diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index d8491460c4d..85df4c86569 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -23,8 +23,12 @@ #include "zend_globals.h" -#define CONST_CS 0x1 /* Case Sensitive */ -#define CONST_PERSISTENT 0x2 +#define CONST_CS (1<<0) /* Case Sensitive */ +#define CONST_PERSISTENT (1<<1) /* Persistent */ +#define CONST_EFREE_PERSISTENT (1<<2) /* In conjunction with CONST_PERSISTENT, + * means that the constant should be freed + * using zval_dtor() on shutdown. + */ typedef struct _zend_constant { zval value; diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index 757019860c9..f919fb8c85f 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -126,6 +126,40 @@ ZEND_API int _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC) } +ZEND_API int zval_persist(zval *zvalue TSRMLS_DC) +{ + switch (zvalue->type) { + case IS_RESOURCE: + return FAILURE; /* resources cannot be persisted */ + break; + case IS_BOOL: + case IS_LONG: + case IS_NULL: + break; + case IS_CONSTANT: + case IS_STRING: + if (zvalue->value.str.val) { + if (zvalue->value.str.len==0) { + zvalue->value.str.val = empty_string; + return SUCCESS; + } + } + persist_alloc(zvalue->value.str.val); + break; + case IS_ARRAY: + case IS_CONSTANT_ARRAY: + persist_alloc(zvalue->value.ht); + zend_hash_apply(zvalue->value.ht, (apply_func_t) zval_persist TSRMLS_CC); + break; + case IS_OBJECT: + persist_alloc(zvalue->value.obj.properties); + zend_hash_apply(zvalue->value.obj.properties, (apply_func_t) zval_persist TSRMLS_CC); + break; + } + return SUCCESS; +} + + ZEND_API int zend_print_variable(zval *var) { return zend_print_zval(var, 0); diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h index 5b6a68481c0..20a75b50e67 100644 --- a/Zend/zend_variables.h +++ b/Zend/zend_variables.h @@ -32,6 +32,8 @@ ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC); #define zval_dtor(zvalue) _zval_dtor((zvalue) ZEND_FILE_LINE_CC) #define zval_ptr_dtor(zval_ptr) _zval_ptr_dtor((zval_ptr) ZEND_FILE_LINE_CC) +ZEND_API int zval_persist(zval *zvalue TSRMLS_DC); + #if ZEND_DEBUG ZEND_API int _zval_copy_ctor_wrapper(zval *zvalue); ZEND_API void _zval_dtor_wrapper(zval *zvalue);