Skip to content

Commit

Permalink
feat(ze3/fcall): initial implementation of call_user_func functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
steffengy committed Dec 4, 2015
1 parent 1836ce4 commit 7bcf46f
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ public function optimize(array $expression, Call $call, CompilationContext $cont
if ($call->mustInitSymbolVariable()) {
$symbolVariable->initVariant($context);
}

$context->codePrinter->output('ZEPHIR_CALL_USER_FUNC_ARRAY(' . $symbolVariable->getName() . ', ' . $resolvedParams[0] . ', ' . $resolvedParams[1] . ');');

$symbol = $context->backend->getVariableCode($symbolVariable);
$context->codePrinter->output('ZEPHIR_CALL_USER_FUNC_ARRAY(' . $symbol . ', ' . $resolvedParams[0] . ', ' . $resolvedParams[1] . ');');
$call->addCallStatusOrJump($context);

return new CompiledExpression('variable', $symbolVariable->getName(), $expression);
Expand Down
5 changes: 3 additions & 2 deletions Library/Optimizers/FunctionCall/CallUserFuncOptimizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ public function optimize(array $expression, Call $call, CompilationContext $cont
if ($call->mustInitSymbolVariable()) {
$symbolVariable->initVariant($context);
}

$context->codePrinter->output('ZEPHIR_CALL_USER_FUNC(' . $symbolVariable->getName() . ', ' . $resolvedParams[0] . ');');

$symbol = $context->backend->getVariableCode($symbolVariable);
$context->codePrinter->output('ZEPHIR_CALL_USER_FUNC(' . $symbol . ', ' . $resolvedParams[0] . ');');
$call->addCallStatusOrJump($context);

return new CompiledExpression('variable', $symbolVariable->getName(), $expression);
Expand Down
42 changes: 42 additions & 0 deletions kernels/ZendEngine3/fcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,48 @@ int zephir_call_class_method_aparams(zval *return_value_ptr, zend_class_entry *c
return status;
}

/**
* Replaces call_user_func_array avoiding function lookup
* This function does not return FAILURE if an exception has ocurred
*/
int zephir_call_user_func_array_noex(zval *return_value, zval *handler, zval *params)
{
zend_fcall_info fci;
zend_fcall_info_cache fci_cache;
char *is_callable_error = NULL;
int status = FAILURE;

if (params && Z_TYPE_P(params) != IS_ARRAY) {
ZVAL_NULL(return_value);
php_error_docref(NULL, E_WARNING, "Invalid arguments supplied for zephir_call_user_func_array_noex()");
return FAILURE;
}

zend_fcall_info_init(handler, 0, &fci, &fci_cache, NULL, &is_callable_error);
if (is_callable_error) {
zend_error(E_WARNING, "%s", is_callable_error);
efree(is_callable_error);
} else {
status = SUCCESS;
}

if (status == SUCCESS) {
zend_fcall_info_args(&fci, params);

fci.retval = return_value;
zend_call_function(&fci, &fci_cache);

if (fci.params) {
efree(fci.params);
}
}

if (EG(exception)) {
status = SUCCESS;
}

return status;
}

/**
* If a retval_ptr is specified, PHP's implementation of zend_eval_stringl
Expand Down
24 changes: 24 additions & 0 deletions kernels/ZendEngine3/fcall.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,18 @@ typedef enum _zephir_call_type {
} \
} while (0)

/** Use these functions to call functions in the PHP userland using an arbitrary zval as callable */
#define ZEPHIR_CALL_USER_FUNC(return_value, handler) ZEPHIR_CALL_USER_FUNC_ARRAY(return_value, handler, NULL)
#define ZEPHIR_CALL_USER_FUNC_ARRAY(return_value, handler, params) \
do { \
ZEPHIR_LAST_CALL_STATUS = zephir_call_user_func_array(return_value, handler, params); \
} while (0)

#define ZEPHIR_CALL_USER_FUNC_ARRAY_NOEX(return_value, handler, params) \
do { \
ZEPHIR_LAST_CALL_STATUS = zephir_call_user_func_array_noex(return_value, handler, params); \
} while (0)

int zephir_call_func_aparams(zval *return_value_ptr, const char *func_name, uint func_length,
zephir_fcall_cache_entry **cache_entry, int cache_slot,
uint param_count, zval **params);
Expand Down Expand Up @@ -385,6 +397,18 @@ ZEPHIR_ATTR_WARN_UNUSED_RESULT static inline int zephir_return_call_class_method
return SUCCESS;
}

/** Fast call_user_func_array/call_user_func */
int zephir_call_user_func_array_noex(zval *return_value, zval *handler, zval *params) ZEPHIR_ATTR_WARN_UNUSED_RESULT;

/**
* Replaces call_user_func_array avoiding function lookup
*/
ZEPHIR_ATTR_WARN_UNUSED_RESULT static inline int zephir_call_user_func_array(zval *return_value, zval *handler, zval *params)
{
int status = zephir_call_user_func_array_noex(return_value, handler, params);
return (EG(exception)) ? FAILURE : status;
}

int zephir_has_constructor_ce(const zend_class_entry *ce) ZEPHIR_ATTR_PURE ZEPHIR_ATTR_NONNULL;

ZEPHIR_ATTR_WARN_UNUSED_RESULT ZEPHIR_ATTR_NONNULL static inline int zephir_has_constructor(const zval *object)
Expand Down

0 comments on commit 7bcf46f

Please sign in to comment.