From b11fa4eb6b0682974af113bcc9b92755effd4a86 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 22 Jul 2012 14:25:00 -0700 Subject: [PATCH 1/2] use zend_execute_internal --- Zend/zend_execute_API.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1deee2a86c89e..fcc19f685eff1 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -406,7 +406,7 @@ ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */ ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */ { - if(EG(exception) && EG(opline_ptr) && active_opline->opcode == ZEND_HANDLE_EXCEPTION && + if(EG(exception) && EG(opline_ptr) && active_opline->opcode == ZEND_HANDLE_EXCEPTION && active_opline->lineno == 0 && EG(opline_before_exception)) { return EG(opline_before_exception)->lineno; } @@ -600,7 +600,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *)); Z_ARRVAL_P(p) = tmp_ht; - } + } /* First go over the array and see if there are any constant indices */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); @@ -977,7 +977,15 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (EX(function_state).function->common.scope) { EG(scope) = EX(function_state).function->common.scope; } - ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); + + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); + } else { + zend_execute_internal(&execute_data, 1 TSRMLS_CC); + } + + /* We shouldn't fix bad extensions here, because it can break proper ones (Bug #34045) if (!EX(function_state).function->common.return_reference) @@ -1312,9 +1320,9 @@ void execute_new_code(TSRMLS_D) /* {{{ */ ZEND_VM_SET_OPCODE_HANDLER(opline); opline++; } - + zend_release_labels(TSRMLS_C); - + EG(return_value_ptr_ptr) = NULL; EG(active_op_array) = CG(active_op_array); orig_interactive = CG(interactive); @@ -1337,11 +1345,11 @@ ZEND_API void zend_timeout(int dummy) /* {{{ */ if (zend_on_timeout) { #ifdef ZEND_SIGNALS - /* + /* We got here because we got a timeout signal, so we are in a signal handler at this point. However, we want to be able to timeout any user-supplied shutdown functions, so pretend we are not in a signal handler while we are - calling these + calling these */ SIGG(running) = 0; #endif @@ -1590,7 +1598,7 @@ zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, zend_error(E_ERROR, "Trait '%s' not found", class_name); } else { zend_error(E_ERROR, "Class '%s' not found", class_name); - } + } } } return NULL; @@ -1613,7 +1621,7 @@ zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_na zend_error(E_ERROR, "Trait '%s' not found", class_name); } else { zend_error(E_ERROR, "Class '%s' not found", class_name); - } + } } } return NULL; @@ -1754,7 +1762,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ zend_execute_data *ex; if (!EG(active_symbol_table)) { - + /* Search for last called user function */ ex = EG(current_execute_data); while (ex && !ex->op_array) { From cd5b933b149b6f9bfecfad0111c251ed874b0ae1 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 26 Aug 2012 23:29:24 -0700 Subject: [PATCH 2/2] use zend_execute_internal if set on internal-internal calls This will allow modules that override zend_execute_internal to intercept all internal function calls, not just user-internal calls. --- Zend/zend_dtrace.c | 4 ++-- Zend/zend_dtrace.h | 4 ++-- Zend/zend_execute.c | 16 ++++++++++++---- Zend/zend_execute.h | 13 +++++++------ Zend/zend_execute_API.c | 9 +++------ Zend/zend_vm_def.h | 14 +++++++------- Zend/zend_vm_execute.h | 2 +- 7 files changed, 34 insertions(+), 28 deletions(-) diff --git a/Zend/zend_dtrace.c b/Zend/zend_dtrace.c index 5b2d0d2dfed21..3d109deabd96d 100644 --- a/Zend/zend_dtrace.c +++ b/Zend/zend_dtrace.c @@ -83,7 +83,7 @@ ZEND_API void dtrace_execute(zend_op_array *op_array TSRMLS_DC) } } -ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) +ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC) { int lineno; char *filename; @@ -96,7 +96,7 @@ ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, int r DTRACE_EXECUTE_ENTRY(filename, lineno); } - execute_internal(execute_data_ptr, return_value_used TSRMLS_CC); + execute_internal(execute_data_ptr, fci, return_value_used TSRMLS_CC); if (DTRACE_EXECUTE_RETURN_ENABLED()) { DTRACE_EXECUTE_RETURN(filename, lineno); diff --git a/Zend/zend_dtrace.h b/Zend/zend_dtrace.h index 65d19ef346a85..49388e562f7ff 100644 --- a/Zend/zend_dtrace.h +++ b/Zend/zend_dtrace.h @@ -32,11 +32,11 @@ extern "C" { #ifdef HAVE_DTRACE ZEND_API zend_op_array *(*zend_dtrace_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); ZEND_API void (*zend_dtrace_execute)(zend_op_array *op_array TSRMLS_DC); -ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); +ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); ZEND_API void dtrace_execute(zend_op_array *op_array TSRMLS_DC); -ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); +ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); #include #endif /* HAVE_DTRACE */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index fbc73258c7090..6a809baa8a14b 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1474,10 +1474,18 @@ static int zend_check_symbol(zval **pz TSRMLS_DC) ZEND_API opcode_handler_t *zend_opcode_handlers; -ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC) +ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC) { - zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; - ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, (execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC); + if(fci != NULL) { + ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(fci->param_count, + *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); + + } else { + zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr; + ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, + (execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, + execute_data_ptr->object, return_value_used TSRMLS_CC); + } } #define ZEND_VM_NEXT_OPCODE() \ @@ -1512,7 +1520,7 @@ ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler { if (opcode != ZEND_USER_OPCODE) { if (handler == NULL) { - /* restore the original handler */ + /* restore the original handler */ zend_user_opcodes[opcode] = opcode; } else { zend_user_opcodes[opcode] = ZEND_USER_OPCODE; diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 7d427388bdadd..b5ac47b14e321 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -5,7 +5,7 @@ | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | + | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.zend.com/license/2_00.txt. | | If you did not receive a copy of the Zend license and are unable to | @@ -49,14 +49,15 @@ typedef union _temp_variable { BEGIN_EXTERN_C() +struct _zend_fcall_info; ZEND_API extern void (*zend_execute)(zend_op_array *op_array TSRMLS_DC); -ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); +ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC); void init_executor(TSRMLS_D); void shutdown_executor(TSRMLS_D); void shutdown_destructors(TSRMLS_D); ZEND_API void execute(zend_op_array *op_array TSRMLS_DC); -ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); +ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC); ZEND_API int zend_is_true(zval *op); #define safe_free_zval_ptr(p) safe_free_zval_ptr_rel(p ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC) static zend_always_inline void safe_free_zval_ptr_rel(zval *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) @@ -270,7 +271,7 @@ static zend_always_inline void *zend_vm_stack_alloc(size_t size TSRMLS_DC) } static zend_always_inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC) -{ +{ if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) { zend_vm_stack p = EG(argument_stack); @@ -282,7 +283,7 @@ static zend_always_inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC) } static zend_always_inline void zend_vm_stack_free(void *ptr TSRMLS_DC) -{ +{ if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) { zend_vm_stack p = EG(argument_stack); @@ -302,7 +303,7 @@ static zend_always_inline void zend_vm_stack_free(void *ptr TSRMLS_DC) static zend_always_inline void** zend_vm_stack_push_args(int count TSRMLS_DC) { - if (UNEXPECTED(EG(argument_stack)->top - ZEND_VM_STACK_ELEMETS(EG(argument_stack)) < count) || + if (UNEXPECTED(EG(argument_stack)->top - ZEND_VM_STACK_ELEMETS(EG(argument_stack)) < count) || UNEXPECTED(EG(argument_stack)->top == EG(argument_stack)->end)) { zend_vm_stack p = EG(argument_stack); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fcc19f685eff1..815f9706ac53d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -38,7 +38,7 @@ #endif ZEND_API void (*zend_execute)(zend_op_array *op_array TSRMLS_DC); -ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC); +ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); /* true globals */ ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 }; @@ -977,15 +977,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (EX(function_state).function->common.scope) { EG(scope) = EX(function_state).function->common.scope; } - - if (!zend_execute_internal) { + if(EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); } else { - zend_execute_internal(&execute_data, 1 TSRMLS_CC); + zend_execute_internal(&execute_data, fci, 1 TSRMLS_CC); } - - /* We shouldn't fix bad extensions here, because it can break proper ones (Bug #34045) if (!EX(function_state).function->common.return_reference) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 92c5fcf40fe7f..af4890f1b7aa3 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2028,7 +2028,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) /* saves one function call if zend_execute_internal is not used */ fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { - zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC); + zend_execute_internal(EXECUTE_DATA, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); } if (!RETURN_VALUE_USED(opline)) { @@ -2151,7 +2151,7 @@ ZEND_VM_HELPER_EX(zend_finally_handler_leaving, ANY, ANY, int type) for (i=0; ilast_try_catch; i++) { if (EX(op_array)->try_catch_array[i].try_op > op_num) { break; - } + } if (op_num < EX(op_array)->try_catch_array[i].finally_op) { finally_op_num = EX(op_array)->try_catch_array[i].finally_op; } @@ -2163,7 +2163,7 @@ ZEND_VM_HELPER_EX(zend_finally_handler_leaving, ANY, ANY, int type) for (i=0; ilast_try_catch; i++) { if (EX(op_array)->try_catch_array[i].try_op > op_num) { break; - } + } if (op_num < EX(op_array)->try_catch_array[i].finally_op) { finally_op_num = EX(op_array)->try_catch_array[i].finally_op; } @@ -2207,8 +2207,8 @@ ZEND_VM_HELPER_EX(zend_finally_handler_leaving, ANY, ANY, int type) for (i=0; ilast_try_catch; i++) { if (EG(active_op_array)->try_catch_array[i].try_op > op_num) { break; - } - if (op_num < EG(active_op_array)->try_catch_array[i].finally_op + } + if (op_num < EG(active_op_array)->try_catch_array[i].finally_op && (EX(leaving_dest) < EG(active_op_array)->try_catch_array[i].try_op || EX(leaving_dest) >= EG(active_op_array)->try_catch_array[i].finally_end)) { finally_op_num = EG(active_op_array)->try_catch_array[i].finally_op; @@ -5145,7 +5145,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) if (EG(active_op_array)->try_catch_array[i].try_op > op_num) { /* further blocks will not be relevant... */ break; - } + } if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) { catch_op_num = EX(op_array)->try_catch_array[i].catch_op; catched = i + 1; @@ -5221,7 +5221,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]); ZEND_VM_CONTINUE(); } - } else if (catched) { + } else if (catched) { EX(leaving) = 0; ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]); ZEND_VM_CONTINUE(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 1e0b2b50a98d4..feace93c5a947 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -615,7 +615,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR /* saves one function call if zend_execute_internal is not used */ fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC); } else { - zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC); + zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC); } if (!RETURN_VALUE_USED(opline)) {