From c081ce628f0d76d44784d7bb8e06428b06142ac0 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 3 Jan 2014 11:08:10 +0800 Subject: Bump year --- Zend/zend_compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_compile.c') diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a0ea594560..3f43b091db 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | -- cgit v1.2.1 From c7bb28333804403c1e7cd817386ea1d527ad25e6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 28 Aug 2013 20:12:54 +0200 Subject: Minor cleanup in zend_do_pass_param() --- Zend/zend_compile.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'Zend/zend_compile.c') diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 3f43b091db..9b12810b0a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2582,9 +2582,9 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{{ */ { zend_op *opline; - int original_op=op; + int original_op = op; zend_function **function_ptr_ptr, *function_ptr; - int send_by_reference; + int send_by_reference = 0; int send_function = 0; zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr); @@ -2607,22 +2607,19 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{ if (function_ptr) { if (ARG_MAY_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) { - if (param->op_type & (IS_VAR|IS_CV) && original_op != ZEND_SEND_VAL) { - send_by_reference = 1; - if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) { + if (op == ZEND_SEND_VAR && param->op_type & (IS_VAR|IS_CV)) { + send_by_reference = ZEND_ARG_SEND_BY_REF; + if (zend_is_function_or_method_call(param)) { /* Method call */ op = ZEND_SEND_VAR_NO_REF; send_function = ZEND_ARG_SEND_FUNCTION | ZEND_ARG_SEND_SILENT; } } else { op = ZEND_SEND_VAL; - send_by_reference = 0; } - } else { - send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0; + } else if (ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) { + send_by_reference = ZEND_ARG_SEND_BY_REF; } - } else { - send_by_reference = 0; } if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) { -- cgit v1.2.1 From 2c47dfbaebb203ab547f3c7e786cb1db5e84674a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 29 Aug 2013 11:35:11 +0200 Subject: Implement argument unpacking RFC: https://wiki.php.net/rfc/argument_unpacking --- Zend/zend_compile.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'Zend/zend_compile.c') diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9b12810b0a..f789e3397f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2549,8 +2549,11 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode } opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)]; } else { + zend_function **function_ptr_ptr; + zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr); + opline = get_next_op(CG(active_op_array) TSRMLS_CC); - if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) { + if (*function_ptr_ptr) { opline->opcode = ZEND_DO_FCALL; SET_NODE(opline->op1, function_name); SET_UNUSED(opline->op2); @@ -2562,6 +2565,13 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); opline->op2.num = --CG(context).nested_calls; + + /* This would normally be a ZEND_DO_FCALL, but was forced to use + * ZEND_DO_FCALL_BY_NAME due to a ... argument. In this case we need to + * free the function_name */ + if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) { + zval_dtor(&function_name->u.constant); + } } } @@ -2687,6 +2697,39 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{ } /* }}} */ +void zend_do_unpack_params(znode *params, int offset TSRMLS_DC) /* {{{ */ +{ + zend_op *opline; + zend_function **function_ptr_ptr; + + zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr); + if (*function_ptr_ptr) { + /* If argument unpacking is used argument numbers and sending modes can no longer be + * computed at compile time, thus we need access to EX(call). In order to have it we + * retroactively emit a ZEND_INIT_FCALL_BY_NAME opcode. */ + zval func_name; + ZVAL_STRING(&func_name, (*function_ptr_ptr)->common.function_name, 1); + + opline = get_next_op(CG(active_op_array) TSRMLS_CC); + opline->opcode = ZEND_INIT_FCALL_BY_NAME; + opline->result.num = CG(context).nested_calls; + SET_UNUSED(opline->op1); + opline->op2_type = IS_CONST; + opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &func_name TSRMLS_CC); + GET_CACHE_SLOT(opline->op2.constant); + + ++CG(context).nested_calls; + *function_ptr_ptr = NULL; + } + + opline = get_next_op(CG(active_op_array) TSRMLS_CC); + opline->opcode = ZEND_SEND_UNPACK; + SET_NODE(opline->op1, params); + SET_UNUSED(opline->op2); + opline->op2.num = (zend_uint) offset; +} +/* }}} */ + static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRMLS_DC) /* {{{ */ { zend_op *opline; -- cgit v1.2.1