summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_compile.c12
-rw-r--r--Zend/zend_vm_def.h37
-rw-r--r--Zend/zend_vm_execute.h134
-rw-r--r--Zend/zend_vm_opcodes.c6
-rw-r--r--Zend/zend_vm_opcodes.h4
-rw-r--r--ext/opcache/Optimizer/optimize_func_calls.c20
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c5
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;