]> granicus.if.org Git - php/commitdiff
We cannot safely assume that all op array will be refcount 0 after execution
authorBob Weinand <bobwei9@hotmail.com>
Wed, 22 Jul 2015 15:15:09 +0000 (17:15 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Wed, 22 Jul 2015 15:16:16 +0000 (17:16 +0200)
Some extensions may want to analyze or re-run the op array later

Zend/zend_compile.h
Zend/zend_opcode.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 06796aab831fc6d1362594041d649d44e1c440c7..96a1f950783799eaff8d9b4a589ee59abc7df40b 100644 (file)
@@ -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);
index 62869373dd22539026d800be2a223bf38f1f1a65..b0242c800e1fdeccd37b8e88a12e44096adcfce3 100644 (file)
@@ -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)
index ac592197ee9cad7bcd2d16048feb81168e34ee35..c26bfce13a50ddb64716c5e933ae898de61fa0e7 100644 (file)
@@ -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();
index 9b4d2107fa5b1c22b2081dead3ab3bf68ed805d5..bfd9c5ff42a43ce663505df990bdb79ebd7e3daa 100644 (file)
@@ -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();