summaryrefslogtreecommitdiff
path: root/Zend/zend_closures.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_closures.c')
-rw-r--r--Zend/zend_closures.c54
1 files changed, 21 insertions, 33 deletions
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index f478578c3e..c534c8838a 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -36,7 +36,6 @@ typedef struct _zend_closure {
zend_object std;
zend_function func;
zval *this_ptr;
- zend_function *invoke;
} zend_closure;
static zend_class_entry *zend_ce_closure;
@@ -44,6 +43,7 @@ static zend_object_handlers closure_handlers;
ZEND_METHOD(Closure, __invoke) /* {{{ */
{
+ zend_function *func = EG(current_execute_data)->function_state.function;
zval ***arguments;
zval *closure_result_ptr = NULL;
@@ -51,16 +51,10 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
efree(arguments);
zend_error(E_ERROR, "Cannot get arguments for calling closure");
- RETURN_FALSE;
- }
-
- if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
- efree(arguments);
- RETURN_FALSE;
- }
-
- efree(arguments);
- if (closure_result_ptr) {
+ RETVAL_FALSE;
+ } else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
+ RETVAL_FALSE;
+ } else if (closure_result_ptr) {
if (Z_ISREF_P(closure_result_ptr) && return_value_ptr) {
if (return_value) {
zval_ptr_dtor(&return_value);
@@ -70,13 +64,12 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */
RETVAL_ZVAL(closure_result_ptr, 1, 1);
}
}
-}
-/* }}} */
+ efree(arguments);
-const static zend_function_entry closure_functions[] = { /* {{{ */
- ZEND_ME(Closure, __invoke, NULL, 0)
- {NULL, NULL, NULL}
-};
+ /* destruct the function also, then - we have allocated it in get_method */
+ efree(func->internal_function.function_name);
+ efree(func);
+}
/* }}} */
static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{{ */
@@ -123,18 +116,17 @@ static zend_function *zend_closure_get_method(zval **object_ptr, char *method_na
memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
) {
zend_closure *closure = (zend_closure *)zend_object_store_get_object(*object_ptr TSRMLS_CC);
-
- if (!closure->invoke) {
- closure->invoke = (zend_function*)emalloc(sizeof(zend_function));
- closure->invoke->common = closure->func.common;
- closure->invoke->type = ZEND_INTERNAL_FUNCTION;
- closure->invoke->internal_function.handler = ZEND_MN(Closure___invoke);
- closure->invoke->internal_function.module = 0;
- closure->invoke->internal_function.scope = zend_ce_closure;
- closure->invoke->internal_function.function_name = ZEND_INVOKE_FUNC_NAME;
- }
+ zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
+
+ invoke->common = closure->func.common;
+ invoke->type = ZEND_INTERNAL_FUNCTION;
+ invoke->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
+ invoke->internal_function.handler = ZEND_MN(Closure___invoke);
+ invoke->internal_function.module = 0;
+ invoke->internal_function.scope = zend_ce_closure;
+ invoke->internal_function.function_name = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
free_alloca(lc_name, use_heap);
- return (zend_function *)closure->invoke;
+ return invoke;
}
free_alloca(lc_name, use_heap);
return NULL;
@@ -195,10 +187,6 @@ static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */
zval_ptr_dtor(&closure->this_ptr);
}
- if (closure->invoke) {
- efree(closure->invoke);
- }
-
efree(closure);
}
/* }}} */
@@ -224,7 +212,7 @@ void zend_register_closure_ce(TSRMLS_D) /* {{{ */
{
zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, "Closure", closure_functions);
+ INIT_CLASS_ENTRY(ce, "Closure", NULL);
zend_ce_closure = zend_register_internal_class(&ce TSRMLS_CC);
zend_ce_closure->ce_flags |= ZEND_ACC_FINAL_CLASS;
zend_ce_closure->create_object = zend_closure_new;