Fix leaks

Must find a good way to handle constant expressions...
This commit is contained in:
Nikita Popov 2014-07-26 18:08:31 +02:00
parent d46f67a3a7
commit edd9fcab1e
7 changed files with 27 additions and 17 deletions

View File

@ -50,6 +50,7 @@ ZEND_API zend_ast *zend_ast_create_decl(
unsigned char *lex_pos, zend_string *doc_comment, zend_string *name,
zend_ast *child0, zend_ast *child1, zend_ast *child2
) {
TSRMLS_FETCH();
zend_ast_decl *ast = zend_arena_alloc(&CG(ast_arena), sizeof(zend_ast_decl));
ast->kind = kind;
@ -139,6 +140,7 @@ static inline zend_bool is_power_of_two(unsigned short n) {
ZEND_API zend_ast *zend_ast_dynamic_add(zend_ast *ast, zend_ast *op)
{
if (ast->children >= 4 && is_power_of_two(ast->children)) {
TSRMLS_FETCH();
size_t old_size = sizeof(zend_ast) + sizeof(zend_ast *) * (ast->children - 1);
zend_ast *new_ast = zend_arena_alloc(&CG(ast_arena),
sizeof(zend_ast) + sizeof(zend_ast *) * (ast->children * 2 - 1));
@ -355,8 +357,7 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
}
}
ZEND_API void zend_ast_destroy(zend_ast *ast)
{
static void zend_ast_destroy_ex(zend_ast *ast, zend_bool free) {
if (!ast) {
return;
}
@ -377,19 +378,28 @@ ZEND_API void zend_ast_destroy(zend_ast *ast)
if (decl->doc_comment) {
STR_RELEASE(decl->doc_comment);
}
zend_ast_destroy(decl->child[0]);
zend_ast_destroy(decl->child[1]);
zend_ast_destroy(decl->child[2]);
zend_ast_destroy_ex(decl->child[0], free);
zend_ast_destroy_ex(decl->child[1], free);
zend_ast_destroy_ex(decl->child[2], free);
break;
}
default:
{
zend_uint i;
for (i = 0; i < ast->children; i++) {
zend_ast_destroy(ast->child[i]);
zend_ast_destroy_ex(ast->child[i], free);
}
}
}
//efree(ast);
if (free) {
efree(ast);
}
}
ZEND_API void zend_ast_destroy(zend_ast *ast) {
zend_ast_destroy_ex(ast, 0);
}
ZEND_API void zend_ast_destroy_and_free(zend_ast *ast) {
zend_ast_destroy_ex(ast, 1);
}

View File

@ -185,6 +185,7 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
ZEND_API zend_ast *zend_ast_copy(zend_ast *ast);
ZEND_API void zend_ast_destroy(zend_ast *ast);
ZEND_API void zend_ast_destroy_and_free(zend_ast *ast);
static inline zend_ast *zend_ast_create_zval(zval *zv) {
return zend_ast_create_zval_ex(zv, 0);

View File

@ -3426,14 +3426,13 @@ static void _tmp_compile_const_expr(zval *result, zend_ast *ast TSRMLS_DC) {
zend_eval_const_expr(&ast TSRMLS_CC);
zend_compile_const_expr(&ast TSRMLS_CC);
if (ast->kind == ZEND_AST_ZVAL) {
ZVAL_COPY(result, zend_ast_get_zval(ast));
ZVAL_COPY_VALUE(result, zend_ast_get_zval(ast));
if (Z_TYPE_P(result) == IS_ARRAY) {
zend_make_immutable_array_r(result TSRMLS_CC);
}
orig_ast->kind = ZEND_AST_ZNODE;
} else {
ast = zend_ast_copy(ast);
ZVAL_NEW_AST(result, ast);
ZVAL_NEW_AST(result, zend_ast_copy(ast));
}
}

View File

@ -606,7 +606,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas
zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope TSRMLS_CC);
if (inline_change) {
zend_ast_destroy(Z_ASTVAL_P(p));
zend_ast_destroy_and_free(Z_ASTVAL_P(p));
efree(Z_AST_P(p));
}
ZVAL_COPY_VALUE(p, &tmp);

View File

@ -585,7 +585,7 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
CG(active_op_array) = op_array;
zend_stack_push(&CG(context_stack), (void *) &CG(context));
zend_init_compiler_context(TSRMLS_C);
CG(ast_arena) = zend_arena_create(1024 * 32 TSRMLS_CC);
CG(ast_arena) = zend_arena_create(1024 * 32);
compiler_result = zendparse(TSRMLS_C);
if (compiler_result != 0) { /* parser error */
zend_bailout();
@ -757,7 +757,7 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
zend_stack_push(&CG(context_stack), (void *) &CG(context));
zend_init_compiler_context(TSRMLS_C);
BEGIN(ST_IN_SCRIPTING);
CG(ast_arena) = zend_arena_create(1024 * 32 TSRMLS_CC);
CG(ast_arena) = zend_arena_create(1024 * 32);
compiler_result = zendparse(TSRMLS_C);
if (SCNG(script_filtered)) {

View File

@ -583,7 +583,7 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
CG(active_op_array) = op_array;
zend_stack_push(&CG(context_stack), (void *) &CG(context));
zend_init_compiler_context(TSRMLS_C);
CG(ast_arena) = zend_arena_create(1024 * 32 TSRMLS_CC);
CG(ast_arena) = zend_arena_create(1024 * 32);
compiler_result = zendparse(TSRMLS_C);
if (compiler_result != 0) { /* parser error */
zend_bailout();
@ -755,7 +755,7 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
zend_stack_push(&CG(context_stack), (void *) &CG(context));
zend_init_compiler_context(TSRMLS_C);
BEGIN(ST_IN_SCRIPTING);
CG(ast_arena) = zend_arena_create(1024 * 32 TSRMLS_CC);
CG(ast_arena) = zend_arena_create(1024 * 32);
compiler_result = zendparse(TSRMLS_C);
if (SCNG(script_filtered)) {

View File

@ -53,7 +53,7 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
case IS_CONSTANT_AST: {
zend_ast_ref *ast = (zend_ast_ref*)p;
zend_ast_destroy(ast->ast);
zend_ast_destroy_and_free(ast->ast);
efree(ast);
break;
}
@ -113,7 +113,7 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC)
case IS_CONSTANT_AST: {
zend_ast_ref *ast = (zend_ast_ref*)p;
zend_ast_destroy(ast->ast);
zend_ast_destroy_and_free(ast->ast);
efree(ast);
break;
}