Skip to content

Commit b06f02c

Browse files
committed
Fix ZEND_JIT_TRACE_INIT_CALL/ZEND_JIT_TRACE_DO_ICALL num_args mismatch
It may be caused by SEND_UNPACK/SEND_ARRAY
1 parent 50d7797 commit b06f02c

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1297,6 +1297,39 @@ typedef struct _zend_tssa {
12971297

12981298
static const zend_op _nop_opcode = {0};
12991299

1300+
static uint32_t find_trampoline_num_args(zend_jit_trace_rec *start, zend_jit_trace_rec *p)
1301+
{
1302+
int inline_level = 0, call_level = 0;
1303+
1304+
p--;
1305+
while (p != start) {
1306+
if (p->op == ZEND_JIT_TRACE_INIT_CALL) {
1307+
if (inline_level == 0) {
1308+
if (call_level == 0) {
1309+
ZEND_ASSERT(!p->op_array);
1310+
return ZEND_JIT_TRACE_NUM_ARGS(p->info);
1311+
} else {
1312+
call_level--;
1313+
}
1314+
}
1315+
} else if (p->op == ZEND_JIT_TRACE_DO_ICALL) {
1316+
if (inline_level == 0) {
1317+
call_level++;
1318+
}
1319+
} else if (p->op == ZEND_JIT_TRACE_ENTER) {
1320+
if (inline_level) {
1321+
inline_level--;
1322+
} else {
1323+
return 0;
1324+
}
1325+
} else if (p->op == ZEND_JIT_TRACE_BACK) {
1326+
inline_level++;
1327+
}
1328+
p--;
1329+
}
1330+
return 0;
1331+
}
1332+
13001333
static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uint32_t parent_trace, uint32_t exit_num, zend_script *script, const zend_op_array **op_arrays, int *num_op_arrays_ptr)
13011334
{
13021335
zend_ssa *tssa;
@@ -1368,6 +1401,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
13681401
stack_size = stack_top;
13691402
}
13701403
} else if (p->op == ZEND_JIT_TRACE_DO_ICALL) {
1404+
uint32_t num_args = 0;
13711405
if (JIT_G(opt_level) < ZEND_JIT_LEVEL_OPT_FUNC) {
13721406
if (p->func
13731407
&& p->func != (zend_function*)&zend_pass_function
@@ -1377,7 +1411,11 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
13771411
ssa->cfg.flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS;
13781412
}
13791413
}
1380-
frame_size = zend_jit_trace_frame_size(p->op_array, ZEND_JIT_TRACE_NUM_ARGS(p->info));
1414+
if (!p->func) {
1415+
/* Find num_args in the corresponding ZEND_JIT_TRACE_INIT_CALL record */
1416+
num_args = find_trampoline_num_args(trace_buffer + ZEND_JIT_TRACE_START_REC_SIZE, p);
1417+
}
1418+
frame_size = zend_jit_trace_frame_size(p->op_array, num_args);
13811419
if (call_level == 0) {
13821420
if (stack_top + frame_size > stack_size) {
13831421
stack_size = stack_top + frame_size;

0 commit comments

Comments
 (0)