From: Michael Wallner Date: Tue, 3 Oct 2006 08:15:44 +0000 (+0000) Subject: - use fci/fcc instead of zval* for user ob handler X-Git-Tag: RELEASE_1_0_0RC1~1463 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ea0f299bad5f44ef57b438ae5ca659916938cdd9;p=php - use fci/fcc instead of zval* for user ob handler --- diff --git a/main/output.c b/main/output.c index eb56752626..b1e909cf48 100644 --- a/main/output.c +++ b/main/output.c @@ -487,6 +487,7 @@ PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler, zval *handler_name = NULL; php_output_handler *handler = NULL; php_output_handler_alias_ctor_t *alias = NULL; + php_output_handler_user_func_t *user = NULL; switch (Z_TYPE_P(output_handler)) { case IS_NULL: @@ -499,14 +500,20 @@ PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler, break; } default: - MAKE_STD_ZVAL(handler_name); - ZVAL_NULL(handler_name); - if (zend_is_callable(output_handler, 0, handler_name)) { + user = emalloc(sizeof(php_output_handler_user_func_t)); + user->fci = empty_fcall_info; + user->fcc = empty_fcall_info_cache; + + if (SUCCESS == zend_fcall_info_init(output_handler, &user->fci, &user->fcc TSRMLS_CC)) { + /* FIXME: redundancy */ + MAKE_STD_ZVAL(handler_name); + zend_make_callable(output_handler, handler_name TSRMLS_CC); handler = php_output_handler_init(handler_name, chunk_size, (flags & ~0xf) | PHP_OUTPUT_HANDLER_USER); - ZVAL_ADDREF(output_handler); - handler->func.user = output_handler; + handler->func.user = user; + zval_ptr_dtor(&handler_name); + } else { + efree(user); } - zval_ptr_dtor(&handler_name); } return handler; @@ -647,7 +654,7 @@ PHPAPI int php_output_handler_reverse_conflict_register(zval *name, php_output_h } /* }}} */ -/* {{{ php_output_handler_context_func_t php_output_handler_alias(zval *name TSRMLS_DC) +/* {{{ php_output_handler_alias_ctor_t php_output_handler_alias(zval *name TSRMLS_DC) Get an internal output handler for a user handler if it exists */ PHPAPI php_output_handler_alias_ctor_t *php_output_handler_alias(zval *name TSRMLS_DC) { @@ -703,7 +710,7 @@ PHPAPI void php_output_handler_dtor(php_output_handler *handler TSRMLS_DC) zval_ptr_dtor(&handler->name); STR_FREE(handler->buffer.data); if (handler->flags & PHP_OUTPUT_HANDLER_USER) { - zval_ptr_dtor(&handler->func.user); + efree(handler->func.user); } if (handler->dtor && handler->opaq) { handler->dtor(handler->opaq TSRMLS_CC); @@ -931,18 +938,19 @@ static inline int php_output_handler_op(php_output_handler *handler, php_output_ OG(running) = handler; if (handler->flags & PHP_OUTPUT_HANDLER_USER) { - zval *retval = NULL, **params[2], *flags, *input; + zval *retval = NULL, *params[2]; - MAKE_STD_ZVAL(input); - /* can we avoid copying here by setting is_ref? */ - ZVAL_STRINGL(input, handler->buffer.data, handler->buffer.used, 1); - MAKE_STD_ZVAL(flags); - ZVAL_LONG(flags, (long) context->op); - params[0] = &input; - params[1] = &flags; + MAKE_STD_ZVAL(params[0]); + ZVAL_STRINGL(params[0], handler->buffer.data, handler->buffer.used, 1); + MAKE_STD_ZVAL(params[1]); + ZVAL_LONG(params[1], (long) context->op); + handler->func.user->fci.param_count = 2; + handler->func.user->fci.params = (zval***) safe_emalloc(handler->func.user->fci.param_count, sizeof(zval**), 0); + handler->func.user->fci.params[0] = ¶ms[0]; + handler->func.user->fci.params[1] = ¶ms[1]; - if ( (SUCCESS == call_user_function_ex(CG(function_table), NULL, handler->func.user, &retval, 2, params, 1, NULL TSRMLS_CC)) && - retval && (Z_TYPE_P(retval) != IS_NULL) && (Z_TYPE_P(retval) != IS_BOOL || Z_BVAL_P(retval))) { +#define PHP_OUTPUT_USER_SUCCESS(retval) (retval && (Z_TYPE_P(retval) != IS_NULL) && (Z_TYPE_P(retval) != IS_BOOL || Z_BVAL_P(retval))) + if (SUCCESS == zend_fcall_info_call(&handler->func.user->fci, &handler->func.user->fcc, &retval, NULL TSRMLS_CC) && PHP_OUTPUT_USER_SUCCESS(retval)) { /* user handler may have returned TRUE */ status = PHP_OUTPUT_HANDLER_NO_DATA; if (Z_TYPE_P(retval) != IS_BOOL) { @@ -958,11 +966,11 @@ static inline int php_output_handler_op(php_output_handler *handler, php_output_ /* call failed, pass internal buffer along */ status = PHP_OUTPUT_HANDLER_FAILURE; } + zend_fcall_info_args(&handler->func.user->fci, NULL TSRMLS_CC); if (retval) { zval_ptr_dtor(&retval); } - zval_ptr_dtor(&input); - zval_ptr_dtor(&flags); + } else { context->in.data = handler->buffer.data; diff --git a/main/php_output.h b/main/php_output.h index a4f5acc0ae..355b750bb0 100644 --- a/main/php_output.h +++ b/main/php_output.h @@ -111,6 +111,11 @@ typedef int (*php_output_handler_conflict_check_t)(zval *handler_name TSRMLS_DC) /* ctor for aliases */ typedef struct _php_output_handler *(*php_output_handler_alias_ctor_t)(zval *handler_name, size_t chunk_size, int flags TSRMLS_DC); +typedef struct _php_output_handler_user_func_t { + zend_fcall_info fci; + zend_fcall_info_cache fcc; +} php_output_handler_user_func_t; + typedef struct _php_output_handler { zval *name; int flags; @@ -122,7 +127,7 @@ typedef struct _php_output_handler { void (*dtor)(void *opaq TSRMLS_DC); union { - zval *user; + php_output_handler_user_func_t *user; php_output_handler_context_func_t internal; } func; } php_output_handler;