From: Bob Weinand Date: Wed, 22 Jul 2015 15:15:09 +0000 (+0200) Subject: We cannot safely assume that all op array will be refcount 0 after execution X-Git-Tag: php-7.0.0beta3~5^2~103^2~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6936adb58288a0606ed847802d9226cddb41e2b;p=php We cannot safely assume that all op array will be refcount 0 after execution Some extensions may want to analyze or re-run the op array later --- diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 06796aab83..96a1f95078 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -726,7 +726,7 @@ ZEND_API zend_op_array *compile_filename(int type, zval *filename); ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...); ZEND_API int open_file_for_scanning(zend_file_handle *file_handle); ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size); -ZEND_API void destroy_op_array(zend_op_array *op_array); +ZEND_API zend_bool destroy_op_array(zend_op_array *op_array); ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle); ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce); ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 62869373dd..b0242c800e 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -335,7 +335,7 @@ void zend_class_add_ref(zval *zv) ce->refcount++; } -ZEND_API void destroy_op_array(zend_op_array *op_array) +ZEND_API zend_bool destroy_op_array(zend_op_array *op_array) { zval *literal = op_array->literals; zval *end; @@ -352,8 +352,8 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) efree(op_array->run_time_cache); } - if (!op_array->refcount || --(*op_array->refcount)>0) { - return; + if (!op_array->refcount || --(*op_array->refcount) > 0) { + return 0; } efree_size(op_array->refcount, sizeof(*(op_array->refcount))); @@ -414,6 +414,8 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) } efree(arg_info); } + + return 1; } void init_op(zend_op *op) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index ac592197ee..c26bfce13a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2364,8 +2364,9 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) ZEND_VM_LEAVE(); } else if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_CODE) { zend_detach_symbol_table(execute_data); - destroy_op_array(&EX(func)->op_array); - efree_size(EX(func), sizeof(zend_op_array)); + if (EXPECTED(destroy_op_array(&EX(func)->op_array) != 0)) { + efree_size(EX(func), sizeof(zend_op_array)); + } old_execute_data = execute_data; execute_data = EG(current_execute_data) = EX(prev_execute_data); zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); @@ -5434,7 +5435,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY) } call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); + i_init_code_execute_data(call, new_op_array, return_value); if (EXPECTED(zend_execute_ex == execute_ex)) { ZEND_VM_ENTER(); } else { @@ -5443,8 +5444,9 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY) zend_vm_stack_free_call_frame(call); } - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); + if (EXPECTED(destroy_op_array(new_op_array) != 0)) { + efree_size(new_op_array, sizeof(zend_op_array)); + } if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9b4d2107fa..bfd9c5ff42 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -503,8 +503,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ ZEND_VM_LEAVE(); } else if (ZEND_CALL_KIND_EX(call_info) == ZEND_CALL_NESTED_CODE) { zend_detach_symbol_table(execute_data); - destroy_op_array(&EX(func)->op_array); - efree_size(EX(func), sizeof(zend_op_array)); + if (EXPECTED(destroy_op_array(&EX(func)->op_array) != 0)) { + efree_size(EX(func), sizeof(zend_op_array)); + } old_execute_data = execute_data; execute_data = EG(current_execute_data) = EX(prev_execute_data); zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); @@ -3642,7 +3643,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN } call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); + i_init_code_execute_data(call, new_op_array, return_value); if (EXPECTED(zend_execute_ex == execute_ex)) { ZEND_VM_ENTER(); } else { @@ -3651,8 +3652,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN zend_vm_stack_free_call_frame(call); } - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); + if (EXPECTED(destroy_op_array(new_op_array) != 0)) { + efree_size(new_op_array, sizeof(zend_op_array)); + } if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); @@ -28986,7 +28988,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE } call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); + i_init_code_execute_data(call, new_op_array, return_value); if (EXPECTED(zend_execute_ex == execute_ex)) { ZEND_VM_ENTER(); } else { @@ -28995,8 +28997,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE zend_vm_stack_free_call_frame(call); } - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); + if (EXPECTED(destroy_op_array(new_op_array) != 0)) { + efree_size(new_op_array, sizeof(zend_op_array)); + } if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); @@ -40392,7 +40395,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA } call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); + i_init_code_execute_data(call, new_op_array, return_value); if (EXPECTED(zend_execute_ex == execute_ex)) { ZEND_VM_ENTER(); } else { @@ -40401,8 +40404,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA zend_vm_stack_free_call_frame(call); } - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); + if (EXPECTED(destroy_op_array(new_op_array) != 0)) { + efree_size(new_op_array, sizeof(zend_op_array)); + } if (UNEXPECTED(EG(exception) != NULL)) { zend_throw_exception_internal(NULL); HANDLE_EXCEPTION();