Skip to content

Commit ccf5c89

Browse files
committed
Fix more issues
1 parent f6f1010 commit ccf5c89

File tree

8 files changed

+73
-64
lines changed

8 files changed

+73
-64
lines changed

Zend/tests/arg_unpack/non_integer_keys.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ try {
1818

1919
?>
2020
--EXPECT--
21-
Exception: Cannot unpack Traversable with non-integer keys
21+
Exception: Keys must be of type int|string during argument unpacking

Zend/tests/arg_unpack/string_keys.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ try {
1515

1616
?>
1717
--EXPECT--
18-
string(42) "Cannot unpack Traversable with string keys"
18+
string(68) "Cannot use positional argument after named argument during unpacking"

Zend/zend_compile.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,6 +3297,7 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
32973297
opline = zend_emit_op(NULL, ZEND_CHECK_FUNC_ARG, NULL, NULL);
32983298
if (arg_name) {
32993299
opline->op2_type = IS_CONST;
3300+
zend_string_addref(arg_name);
33003301
opline->op2.constant = zend_add_literal_string(&arg_name);
33013302
opline->result.num = zend_alloc_cache_slots(2);
33023303
} else {
@@ -3344,6 +3345,7 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
33443345
opline = zend_emit_op(NULL, opcode, &arg_node, NULL);
33453346
if (arg_name) {
33463347
opline->op2_type = IS_CONST;
3348+
zend_string_addref(arg_name);
33473349
opline->op2.constant = zend_add_literal_string(&arg_name);
33483350
opline->result.num = zend_alloc_cache_slots(2);
33493351
} else {

Zend/zend_execute.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3732,7 +3732,10 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o
37323732
case ZEND_SEND_VAR_NO_REF_EX:
37333733
case ZEND_SEND_USER:
37343734
if (level == 0) {
3735-
ZEND_CALL_NUM_ARGS(call) = opline->op2.num;
3735+
/* For named args, the number of arguments is up to date. */
3736+
if (opline->op2_type != IS_CONST) {
3737+
ZEND_CALL_NUM_ARGS(call) = opline->op2.num;
3738+
}
37363739
do_exit = 1;
37373740
}
37383741
break;
@@ -3782,6 +3785,9 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o
37823785
if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
37833786
OBJ_RELEASE(Z_OBJ(call->This));
37843787
}
3788+
if (ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
3789+
zend_array_destroy(call->extra_named_params);
3790+
}
37853791
if (call->func->common.fn_flags & ZEND_ACC_CLOSURE) {
37863792
zend_object_release(ZEND_CLOSURE_OBJECT(call->func));
37873793
} else if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9323,7 +9323,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR, op->op2_type == IS_UNUSED && (op1_i
93239323
ZEND_VM_NEXT_OPCODE();
93249324
}
93259325

9326-
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR_EX, op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_EX_SIMPLE, CV|VAR, NUM)
9326+
ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_SEND_VAR_EX, op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0, ZEND_SEND_VAR_EX_SIMPLE, CV|VAR, UNUSED|NUM)
93279327
{
93289328
USE_OPLINE
93299329
zval *varptr, *arg;

Zend/zend_vm_execute.h

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -20950,28 +20950,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SP
2095020950
ZEND_VM_NEXT_OPCODE();
2095120951
}
2095220952

20953-
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
20954-
{
20955-
USE_OPLINE
20956-
zval *varptr, *arg;
20957-
uint32_t arg_num = opline->op2.num;
20958-
20959-
if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
20960-
ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
20961-
}
20962-
20963-
varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
20964-
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
20965-
20966-
if (IS_VAR == IS_CV) {
20967-
ZVAL_COPY(arg, varptr);
20968-
} else /* if (IS_VAR == IS_VAR) */ {
20969-
ZVAL_COPY_VALUE(arg, varptr);
20970-
}
20971-
20972-
ZEND_VM_NEXT_OPCODE();
20973-
}
20974-
2097520953
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
2097620954
{
2097720955
USE_OPLINE
@@ -27432,6 +27410,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDL
2743227410
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2743327411
}
2743427412

27413+
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
27414+
{
27415+
USE_OPLINE
27416+
zval *varptr, *arg;
27417+
uint32_t arg_num = opline->op2.num;
27418+
27419+
if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
27420+
ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
27421+
}
27422+
27423+
varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
27424+
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
27425+
27426+
if (IS_VAR == IS_CV) {
27427+
ZVAL_COPY(arg, varptr);
27428+
} else /* if (IS_VAR == IS_VAR) */ {
27429+
ZVAL_COPY_VALUE(arg, varptr);
27430+
}
27431+
27432+
ZEND_VM_NEXT_OPCODE();
27433+
}
27434+
2743527435
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
2743627436
{
2743727437
USE_OPLINE
@@ -37614,28 +37614,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_SIMPLE_SP
3761437614
ZEND_VM_NEXT_OPCODE();
3761537615
}
3761637616

37617-
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
37618-
{
37619-
USE_OPLINE
37620-
zval *varptr, *arg;
37621-
uint32_t arg_num = opline->op2.num;
37622-
37623-
if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
37624-
ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
37625-
}
37626-
37627-
varptr = EX_VAR(opline->op1.var);
37628-
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
37629-
37630-
if (IS_CV == IS_CV) {
37631-
ZVAL_COPY(arg, varptr);
37632-
} else /* if (IS_CV == IS_VAR) */ {
37633-
ZVAL_COPY_VALUE(arg, varptr);
37634-
}
37635-
37636-
ZEND_VM_NEXT_OPCODE();
37637-
}
37638-
3763937617
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
3764037618
{
3764137619
USE_OPLINE
@@ -46269,6 +46247,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLE
4626946247
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4627046248
}
4627146249

46250+
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
46251+
{
46252+
USE_OPLINE
46253+
zval *varptr, *arg;
46254+
uint32_t arg_num = opline->op2.num;
46255+
46256+
if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
46257+
ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
46258+
}
46259+
46260+
varptr = EX_VAR(opline->op1.var);
46261+
arg = ZEND_CALL_VAR(EX(call), opline->result.var);
46262+
46263+
if (IS_CV == IS_CV) {
46264+
ZVAL_COPY(arg, varptr);
46265+
} else /* if (IS_CV == IS_VAR) */ {
46266+
ZVAL_COPY_VALUE(arg, varptr);
46267+
}
46268+
46269+
ZEND_VM_NEXT_OPCODE();
46270+
}
46271+
4627246272
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
4627346273
{
4627446274
USE_OPLINE
@@ -52956,9 +52956,9 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5295652956
(void*)&&ZEND_SEND_VAR_SIMPLE_SPEC_CV_LABEL,
5295752957
(void*)&&ZEND_NULL_LABEL,
5295852958
(void*)&&ZEND_NULL_LABEL,
52959-
(void*)&&ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_LABEL,
52959+
(void*)&&ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_LABEL,
5296052960
(void*)&&ZEND_NULL_LABEL,
52961-
(void*)&&ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_LABEL,
52961+
(void*)&&ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_LABEL,
5296252962
(void*)&&ZEND_SEND_VAL_SIMPLE_SPEC_CONST_LABEL,
5296352963
(void*)&&ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST_LABEL,
5296452964
(void*)&&ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_LABEL,
@@ -55270,10 +55270,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5527055270
VM_TRACE(ZEND_SEND_VAR_SIMPLE_SPEC_VAR)
5527155271
ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
5527255272
HYBRID_BREAK();
55273-
HYBRID_CASE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR):
55274-
VM_TRACE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR)
55275-
ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
55276-
HYBRID_BREAK();
5527755273
HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_CONST):
5527855274
VM_TRACE(ZEND_IS_IDENTICAL_SPEC_VAR_CONST)
5527955275
ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -55698,6 +55694,10 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5569855694
VM_TRACE(ZEND_GET_TYPE_SPEC_VAR_UNUSED)
5569955695
ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
5570055696
HYBRID_BREAK();
55697+
HYBRID_CASE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED):
55698+
VM_TRACE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED)
55699+
ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
55700+
HYBRID_BREAK();
5570155701
HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV):
5570255702
VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV)
5570355703
ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -56435,10 +56435,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5643556435
VM_TRACE(ZEND_SEND_VAR_SIMPLE_SPEC_CV)
5643656436
ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
5643756437
HYBRID_BREAK();
56438-
HYBRID_CASE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV):
56439-
VM_TRACE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV)
56440-
ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
56441-
HYBRID_BREAK();
5644256438
HYBRID_CASE(ZEND_DIV_SPEC_CV_CONST):
5644356439
VM_TRACE(ZEND_DIV_SPEC_CV_CONST)
5644456440
ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -57055,6 +57051,10 @@ ZEND_API void execute_ex(zend_execute_data *ex)
5705557051
VM_TRACE(ZEND_GET_TYPE_SPEC_CV_UNUSED)
5705657052
ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
5705757053
HYBRID_BREAK();
57054+
HYBRID_CASE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED):
57055+
VM_TRACE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED)
57056+
ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
57057+
HYBRID_BREAK();
5705857058
HYBRID_CASE(ZEND_DIV_SPEC_CV_CV):
5705957059
VM_TRACE(ZEND_DIV_SPEC_CV_CV)
5706057060
ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -60724,9 +60724,9 @@ void zend_vm_init(void)
6072460724
ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER,
6072560725
ZEND_NULL_HANDLER,
6072660726
ZEND_NULL_HANDLER,
60727-
ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_HANDLER,
60727+
ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER,
6072860728
ZEND_NULL_HANDLER,
60729-
ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_HANDLER,
60729+
ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_HANDLER,
6073060730
ZEND_SEND_VAL_SIMPLE_SPEC_CONST_HANDLER,
6073160731
ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST_HANDLER,
6073260732
ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER,

Zend/zend_vm_handlers.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,8 +1796,8 @@
17961796
_(3367, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \
17971797
_(3370, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \
17981798
_(3372, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \
1799-
_(3375, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR) \
1800-
_(3377, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV) \
1799+
_(3375, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \
1800+
_(3377, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \
18011801
_(3378, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \
18021802
_(3379, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \
18031803
_(3380, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \

ext/opcache/Optimizer/optimize_func_calls.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,8 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
230230
case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
231231
case ZEND_FETCH_OBJ_FUNC_ARG:
232232
case ZEND_FETCH_DIM_FUNC_ARG:
233-
if (call_stack[call - 1].func) {
234-
ZEND_ASSERT(call_stack[call - 1].func_arg_num != (uint32_t)-1);
233+
if (call_stack[call - 1].func
234+
&& call_stack[call - 1].func_arg_num != (uint32_t)-1) {
235235
if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, call_stack[call - 1].func_arg_num)) {
236236
if (opline->opcode != ZEND_FETCH_STATIC_PROP_FUNC_ARG) {
237237
opline->opcode -= 9;
@@ -274,6 +274,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
274274
if (call_stack[call - 1].func) {
275275
if (opline->op2_type == IS_CONST) {
276276
call_stack[call - 1].try_inline = 0;
277+
call_stack[call - 1].func_arg_num = (uint32_t)-1;
277278
break;
278279
}
279280

0 commit comments

Comments
 (0)