diff options
Diffstat (limited to 'Zend/zend_closures.c')
| -rw-r--r-- | Zend/zend_closures.c | 54 |
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; |
