From b36aaea6ede499589b3298e204095c292d025c34 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 8 Jul 2014 02:13:53 +0400 Subject: [PATCH] ZEND_SEND_VAR and ZEND_SEND_VAL specialization --- Zend/zend_compile.c | 12 +- Zend/zend_vm_def.h | 37 ++++-- Zend/zend_vm_execute.h | 134 ++++++++++++-------- Zend/zend_vm_opcodes.c | 6 +- Zend/zend_vm_opcodes.h | 4 +- ext/opcache/Optimizer/optimize_func_calls.c | 20 ++- ext/opcache/Optimizer/zend_optimizer.c | 5 +- 7 files changed, 136 insertions(+), 82 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ea843483e5..6b40dbb35d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2672,8 +2672,15 @@ void zend_do_pass_param(znode *param, zend_uchar op TSRMLS_DC) /* {{{ */ opline->extended_value = send_function; } } else { - if (function_ptr) { - opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND; + if (!function_ptr) { + switch (op) { + case ZEND_SEND_VAL: + op = ZEND_SEND_VAL_EX; + break; + case ZEND_SEND_VAR: + op = ZEND_SEND_VAR_EX; + break; + } } } opline->opcode = op; @@ -5800,7 +5807,6 @@ void zend_do_shell_exec(znode *result, znode *cmd TSRMLS_DC) /* {{{ */ } SET_NODE(opline->op1, cmd); opline->op2.opline_num = 1; - opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND; SET_UNUSED(opline->op2); /* FIXME: exception support not added to this op2 */ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 12c4faf849..67fa0f7956 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2952,12 +2952,28 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) zend_free_op free_op1; SAVE_OPLINE(); - if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) { - if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); + value = GET_OP1_ZVAL_PTR(BP_VAR_R); + arg = ZEND_CALL_ARG(EX(call), opline->op2.num); + EX(call)->num_args = opline->op2.num; + ZVAL_COPY_VALUE(arg, value); + if (OP1_TYPE == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) { + zval_copy_ctor_func(arg); } } + ZEND_VM_NEXT_OPCODE(); +} +ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, ANY) +{ + USE_OPLINE + zval *value, *arg; + zend_free_op free_op1; + + SAVE_OPLINE(); + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); + } value = GET_OP1_ZVAL_PTR(BP_VAR_R); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; @@ -2970,7 +2986,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY) +ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY) { USE_OPLINE zval *varptr, *arg; @@ -3000,11 +3016,11 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) SAVE_OPLINE(); if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR); } } else { if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR); } } @@ -3075,18 +3091,15 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY) +ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY) { USE_OPLINE zval *varptr, *arg; zend_free_op free_op1; - if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) { - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF); - } + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF); } - varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cd40524370..52b1b794ab 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2610,12 +2610,28 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); - if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) { - if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); + value = opline->op1.zv; + arg = ZEND_CALL_ARG(EX(call), opline->op2.num); + EX(call)->num_args = opline->op2.num; + ZVAL_COPY_VALUE(arg, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) { + zval_copy_ctor_func(arg); } } + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + + SAVE_OPLINE(); + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); + } value = opline->op1.zv; arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; @@ -7802,12 +7818,28 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_free_op free_op1; SAVE_OPLINE(); - if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) { - if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + arg = ZEND_CALL_ARG(EX(call), opline->op2.num); + EX(call)->num_args = opline->op2.num; + ZVAL_COPY_VALUE(arg, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(arg))) { + zval_copy_ctor_func(arg); } } + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + zend_free_op free_op1; + SAVE_OPLINE(); + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); + } value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; @@ -12938,7 +12970,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) HANDLE_EXCEPTION(); } -static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *varptr, *arg; @@ -12968,11 +13000,11 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } } else { if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } } @@ -13043,18 +13075,15 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZEND_VM_NEXT_OPCODE(); } -static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *varptr, *arg; zend_free_op free_op1; - if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) { - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } - varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; @@ -30085,7 +30114,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) HANDLE_EXCEPTION(); } -static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *varptr, *arg; @@ -30115,11 +30144,11 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } } else { if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + return ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } } @@ -30189,18 +30218,15 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZEND_VM_NEXT_OPCODE(); } -static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *varptr, *arg; - if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND) { - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { - return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { + return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } - varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; @@ -41749,21 +41775,21 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, - ZEND_SEND_VAR_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, - ZEND_SEND_VAR_SPEC_CV_HANDLER, + ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, + ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, + ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, + ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, + ZEND_SEND_VAR_EX_SPEC_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -42989,6 +43015,16 @@ void zend_init_opcodes_handlers(void) ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER, + ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, + ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, + ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, + ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, + ZEND_SEND_VAL_EX_SPEC_CONST_HANDLER, + ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, + ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, + ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, + ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, + ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -43014,31 +43050,21 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_SEND_VAR_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_SPEC_VAR_HANDLER, + ZEND_SEND_VAR_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_SEND_VAR_SPEC_CV_HANDLER, + ZEND_SEND_VAR_SPEC_CV_HANDLER, + ZEND_SEND_VAR_SPEC_CV_HANDLER, + ZEND_SEND_VAR_SPEC_CV_HANDLER, + ZEND_SEND_VAR_SPEC_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 8859228aad..70d7e716bc 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -88,7 +88,7 @@ const char *zend_vm_opcodes_map[169] = { "ZEND_RECV", "ZEND_RECV_INIT", "ZEND_SEND_VAL", - "ZEND_SEND_VAR", + "ZEND_SEND_VAR_EX", "ZEND_SEND_REF", "ZEND_NEW", "ZEND_INIT_NS_FCALL_BY_NAME", @@ -138,8 +138,8 @@ const char *zend_vm_opcodes_map[169] = { "ZEND_INIT_STATIC_METHOD_CALL", "ZEND_ISSET_ISEMPTY_VAR", "ZEND_ISSET_ISEMPTY_DIM_OBJ", - NULL, - NULL, + "ZEND_SEND_VAL_EX", + "ZEND_SEND_VAR", NULL, NULL, NULL, diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 7d74a807b5..8aae4ae74c 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -89,7 +89,7 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode); #define ZEND_RECV 63 #define ZEND_RECV_INIT 64 #define ZEND_SEND_VAL 65 -#define ZEND_SEND_VAR 66 +#define ZEND_SEND_VAR_EX 66 #define ZEND_SEND_REF 67 #define ZEND_NEW 68 #define ZEND_INIT_NS_FCALL_BY_NAME 69 @@ -139,6 +139,8 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode); #define ZEND_INIT_STATIC_METHOD_CALL 113 #define ZEND_ISSET_ISEMPTY_VAR 114 #define ZEND_ISSET_ISEMPTY_DIM_OBJ 115 +#define ZEND_SEND_VAL_EX 116 +#define ZEND_SEND_VAR 117 #define ZEND_PRE_INC_OBJ 132 #define ZEND_PRE_DEC_OBJ 133 #define ZEND_POST_INC_OBJ 134 diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index 3f755bed18..65897425be 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -48,10 +48,12 @@ static void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx if (fcall->opcode == ZEND_INIT_FCALL_BY_NAME) { fcall->opcode = ZEND_INIT_FCALL; + Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]); literal_dtor(&ZEND_OP2_LITERAL(fcall)); fcall->op2.constant = fcall->op2.constant + 1; } else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) { fcall->opcode = ZEND_INIT_FCALL; + Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]); literal_dtor(&op_array->literals[fcall->op2.constant]); literal_dtor(&op_array->literals[fcall->op2.constant + 2]); fcall->op2.constant = fcall->op2.constant + 1; @@ -66,6 +68,7 @@ static void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx zend_op *fcall = call_stack[call].opline; fcall->opcode = ZEND_INIT_FCALL; + Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]); literal_dtor(&ZEND_OP2_LITERAL(fcall)); fcall->op2.constant = fcall->op2.constant + 1; } @@ -85,22 +88,23 @@ static void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx } } break; - case ZEND_SEND_VAL: - if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) && call_stack[call - 1].func) { + case ZEND_SEND_VAL_EX: + if (call_stack[call - 1].func) { if (ARG_MUST_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) { /* We won't convert it into_DO_FCALL to emit error at run-time */ call_stack[call - 1].opline = NULL; } else { - opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND; + opline->opcode = ZEND_SEND_VAL; } } break; - case ZEND_SEND_VAR: - if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) && call_stack[call - 1].func) { + case ZEND_SEND_VAR_EX: + if (call_stack[call - 1].func) { if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) { opline->opcode = ZEND_SEND_REF; + } else { + opline->opcode = ZEND_SEND_VAR; } - opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND; } break; case ZEND_SEND_VAR_NO_REF: @@ -111,16 +115,18 @@ static void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND; } else { opline->opcode = ZEND_SEND_VAR; - opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND; + opline->extended_value = 0; } } break; +#if 0 case ZEND_SEND_REF: if (opline->extended_value != ZEND_ARG_COMPILE_TIME_BOUND && call_stack[call - 1].func) { /* We won't handle run-time pass by reference */ call_stack[call - 1].opline = NULL; } break; +#endif #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO case ZEND_SEND_UNPACK: call_stack[call - 1].func = NULL; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 681a54a74e..3b6595485b 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -341,11 +341,12 @@ static int replace_var_by_const(zend_op_array *op_array, if (opline->extended_value & ZEND_ARG_SEND_BY_REF) { return 0; } - opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND; + opline->extended_value = 0; + opline->opcode = ZEND_SEND_VAL_EX; } else { opline->extended_value = 0; + opline->opcode = ZEND_SEND_VAL; } - opline->opcode = ZEND_SEND_VAL; break; default: break; -- 2.40.0