Skip to content

Commit f6f1010

Browse files
committed
Fix some opcache issues
Support is definitely incomplete.
1 parent 0e96505 commit f6f1010

File tree

8 files changed

+52
-4
lines changed

8 files changed

+52
-4
lines changed

Zend/tests/named_params/missing_param.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
Require parameter not passed
2+
Required parameter not passed
33
--FILE--
44
<?php
55

Zend/tests/named_params/unpack.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ array(1) {
7070
}
7171
a = a, b = b, c = c
7272
a = a, b = b, c = c
73+
a = a, b = b, c = c
7374
Cannot use positional argument after named argument during unpacking
7475
Named parameter $a overwrites previous argument
7576

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5289,7 +5289,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_RECV, op->op2.num == MAY_BE_ANY, ZEND_RECV_NO
52895289
USE_OPLINE
52905290
uint32_t arg_num = opline->op1.num;
52915291

5292-
if (UNEXPECTED(arg_num > EX_NUM_ARGS())) {
5292+
if (UNEXPECTED(arg_num > EX_NUM_ARGS()) || Z_ISUNDEF_P(EX_VAR(opline->result.var))) {
52935293
ZEND_VM_DISPATCH_TO_HELPER(zend_missing_arg_helper, arg_num, arg_num);
52945294
}
52955295

Zend/zend_vm_execute.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2188,7 +2188,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_NOTYPE_SPEC_H
21882188
USE_OPLINE
21892189
uint32_t arg_num = opline->op1.num;
21902190

2191-
if (UNEXPECTED(arg_num > EX_NUM_ARGS())) {
2191+
if (UNEXPECTED(arg_num > EX_NUM_ARGS()) || Z_ISUNDEF_P(EX_VAR(opline->result.var))) {
21922192
ZEND_VM_TAIL_CALL(zend_missing_arg_helper_SPEC(arg_num ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
21932193
}
21942194

ext/opcache/Optimizer/compact_literals.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,20 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
779779
opline->extended_value = cache_size;
780780
cache_size += sizeof(void *);
781781
break;
782+
case ZEND_SEND_VAL:
783+
case ZEND_SEND_VAL_EX:
784+
case ZEND_SEND_VAR:
785+
case ZEND_SEND_VAR_EX:
786+
case ZEND_SEND_VAR_NO_REF:
787+
case ZEND_SEND_VAR_NO_REF_EX:
788+
case ZEND_SEND_REF:
789+
case ZEND_SEND_FUNC_ARG:
790+
case ZEND_CHECK_FUNC_ARG:
791+
if (opline->op2_type == IS_CONST) {
792+
opline->result.num = cache_size;
793+
cache_size += 2 * sizeof(void *);
794+
}
795+
break;
782796
}
783797
opline++;
784798
}

ext/opcache/Optimizer/optimize_func_calls.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
257257
break;
258258
case ZEND_SEND_VAL_EX:
259259
if (call_stack[call - 1].func) {
260+
if (opline->op2_type == IS_CONST) {
261+
call_stack[call - 1].try_inline = 0;
262+
break;
263+
}
264+
260265
if (ARG_MUST_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
261266
/* We won't convert it into_DO_FCALL to emit error at run-time */
262267
call_stack[call - 1].opline = NULL;
@@ -267,13 +272,23 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
267272
break;
268273
case ZEND_CHECK_FUNC_ARG:
269274
if (call_stack[call - 1].func) {
275+
if (opline->op2_type == IS_CONST) {
276+
call_stack[call - 1].try_inline = 0;
277+
break;
278+
}
279+
270280
call_stack[call - 1].func_arg_num = opline->op2.num;
271281
MAKE_NOP(opline);
272282
}
273283
break;
274284
case ZEND_SEND_VAR_EX:
275285
case ZEND_SEND_FUNC_ARG:
276286
if (call_stack[call - 1].func) {
287+
if (opline->op2_type == IS_CONST) {
288+
call_stack[call - 1].try_inline = 0;
289+
break;
290+
}
291+
277292
call_stack[call - 1].func_arg_num = (uint32_t)-1;
278293
if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
279294
opline->opcode = ZEND_SEND_REF;
@@ -284,6 +299,11 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
284299
break;
285300
case ZEND_SEND_VAR_NO_REF_EX:
286301
if (call_stack[call - 1].func) {
302+
if (opline->op2_type == IS_CONST) {
303+
call_stack[call - 1].try_inline = 0;
304+
break;
305+
}
306+
287307
if (ARG_MUST_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
288308
opline->opcode = ZEND_SEND_VAR_NO_REF;
289309
} else if (ARG_MAY_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
@@ -293,6 +313,14 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
293313
}
294314
}
295315
break;
316+
case ZEND_SEND_VAL:
317+
case ZEND_SEND_VAR:
318+
case ZEND_SEND_REF:
319+
if (opline->op2_type == IS_CONST) {
320+
call_stack[call - 1].try_inline = 0;
321+
break;
322+
}
323+
break;
296324
case ZEND_SEND_UNPACK:
297325
case ZEND_SEND_USER:
298326
case ZEND_SEND_ARRAY:

ext/opcache/Optimizer/zend_call_graph.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,12 @@ int zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_f
126126
case ZEND_SEND_VAR_NO_REF_EX:
127127
case ZEND_SEND_USER:
128128
if (call_info) {
129-
uint32_t num = opline->op2.num;
129+
if (opline->op2_type == IS_CONST) {
130+
call_info->named_args = 1;
131+
break;
132+
}
130133

134+
uint32_t num = opline->op2.num;
131135
if (num > 0) {
132136
num--;
133137
}

ext/opcache/Optimizer/zend_call_graph.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct _zend_call_info {
4242
zend_func_info *clone;
4343
zend_bool recursive;
4444
zend_bool send_unpack; /* Parameters passed by SEND_UNPACK or SEND_ARRAY */
45+
zend_bool named_args; /* Function has named arguments */
4546
int num_args;
4647
zend_send_arg_info arg_info[1];
4748
};

0 commit comments

Comments
 (0)