static int zend_create_closure_from_callable(zval *return_value, zval *callable, char **error) /* {{{ */ { zend_fcall_info_cache fcc; zend_function *mptr; zval instance; zend_internal_function call; if (!zend_is_callable_ex(callable, NULL, 0, NULL, &fcc, error)) { return FAILURE; } mptr = fcc.function_handler; if (mptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { memset(&call, 0, sizeof(zend_internal_function)); call.type = ZEND_INTERNAL_FUNCTION; call.handler = zend_closure_call_magic; call.function_name = mptr->common.function_name; call.arg_info = (zend_internal_arg_info *) mptr->common.prototype; call.scope = mptr->common.scope; zend_free_trampoline(mptr); mptr = (zend_function *) &call; } if (fcc.object) { ZVAL_OBJ(&instance, fcc.object); zend_create_fake_closure(return_value, mptr, mptr->common.scope, fcc.called_scope, &instance); } else { zend_create_fake_closure(return_value, mptr, mptr->common.scope, fcc.called_scope, NULL); } return SUCCESS; }
static void autoload_func_info_dtor(zval *element) { autoload_func_info *alfi = (autoload_func_info*)Z_PTR_P(element); if (!Z_ISUNDEF(alfi->obj)) { zval_ptr_dtor(&alfi->obj); } if (alfi->func_ptr && UNEXPECTED(alfi->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { zend_string_release(alfi->func_ptr->common.function_name); zend_free_trampoline(alfi->func_ptr); } if (!Z_ISUNDEF(alfi->closure)) { zval_ptr_dtor(&alfi->closure); } efree(alfi); }