summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-02-05 19:40:06 +0300
committerDmitry Stogov <dmitry@zend.com>2018-02-05 19:40:06 +0300
commit3a794d39f081f73b2204aed8b80163a197ab41c3 (patch)
tree90af4978f502d85b1a1ac1e1e72ebeaf9e65d6bc
parent7416562ab0c1062722c43c6b55d38e1a79f217cb (diff)
downloadphp-git-3a794d39f081f73b2204aed8b80163a197ab41c3.tar.gz
Avoid repeatable ARG_SHOULD_BE_SENT_BY_REF() checks in FETCH_*FUNC_ARG and following SEND_VAR_EX. Perform the check once in a new CHECK_FUNC_ARG opcode and reuse in the following FETCH_*FUNC_ARG and SEND_FUNC_ARG (SEND_VAR_EX replacement).
-rw-r--r--Zend/zend_compile.c23
-rw-r--r--Zend/zend_compile.h16
-rw-r--r--Zend/zend_execute.c2
-rw-r--r--Zend/zend_vm_def.h78
-rw-r--r--Zend/zend_vm_execute.h414
-rw-r--r--Zend/zend_vm_gen.php2
-rw-r--r--Zend/zend_vm_opcodes.c16
-rw-r--r--Zend/zend_vm_opcodes.h3
-rw-r--r--ext/opcache/Optimizer/optimize_func_calls.c16
-rw-r--r--ext/opcache/Optimizer/sccp.c1
-rw-r--r--ext/opcache/Optimizer/zend_call_graph.c1
-rw-r--r--ext/opcache/Optimizer/zend_dfg.c1
-rw-r--r--ext/opcache/Optimizer/zend_dump.c19
-rw-r--r--ext/opcache/Optimizer/zend_inference.c4
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c2
-rw-r--r--ext/opcache/Optimizer/zend_ssa.c1
16 files changed, 393 insertions, 206 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 0b4941e1f4..3d9b2e77c6 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1957,7 +1957,7 @@ static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */
{
zend_uchar factor = (opline->opcode == ZEND_FETCH_STATIC_PROP_R) ? 1 : 3;
- switch (type & BP_VAR_MASK) {
+ switch (type) {
case BP_VAR_R:
return;
case BP_VAR_W:
@@ -1971,7 +1971,6 @@ static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */
return;
case BP_VAR_FUNC_ARG:
opline->opcode += 4 * factor;
- opline->extended_value |= type >> BP_VAR_SHIFT;
return;
case BP_VAR_UNSET:
opline->opcode += 5 * factor;
@@ -3249,9 +3248,23 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
opcode = ZEND_SEND_VAR;
}
} else {
- zend_compile_var(&arg_node, arg,
- BP_VAR_FUNC_ARG | (arg_num << BP_VAR_SHIFT));
- opcode = ZEND_SEND_VAR_EX;
+ do {
+ if (arg->kind == ZEND_AST_VAR) {
+ CG(zend_lineno) = zend_ast_get_lineno(ast);
+ if (is_this_fetch(arg)) {
+ zend_emit_op(&arg_node, ZEND_FETCH_THIS, NULL, NULL);
+ opcode = ZEND_SEND_VAR_EX;
+ break;
+ } else if (zend_try_compile_cv(&arg_node, arg) == SUCCESS) {
+ opcode = ZEND_SEND_VAR_EX;
+ break;
+ }
+ }
+ opline = zend_emit_op(NULL, ZEND_CHECK_FUNC_ARG, NULL, NULL);
+ opline->op2.num = arg_num;
+ zend_compile_var(&arg_node, arg, BP_VAR_FUNC_ARG);
+ opcode = ZEND_SEND_FUNC_ARG;
+ } while (0);
}
} else {
zend_compile_expr(&arg_node, arg);
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index e26d6c7cc4..65a03e6b0e 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -481,6 +481,7 @@ struct _zend_execute_data {
#define ZEND_CALL_GENERATOR (1 << 8)
#define ZEND_CALL_DYNAMIC (1 << 9)
#define ZEND_CALL_FAKE_CLOSURE (1 << 10)
+#define ZEND_CALL_SEND_ARG_BY_REF (1 << 11)
#define ZEND_CALL_INFO_SHIFT 16
@@ -501,10 +502,18 @@ struct _zend_execute_data {
call_info |= ((flag) << ZEND_CALL_INFO_SHIFT); \
} while (0)
+#define ZEND_DEL_CALL_FLAG_EX(call_info, flag) do { \
+ call_info &= ~((flag) << ZEND_CALL_INFO_SHIFT); \
+ } while (0)
+
#define ZEND_ADD_CALL_FLAG(call, flag) do { \
ZEND_ADD_CALL_FLAG_EX(Z_TYPE_INFO((call)->This), flag); \
} while (0)
+#define ZEND_DEL_CALL_FLAG(call, flag) do { \
+ ZEND_DEL_CALL_FLAG_EX(Z_TYPE_INFO((call)->This), flag); \
+ } while (0)
+
#define ZEND_CALL_NUM_ARGS(call) \
(call)->This.u2.num_args
@@ -840,11 +849,6 @@ void zend_assert_valid_class_name(const zend_string *const_name);
#define BP_VAR_FUNC_ARG 4
#define BP_VAR_UNSET 5
-/* Bottom 3 bits are the type, top bits are arg num for BP_VAR_FUNC_ARG */
-#define BP_VAR_SHIFT 3
-#define BP_VAR_MASK 7
-
-
#define ZEND_INTERNAL_FUNCTION 1
#define ZEND_USER_FUNCTION 2
#define ZEND_OVERLOADED_FUNCTION 3
@@ -875,8 +879,6 @@ void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_ISSET 0x00000001
-#define ZEND_FETCH_ARG_MASK 0x0fffffff
-
#define ZEND_LAST_CATCH 0x00000001
#define ZEND_FREE_ON_RETURN (1<<0)
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 7714ecf852..9e4f0baf0a 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1228,6 +1228,7 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D)
break;
case ZEND_SEND_REF:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
msg = "Only variables can be passed by reference";
break;
case ZEND_FE_RESET_RW:
@@ -2491,6 +2492,7 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index fa450b1427..3f34100ba7 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1485,11 +1485,11 @@ ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW);
}
-ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ARG_NUM)
+ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value & ZEND_FETCH_ARG_MASK, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
} else {
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
@@ -1554,11 +1554,11 @@ ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, CONST|TMPVAR|CV, UNUSED|CLASS_FE
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW);
}
-ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, NUM)
+ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR)
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
} else {
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
@@ -1659,11 +1659,11 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, NUM)
+ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -1946,11 +1946,11 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM)
+ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -4362,6 +4362,68 @@ ZEND_VM_C_LABEL(send_var_by_ref):
ZEND_VM_NEXT_OPCODE();
}
+ZEND_VM_HOT_HANDLER(100, ZEND_CHECK_FUNC_ARG, UNUSED, NUM, SPEC(QUICK_ARG))
+{
+ USE_OPLINE
+ uint32_t arg_num = opline->op2.num;
+
+ if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
+ if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ } else {
+ ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ }
+ } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ } else {
+ ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ }
+ ZEND_VM_NEXT_OPCODE();
+}
+
+ZEND_VM_HOT_HANDLER(185, ZEND_SEND_FUNC_ARG, VAR, NUM)
+{
+ USE_OPLINE
+ zval *varptr, *arg;
+ zend_free_op free_op1;
+
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+ ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
+ }
+
+ varptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+ SAVE_OPLINE();
+ GET_OP1_UNDEF_CV(varptr, BP_VAR_R);
+ arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+ ZVAL_NULL(arg);
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ }
+
+ arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+ if (OP1_TYPE == IS_CV) {
+ ZVAL_OPT_DEREF(varptr);
+ ZVAL_COPY(arg, varptr);
+ } else /* if (OP1_TYPE == IS_VAR) */ {
+ if (UNEXPECTED(Z_ISREF_P(varptr))) {
+ zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+ varptr = Z_REFVAL_P(varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
+ if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+ efree_size(ref, sizeof(zend_reference));
+ } else if (Z_OPT_REFCOUNTED_P(arg)) {
+ Z_ADDREF_P(arg);
+ }
+ } else {
+ ZVAL_COPY_VALUE(arg, varptr);
+ }
+ }
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
{
USE_OPLINE
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 8e42c33365..cc67f61dff 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4683,7 +4683,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -4754,7 +4754,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -4977,7 +4977,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -6961,7 +6961,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -7186,7 +7186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -8217,7 +8217,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -8669,7 +8669,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUS
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value & ZEND_FETCH_ARG_MASK, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -8736,7 +8736,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CONST_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -8757,7 +8757,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -10100,7 +10100,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -10323,7 +10323,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -13795,7 +13795,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -16243,7 +16243,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -16604,7 +16604,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNU
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value & ZEND_FETCH_ARG_MASK, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -16673,7 +16673,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_TMPVAR_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -19058,7 +19058,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CO
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -19085,7 +19085,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CO
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -19495,7 +19495,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TM
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -19522,7 +19522,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TM
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -20069,7 +20069,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UN
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -20498,7 +20498,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -20525,7 +20525,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -21619,6 +21619,49 @@ send_var_by_ref:
ZEND_VM_NEXT_OPCODE();
}
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_FUNC_ARG_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval *varptr, *arg;
+ zend_free_op free_op1;
+
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
+ ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+ }
+
+ varptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) {
+ SAVE_OPLINE();
+ GET_OP1_UNDEF_CV(varptr, BP_VAR_R);
+ arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+ ZVAL_NULL(arg);
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ }
+
+ arg = ZEND_CALL_VAR(EX(call), opline->result.var);
+
+ if (IS_VAR == IS_CV) {
+ ZVAL_OPT_DEREF(varptr);
+ ZVAL_COPY(arg, varptr);
+ } else /* if (IS_VAR == IS_VAR) */ {
+ if (UNEXPECTED(Z_ISREF_P(varptr))) {
+ zend_refcounted *ref = Z_COUNTED_P(varptr);
+
+ varptr = Z_REFVAL_P(varptr);
+ ZVAL_COPY_VALUE(arg, varptr);
+ if (UNEXPECTED(GC_DELREF(ref) == 0)) {
+ efree_size(ref, sizeof(zend_reference));
+ } else if (Z_OPT_REFCOUNTED_P(arg)) {
+ Z_ADDREF_P(arg);
+ }
+ } else {
+ ZVAL_COPY_VALUE(arg, varptr);
+ }
+ }
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -23369,7 +23412,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CO
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -23458,7 +23501,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CO
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -25810,7 +25853,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TM
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -25899,7 +25942,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TM
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -28063,7 +28106,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UN
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -29665,7 +29708,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -29754,7 +29797,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -31540,6 +31583,44 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_
}
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ uint32_t arg_num = opline->op2.num;
+
+ if (EXPECTED(0)) {
+ if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ } else {
+ ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ }
+ } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ } else {
+ ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ }
+ ZEND_VM_NEXT_OPCODE();
+}
+
+static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ uint32_t arg_num = opline->op2.num;
+
+ if (EXPECTED(1)) {
+ if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ } else {
+ ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ }
+ } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
+ ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ } else {
+ ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
+ }
+ ZEND_VM_NEXT_OPCODE();
+}
+
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -32295,7 +32376,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -34165,7 +34246,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -36608,7 +36689,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -40897,7 +40978,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_CONST(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -41002,7 +41083,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CON
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -41287,7 +41368,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CON
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -44897,7 +44978,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -45184,7 +45265,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -47242,7 +47323,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_VAR(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -48026,7 +48107,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value & ZEND_FETCH_ARG_MASK, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_var_address_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -48093,7 +48174,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPE
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_W ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
} else {
ZEND_VM_TAIL_CALL(zend_fetch_static_prop_helper_SPEC_CV_UNUSED(BP_VAR_R ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
@@ -48148,7 +48229,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNU
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -50640,7 +50721,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
zend_throw_error(NULL, "Cannot use temporary expression in write context");
@@ -50925,7 +51006,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_
{
USE_OPLINE
- if (zend_is_by_ref_func_arg_fetch(opline->extended_value, EX(call)->func)) {
+ if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
/* Behave like FETCH_OBJ_W */
if ((IS_CV & (IS_CONST|IS_TMP_VAR))) {
SAVE_OPLINE();
@@ -54946,6 +55027,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
(void*)&&ZEND_NULL_LABEL,
(void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_LABEL,
(void*)&&ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_LABEL,
+ (void*)&&ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_LABEL,
+ (void*)&&ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_QUICK_LABEL,
(void*)&&ZEND_EXT_STMT_SPEC_LABEL,
(void*)&&ZEND_EXT_FCALL_BEGIN_SPEC_LABEL,
(void*)&&ZEND_EXT_FCALL_END_SPEC_LABEL,
@@ -55916,6 +55999,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
(void*)&&ZEND_BIND_LEXICAL_SPEC_TMP_CV_LABEL,
(void*)&&ZEND_BIND_STATIC_SPEC_CV_CONST_LABEL,
(void*)&&ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_LABEL,
+ (void*)&&ZEND_SEND_FUNC_ARG_SPEC_VAR_LABEL,
(void*)&&ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_LABEL,
(void*)&&ZEND_SWITCH_LONG_SPEC_CONST_CONST_LABEL,
(void*)&&ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_LABEL,
@@ -58477,6 +58561,9 @@ ZEND_API void execute_ex(zend_execute_data *ex)
HYBRID_CASE(ZEND_SEND_VAR_EX_SPEC_VAR_QUICK):
ZEND_SEND_VAR_EX_SPEC_VAR_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
+ HYBRID_CASE(ZEND_SEND_FUNC_ARG_SPEC_VAR):
+ ZEND_SEND_FUNC_ARG_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ HYBRID_BREAK();
HYBRID_CASE(ZEND_SEND_USER_SPEC_VAR):
ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
@@ -59239,6 +59326,12 @@ ZEND_API void execute_ex(zend_execute_data *ex)
HYBRID_CASE(ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED):
ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
+ HYBRID_CASE(ZEND_CHECK_FUNC_ARG_SPEC_UNUSED):
+ ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ HYBRID_BREAK();
+ HYBRID_CASE(ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_QUICK):
+ ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ HYBRID_BREAK();
HYBRID_CASE(ZEND_NEW_SPEC_UNUSED):
ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
HYBRID_BREAK();
@@ -62831,6 +62924,8 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER,
ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER,
+ ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_HANDLER,
+ ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_QUICK_HANDLER,
ZEND_EXT_STMT_SPEC_HANDLER,
ZEND_EXT_FCALL_BEGIN_SPEC_HANDLER,
ZEND_EXT_FCALL_END_SPEC_HANDLER,
@@ -63801,6 +63896,7 @@ void zend_init_opcodes_handlers(void)
ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDLER,
ZEND_BIND_STATIC_SPEC_CV_CONST_HANDLER,
ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_HANDLER,
+ ZEND_SEND_FUNC_ARG_SPEC_VAR_HANDLER,
ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_HANDLER,
ZEND_SWITCH_LONG_SPEC_CONST_CONST_HANDLER,
ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_HANDLER,
@@ -64865,106 +64961,106 @@ void zend_init_opcodes_handlers(void)
1957 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
1982 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2007,
- 3939,
- 2008,
- 2009,
+ 2008 | SPEC_RULE_QUICK_ARG,
2010,
2011,
2012,
2013,
2014,
- 2015 | SPEC_RULE_OP1,
- 2020 | SPEC_RULE_OP2,
- 2025 | SPEC_RULE_OP1,
- 2030 | SPEC_RULE_OP1,
- 2035 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2060 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2085 | SPEC_RULE_OP1,
- 2090 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2115 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG,
- 2125 | SPEC_RULE_OP1,
- 2130 | SPEC_RULE_OP2,
- 2135,
- 2136 | SPEC_RULE_OP1,
- 2141 | SPEC_RULE_OP1,
- 2146,
- 2147 | SPEC_RULE_OP1,
- 2152 | SPEC_RULE_OP1,
- 2157 | SPEC_RULE_OP1,
- 2162,
- 2163,
- 2164 | SPEC_RULE_OP2,
- 2169 | SPEC_RULE_RETVAL,
+ 2015,
+ 2016,
+ 2017 | SPEC_RULE_OP1,
+ 2022 | SPEC_RULE_OP2,
+ 2027 | SPEC_RULE_OP1,
+ 2032 | SPEC_RULE_OP1,
+ 2037 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2062 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2087 | SPEC_RULE_OP1,
+ 2092 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2117 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG,
+ 2127 | SPEC_RULE_OP1,
+ 2132 | SPEC_RULE_OP2,
+ 2137,
+ 2138 | SPEC_RULE_OP1,
+ 2143 | SPEC_RULE_OP1,
+ 2148,
+ 2149 | SPEC_RULE_OP1,
+ 2154 | SPEC_RULE_OP1,
+ 2159 | SPEC_RULE_OP1,
+ 2164,
+ 2165,
+ 2166 | SPEC_RULE_OP2,
2171 | SPEC_RULE_RETVAL,
2173 | SPEC_RULE_RETVAL,
- 2175 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2200 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2225 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2250 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2275 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA,
- 2400,
- 2401 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2426,
- 2427,
+ 2175 | SPEC_RULE_RETVAL,
+ 2177 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2202 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2227 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2252 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2277 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA,
+ 2402,
+ 2403 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2428,
- 2429 | SPEC_RULE_OP1,
- 2434,
- 2435,
+ 2429,
+ 2430,
+ 2431 | SPEC_RULE_OP1,
2436,
2437,
- 2438 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA,
- 2563 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2588,
- 2589,
+ 2438,
+ 2439,
+ 2440 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_OP_DATA,
+ 2565 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
2590,
- 2591 | SPEC_RULE_OP1,
- 2596,
- 2597,
+ 2591,
+ 2592,
+ 2593 | SPEC_RULE_OP1,
2598,
2599,
2600,
2601,
2602,
- 2603 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2628 | SPEC_RULE_OP1,
- 2633,
- 2634,
+ 2603,
+ 2604,
+ 2605 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2630 | SPEC_RULE_OP1,
2635,
2636,
- 2637 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2662 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_DIM_OBJ,
- 2737,
- 2738 | SPEC_RULE_OP1,
- 2743 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2768,
- 2769,
- 2770 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2795 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2820 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2845 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2870 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2895 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2920 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2945 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 2970 | SPEC_RULE_OP1,
- 2975,
- 2976,
+ 2637,
+ 2638,
+ 2639 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2664 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_DIM_OBJ,
+ 2739,
+ 2740 | SPEC_RULE_OP1,
+ 2745 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2770,
+ 2771,
+ 2772 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2797 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2822 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2847 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2872 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2897 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2922 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2947 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 2972 | SPEC_RULE_OP1,
2977,
- 3939,
2978,
- 2979 | SPEC_RULE_OP1,
- 2984 | SPEC_RULE_OP1,
- 2989 | SPEC_RULE_OP1,
- 2994 | SPEC_RULE_OP1,
- 2999 | SPEC_RULE_OP1,
- 3004,
- 3005 | SPEC_RULE_OP1,
- 3010,
- 3011 | SPEC_RULE_OP1,
- 3016,
- 3017,
- 3018 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
- 3939
+ 2979,
+ 2980,
+ 2981,
+ 2982 | SPEC_RULE_OP1,
+ 2987 | SPEC_RULE_OP1,
+ 2992 | SPEC_RULE_OP1,
+ 2997 | SPEC_RULE_OP1,
+ 3002 | SPEC_RULE_OP1,
+ 3007,
+ 3008 | SPEC_RULE_OP1,
+ 3013,
+ 3014 | SPEC_RULE_OP1,
+ 3019,
+ 3020,
+ 3021 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
+ 3942
};
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
zend_opcode_handler_funcs = labels;
@@ -65152,7 +65248,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3044 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+ spec = 3047 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
if (op->op1_type < op->op2_type) {
zend_swap_operands(op);
}
@@ -65160,7 +65256,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3069 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+ spec = 3072 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
if (op->op1_type < op->op2_type) {
zend_swap_operands(op);
}
@@ -65168,7 +65264,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3094 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+ spec = 3097 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
if (op->op1_type < op->op2_type) {
zend_swap_operands(op);
}
@@ -65179,17 +65275,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3119 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+ spec = 3122 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3144 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+ spec = 3147 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3169 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+ spec = 3172 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
}
break;
case ZEND_MUL:
@@ -65200,17 +65296,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3194 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+ spec = 3197 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3219 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+ spec = 3222 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3244 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
+ spec = 3247 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
}
break;
case ZEND_IS_EQUAL:
@@ -65221,12 +65317,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3269 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+ spec = 3272 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3344 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+ spec = 3347 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
}
break;
case ZEND_IS_NOT_EQUAL:
@@ -65237,12 +65333,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3419 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+ spec = 3422 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3494 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
+ spec = 3497 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
}
break;
case ZEND_IS_SMALLER:
@@ -65250,12 +65346,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3569 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+ spec = 3572 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3644 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+ spec = 3647 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
}
break;
case ZEND_IS_SMALLER_OR_EQUAL:
@@ -65263,80 +65359,80 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3719 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+ spec = 3722 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
break;
}
- spec = 3794 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
+ spec = 3797 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
}
break;
case ZEND_QM_ASSIGN:
if (op1_info == MAY_BE_DOUBLE) {
- spec = 3887 | SPEC_RULE_OP1;
+ spec = 3890 | SPEC_RULE_OP1;
} else if (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)))) {
- spec = 3892 | SPEC_RULE_OP1;
+ spec = 3895 | SPEC_RULE_OP1;
}
break;
case ZEND_PRE_INC:
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
- spec = 3869 | SPEC_RULE_RETVAL;
+ spec = 3872 | SPEC_RULE_RETVAL;
} else if (op1_info == MAY_BE_LONG) {
- spec = 3871 | SPEC_RULE_RETVAL;
+ spec = 3874 | SPEC_RULE_RETVAL;
} else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) {
- spec = 3873 | SPEC_RULE_RETVAL;
+ spec = 3876 | SPEC_RULE_RETVAL;
}
break;
case ZEND_PRE_DEC:
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
- spec = 3875 | SPEC_RULE_RETVAL;
+ spec = 3878 | SPEC_RULE_RETVAL;
} else if (op1_info == MAY_BE_LONG) {
- spec = 3877 | SPEC_RULE_RETVAL;
+ spec = 3880 | SPEC_RULE_RETVAL;
} else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) {
- spec = 3879 | SPEC_RULE_RETVAL;
+ spec = 3882 | SPEC_RULE_RETVAL;
}
break;
case ZEND_POST_INC:
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
- spec = 3881;
+ spec = 3884;
} else if (op1_info == MAY_BE_LONG) {
- spec = 3882;
+ spec = 3885;
} else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) {
- spec = 3883;
+ spec = 3886;
}
break;
case ZEND_POST_DEC:
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
- spec = 3884;
+ spec = 3887;
} else if (op1_info == MAY_BE_LONG) {
- spec = 3885;
+ spec = 3888;
} else if (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)) {
- spec = 3886;
+ spec = 3889;
}
break;
case ZEND_JMP:
if (OP_JMP_ADDR(op, op->op1) > op) {
- spec = 3043;
+ spec = 3046;
}
break;
case ZEND_SEND_VAR_EX:
if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
- spec = 3927 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG;
+ spec = 3930 | SPEC_RULE_OP1 | SPEC_RULE_QUICK_ARG;
}
break;
case ZEND_FE_FETCH_R:
if (op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) {
- spec = 3937 | SPEC_RULE_RETVAL;
+ spec = 3940 | SPEC_RULE_RETVAL;
}
break;
case ZEND_FETCH_DIM_R:
if (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
- spec = 3897 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+ spec = 3900 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
}
break;
case ZEND_SEND_VAR:
if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
- spec = 3922 | SPEC_RULE_OP1;
+ spec = 3925 | SPEC_RULE_OP1;
}
break;
case ZEND_BW_OR:
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index 2c392b8760..d95a439c7e 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -73,7 +73,6 @@ $vm_op_flags = array(
"ZEND_VM_EXT_VAR_FETCH" => 1<<16,
"ZEND_VM_EXT_ISSET" => 1<<17,
- "ZEND_VM_EXT_ARG_NUM" => 1<<18,
"ZEND_VM_EXT_ARRAY_INIT" => 1<<19,
"ZEND_VM_EXT_REF" => 1<<20,
"ZEND_VM_EXT_MASK" => 0x0f000000,
@@ -128,7 +127,6 @@ $vm_ext_decode = array(
"EVAL" => ZEND_VM_EXT_EVAL,
"TYPE_MASK" => ZEND_VM_EXT_TYPE_MASK,
"ISSET" => ZEND_VM_EXT_ISSET,
- "ARG_NUM" => ZEND_VM_EXT_ARG_NUM,
"REF" => ZEND_VM_EXT_REF,
"SRC" => ZEND_VM_EXT_SRC,
);
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index b01d7395d3..7be1db0052 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -122,7 +122,7 @@ static const char *zend_vm_opcodes_names[199] = {
"ZEND_FETCH_OBJ_UNSET",
"ZEND_FETCH_LIST_R",
"ZEND_FETCH_CONSTANT",
- NULL,
+ "ZEND_CHECK_FUNC_ARG",
"ZEND_EXT_STMT",
"ZEND_EXT_FCALL_BEGIN",
"ZEND_EXT_FCALL_END",
@@ -207,7 +207,7 @@ static const char *zend_vm_opcodes_names[199] = {
"ZEND_BIND_LEXICAL",
"ZEND_BIND_STATIC",
"ZEND_FETCH_THIS",
- NULL,
+ "ZEND_SEND_FUNC_ARG",
"ZEND_ISSET_ISEMPTY_THIS",
"ZEND_SWITCH_LONG",
"ZEND_SWITCH_STRING",
@@ -316,15 +316,15 @@ static uint32_t zend_vm_opcodes_flags[199] = {
0x00010107,
0x00000707,
0x00000757,
- 0x00050107,
- 0x01006703,
- 0x01000753,
+ 0x00010107,
+ 0x00006703,
+ 0x00000753,
0x00010107,
0x00000701,
0x00000751,
0x0000070b,
0x00000391,
- 0x00000000,
+ 0x00001001,
0x00000000,
0x00000000,
0x00000000,
@@ -401,7 +401,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
0x00007307,
0x00007307,
0x00007307,
- 0x01007307,
+ 0x00007307,
0x00007307,
0x00007307,
0x00027307,
@@ -409,7 +409,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
0x00100101,
0x00100301,
0x00000101,
- 0x00000000,
+ 0x00001001,
0x00000101,
0x0300030b,
0x0300030b,
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index fc0cba498f..d652c292ce 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -50,7 +50,6 @@
#define ZEND_VM_OP_CONST_FETCH 0x00000090
#define ZEND_VM_EXT_VAR_FETCH 0x00010000
#define ZEND_VM_EXT_ISSET 0x00020000
-#define ZEND_VM_EXT_ARG_NUM 0x00040000
#define ZEND_VM_EXT_ARRAY_INIT 0x00080000
#define ZEND_VM_EXT_REF 0x00100000
#define ZEND_VM_EXT_MASK 0x0f000000
@@ -174,6 +173,7 @@ END_EXTERN_C()
#define ZEND_FETCH_OBJ_UNSET 97
#define ZEND_FETCH_LIST_R 98
#define ZEND_FETCH_CONSTANT 99
+#define ZEND_CHECK_FUNC_ARG 100
#define ZEND_EXT_STMT 101
#define ZEND_EXT_FCALL_BEGIN 102
#define ZEND_EXT_FCALL_END 103
@@ -258,6 +258,7 @@ END_EXTERN_C()
#define ZEND_BIND_LEXICAL 182
#define ZEND_BIND_STATIC 183
#define ZEND_FETCH_THIS 184
+#define ZEND_SEND_FUNC_ARG 185
#define ZEND_ISSET_ISEMPTY_THIS 186
#define ZEND_SWITCH_LONG 187
#define ZEND_SWITCH_STRING 188
diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c
index 2696a64879..32de6ba35c 100644
--- a/ext/opcache/Optimizer/optimize_func_calls.c
+++ b/ext/opcache/Optimizer/optimize_func_calls.c
@@ -40,6 +40,7 @@ typedef struct _optimizer_call_info {
zend_function *func;
zend_op *opline;
zend_bool try_inline;
+ uint32_t func_arg_num;
} optimizer_call_info;
static void zend_delete_call_instructions(zend_op *opline)
@@ -176,6 +177,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_USER_CALL:
call_stack[call].opline = opline;
+ call_stack[call].func_arg_num = (uint32_t)-1;
call++;
break;
case ZEND_DO_FCALL:
@@ -219,14 +221,15 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
call_stack[call].func = NULL;
call_stack[call].opline = NULL;
call_stack[call].try_inline = 0;
+ call_stack[call].func_arg_num = (uint32_t)-1;
break;
case ZEND_FETCH_FUNC_ARG:
case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
case ZEND_FETCH_OBJ_FUNC_ARG:
case ZEND_FETCH_DIM_FUNC_ARG:
if (call_stack[call - 1].func) {
- if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- opline->extended_value &= ZEND_FETCH_TYPE_MASK;
+ ZEND_ASSERT(call_stack[call - 1].func_arg_num != (uint32_t)-1);
+ if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, call_stack[call - 1].func_arg_num)) {
if (opline->opcode != ZEND_FETCH_STATIC_PROP_FUNC_ARG) {
opline->opcode -= 9;
} else {
@@ -241,7 +244,6 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
break;
}
- opline->extended_value &= ZEND_FETCH_TYPE_MASK;
if (opline->opcode != ZEND_FETCH_STATIC_PROP_FUNC_ARG) {
opline->opcode -= 12;
} else {
@@ -260,8 +262,16 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
}
}
break;
+ case ZEND_CHECK_FUNC_ARG:
+ if (call_stack[call - 1].func) {
+ call_stack[call - 1].func_arg_num = opline->op2.num;
+ MAKE_NOP(opline);
+ }
+ break;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
if (call_stack[call - 1].func) {
+ call_stack[call - 1].func_arg_num = (uint32_t)-1;
if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
opline->opcode = ZEND_SEND_REF;
} else {
diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c
index bf6d57f030..1b2623c307 100644
--- a/ext/opcache/Optimizer/sccp.c
+++ b/ext/opcache/Optimizer/sccp.c
@@ -228,6 +228,7 @@ static zend_bool can_replace_op1(
case ZEND_UNSET_OBJ:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_UNPACK:
case ZEND_SEND_ARRAY:
case ZEND_SEND_USER:
diff --git a/ext/opcache/Optimizer/zend_call_graph.c b/ext/opcache/Optimizer/zend_call_graph.c
index 886a793971..a23e9ead63 100644
--- a/ext/opcache/Optimizer/zend_call_graph.c
+++ b/ext/opcache/Optimizer/zend_call_graph.c
@@ -152,6 +152,7 @@ int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_f
case ZEND_SEND_VAR:
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
diff --git a/ext/opcache/Optimizer/zend_dfg.c b/ext/opcache/Optimizer/zend_dfg.c
index d750c136a2..224ea56167 100644
--- a/ext/opcache/Optimizer/zend_dfg.c
+++ b/ext/opcache/Optimizer/zend_dfg.c
@@ -95,6 +95,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
case ZEND_BIND_GLOBAL:
case ZEND_BIND_STATIC:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c
index 0724dd52e2..22e149ae55 100644
--- a/ext/opcache/Optimizer/zend_dump.c
+++ b/ext/opcache/Optimizer/zend_dump.c
@@ -563,16 +563,12 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
}
} else {
if (ZEND_VM_EXT_VAR_FETCH & flags) {
- switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
- case ZEND_FETCH_GLOBAL:
- fprintf(stderr, " (global)");
- break;
- case ZEND_FETCH_LOCAL:
- fprintf(stderr, " (local)");
- break;
- case ZEND_FETCH_GLOBAL_LOCK:
- fprintf(stderr, " (global+lock)");
- break;
+ if (opline->extended_value & ZEND_FETCH_GLOBAL) {
+ fprintf(stderr, " (global)");
+ } else if (opline->extended_value & ZEND_FETCH_LOCAL) {
+ fprintf(stderr, " (local)");
+ } else if (opline->extended_value & ZEND_FETCH_GLOBAL_LOCK) {
+ fprintf(stderr, " (global+lock)");
}
}
if (ZEND_VM_EXT_ISSET & flags) {
@@ -582,9 +578,6 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
fprintf(stderr, " (empty)");
}
}
- if (ZEND_VM_EXT_ARG_NUM & flags) {
- fprintf(stderr, " %u", opline->extended_value & ZEND_FETCH_ARG_MASK);
- }
if (ZEND_VM_EXT_ARRAY_INIT & flags) {
fprintf(stderr, " %u", opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT);
if (!(opline->extended_value & ZEND_ARRAY_NOT_PACKED)) {
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c
index fef99bc053..26ef8b82a9 100644
--- a/ext/opcache/Optimizer/zend_inference.c
+++ b/ext/opcache/Optimizer/zend_inference.c
@@ -2721,6 +2721,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
}
break;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
if (ssa_ops[i].op1_def >= 0) {
tmp = (t1 & MAY_BE_UNDEF)|MAY_BE_REF|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
@@ -3093,6 +3094,7 @@ static int zend_update_type_info(const zend_op_array *op_array,
tmp |= MAY_BE_ARRAY_OF_OBJECT;
break;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_SEND_REF:
@@ -4042,6 +4044,7 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_SEND_REF:
@@ -4091,6 +4094,7 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa
case ZEND_SEND_VAL:
case ZEND_SEND_REF:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_FREE:
case ZEND_SEPARATE:
case ZEND_TYPE_CHECK:
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index a7d463030f..f9b21ff19e 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -265,6 +265,7 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
zval_ptr_dtor_nogc(val);
return 1;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_FETCH_DIM_W:
case ZEND_FETCH_DIM_RW:
case ZEND_FETCH_DIM_FUNC_ARG:
@@ -593,6 +594,7 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
opline->opcode = ZEND_SEND_VAL;
break;
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
opline->extended_value = 0;
opline->opcode = ZEND_SEND_VAL_EX;
break;
diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c
index 45e6721216..a18f4a875c 100644
--- a/ext/opcache/Optimizer/zend_ssa.c
+++ b/ext/opcache/Optimizer/zend_ssa.c
@@ -680,6 +680,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_SEND_VAR_EX:
+ case ZEND_SEND_FUNC_ARG:
case ZEND_SEND_REF:
case ZEND_SEND_UNPACK:
case ZEND_FE_RESET_RW: