summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.c
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2012-06-09 00:40:47 +0200
committerNikita Popov <nikic@php.net>2012-06-09 00:40:47 +0200
commitf169b26dd7a4047996ab1284e649fda0cfb1a10b (patch)
tree342b4ada98867d105eeba50235410df0979a0f7f /Zend/zend_execute.c
parent40760ecb90d1b024c76862e33d13d40137650af7 (diff)
downloadphp-git-f169b26dd7a4047996ab1284e649fda0cfb1a10b.tar.gz
Fix backtraces and func_get_args()
To make the generator function show up in backtraces one has to insert an additional execute_data into the chain, as prev_execute_data->function_state is used to determine the called function. Adding the additional stack frame is also required for func_get_args(), as the arguments are fetched from there too. The arguments have to be copied in order to keep them around. Due to the way they are saved doing so is quite ugly, so I added another function zend_copy_arguments to zend_execute.c which handles this.
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r--Zend/zend_execute.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 9031fb5557..c7ef212887 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1563,6 +1563,25 @@ void zend_free_compiled_variables(zval ***CVs, int num) /* {{{ */
}
/* }}} */
+void** zend_copy_arguments(void **arguments_end) /* {{{ */
+{
+ int arguments_count = (int) (zend_uintptr_t) *arguments_end;
+ size_t arguments_size = (arguments_count + 1) * sizeof(void **);
+ void **arguments_start = arguments_end - arguments_count;
+ void **copied_arguments_start = emalloc(arguments_size);
+ void **copied_arguments_end = copied_arguments_start + arguments_count;
+ int i;
+
+ memcpy(copied_arguments_start, arguments_start, arguments_size);
+
+ for (i = 0; i < arguments_count; i++) {
+ Z_ADDREF_P((zval *) arguments_start[i]);
+ }
+
+ return copied_arguments_end;
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4