diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2016-04-07 17:34:53 +0300 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2016-04-07 17:34:53 +0300 |
| commit | 3444c1ae2400b279b936c4ca04cb84dfdfb57bbf (patch) | |
| tree | a63676497e4c163bb917a183780180e743a1acd2 /Zend | |
| parent | 708d030b694f89a001c5f5ed6e3af25e7097f483 (diff) | |
| download | php-git-3444c1ae2400b279b936c4ca04cb84dfdfb57bbf.tar.gz | |
Use return type hints for type inference and eliminate useless VERIFY_RETRUN_TYPE opcodes.
Diffstat (limited to 'Zend')
| -rw-r--r-- | Zend/zend_compile.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 5f3114d10e..da2c83c55e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2265,12 +2265,30 @@ static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */ static void zend_emit_return_type_check(znode *expr, zend_arg_info *return_info) /* {{{ */ { /* `return ...;` is illegal in a void function (but `return;` isn't) */ - if (expr && return_info->type_hint == IS_VOID) { - zend_error_noreturn(E_COMPILE_ERROR, "A void function must not return a value"); + if (return_info->type_hint == IS_VOID) { + if (expr) { + zend_error_noreturn(E_COMPILE_ERROR, "A void function must not return a value"); + } + /* we don't need run-time check */ + return; } if (return_info->type_hint != IS_UNDEF) { - zend_op *opline = zend_emit_op(NULL, ZEND_VERIFY_RETURN_TYPE, expr, NULL); + zend_op *opline; + + if (expr && expr->op_type == IS_CONST) { + if ((return_info->type_hint == Z_TYPE(expr->u.constant)) + ||((return_info->type_hint == _IS_BOOL) + && (Z_TYPE(expr->u.constant) == IS_FALSE + || Z_TYPE(expr->u.constant) == IS_TRUE)) + || (return_info->allow_null + && Z_TYPE(expr->u.constant) == IS_NULL)) { + /* we don't need run-time check */ + return; + } + } + + opline = zend_emit_op(NULL, ZEND_VERIFY_RETURN_TYPE, expr, NULL); if (expr && expr->op_type == IS_CONST) { opline->result_type = expr->op_type = IS_TMP_VAR; opline->result.var = expr->u.op.var = get_temporary_variable(CG(active_op_array)); |
