#include "zend_objects_API.h"
#include "zend_globals.h"
-#define ZEND_INVOKE_FUNC_NAME "__invoke"
#define ZEND_CLOSURE_PRINT_NAME "Closure object"
#define ZEND_CLOSURE_PROPERTY_ERROR() \
- zend_error(E_ERROR, "Closure object cannot have properties")
+ zend_error(E_RECOVERABLE_ERROR, "Closure object cannot have properties")
typedef struct _zend_closure {
zend_object std;
zval *this_ptr;
} zend_closure;
-static zend_class_entry *zend_ce_closure;
+ZEND_API zend_class_entry *zend_ce_closure;
static zend_object_handlers closure_handlers;
ZEND_METHOD(Closure, __invoke) /* {{{ */
arguments = emalloc(sizeof(zval**) * ZEND_NUM_ARGS());
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
efree(arguments);
- zend_error(E_ERROR, "Cannot get arguments for calling closure");
+ zend_error(E_RECOVERABLE_ERROR, "Cannot get arguments for calling closure");
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;
static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{{ */
{
- zend_error(E_ERROR, "Instantiation of 'Closure' is not allowed");
+ zend_error(E_RECOVERABLE_ERROR, "Instantiation of 'Closure' is not allowed");
return NULL;
}
/* }}} */
static int zend_closure_serialize(zval *object, int *type, zstr *buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
{
- zend_error(E_ERROR, "Serialization of 'Closure' is not allowed");
+ zend_error(E_RECOVERABLE_ERROR, "Serialization of 'Closure' is not allowed");
return FAILURE;
}
/* }}} */
static int zend_closure_unserialize(zval **object, zend_class_entry *ce, int type, const zstr buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
{
- zend_error(E_ERROR, "Unserialization of 'Closure' is not allowed");
+ zend_error(E_RECOVERABLE_ERROR, "Unserialization of 'Closure' is not allowed");
return FAILURE;
}
/* }}} */
}
/* }}} */
+ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC) /* {{{ */
+{
+ zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
+ 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_PUBLIC | 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;
+ if (UG(unicode)) {
+ invoke->internal_function.function_name.u = USTR_MAKE(ZEND_INVOKE_FUNC_NAME);
+ } else {
+ invoke->internal_function.function_name.s = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
+ }
+ return invoke;
+}
+/* }}} */
+
static zend_function *zend_closure_get_method(zval **object_ptr, zstr method_name, int method_len TSRMLS_DC) /* {{{ */
{
unsigned int lc_name_len;
if ((lc_name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
(ZEND_U_EQUAL(type, lc_name, lc_name_len, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))
) {
- zend_closure *closure = (zend_closure *)zend_object_store_get_object(*object_ptr TSRMLS_CC);
- 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;
- if (UG(unicode)) {
- invoke->internal_function.function_name.u = USTR_MAKE(ZEND_INVOKE_FUNC_NAME);
- } else {
- invoke->internal_function.function_name.s = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
- }
efree(lc_name.v);
- return invoke;
+ return zend_get_closure_invoke_method(*object_ptr TSRMLS_CC);
}
efree(lc_name.v);
return NULL;