Skip to content

Commit d857878

Browse files
committed
fix(opcache): preserve substituted arg_info on inherited methods
Signed-off-by: azjezz <azjezz@protonmail.com>
1 parent 004156c commit d857878

3 files changed

Lines changed: 60 additions & 2 deletions

File tree

Zend/Optimizer/zend_optimizer.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,12 +1734,17 @@ ZEND_API void zend_optimize_script(zend_script *script, zend_long optimization_l
17341734
uint32_t fn_flags2 = op_array->fn_flags2;
17351735
zend_function *prototype = op_array->prototype;
17361736
HashTable *ht = op_array->static_variables;
1737+
zend_arg_info *arg_info = op_array->arg_info;
1738+
bool arg_info_substituted = (arg_info != orig_op_array->arg_info);
17371739

17381740
*op_array = *orig_op_array;
17391741
op_array->fn_flags = fn_flags;
17401742
op_array->fn_flags2 = fn_flags2;
17411743
op_array->prototype = prototype;
17421744
op_array->static_variables = ht;
1745+
if (arg_info_substituted) {
1746+
op_array->arg_info = arg_info;
1747+
}
17431748
}
17441749
}
17451750
} ZEND_HASH_FOREACH_END();

ext/opcache/zend_persist.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,31 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
586586
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
587587
arg_info--;
588588
}
589-
arg_info = zend_shared_alloc_get_xlat_entry(arg_info);
590-
ZEND_ASSERT(arg_info != NULL);
589+
zend_arg_info *xlat_arg_info = zend_shared_alloc_get_xlat_entry(arg_info);
590+
if (xlat_arg_info) {
591+
arg_info = xlat_arg_info;
592+
} else {
593+
uint32_t num_args = op_array->num_args;
594+
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
595+
num_args++;
596+
}
597+
598+
if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
599+
num_args++;
600+
}
601+
602+
arg_info = zend_shared_memdup_put(arg_info, sizeof(zend_arg_info) * num_args);
603+
for (uint32_t i = 0; i < num_args; i++) {
604+
if (arg_info[i].name) {
605+
zend_accel_store_interned_string(arg_info[i].name);
606+
}
607+
608+
zend_persist_type(&arg_info[i].type);
609+
if (arg_info[i].doc_comment) {
610+
zend_accel_store_interned_string(arg_info[i].doc_comment);
611+
}
612+
}
613+
}
591614
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
592615
arg_info++;
593616
}

ext/opcache/zend_persist_calc.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,36 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
343343
if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) {
344344
/* already stored */
345345
ADD_SIZE(ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist_calc(op_array)));
346+
if (op_array->arg_info) {
347+
zend_arg_info *arg_info = op_array->arg_info;
348+
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
349+
arg_info--;
350+
}
351+
352+
if (!zend_shared_alloc_get_xlat_entry(arg_info)) {
353+
uint32_t num_args = op_array->num_args;
354+
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
355+
num_args++;
356+
}
357+
358+
if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
359+
num_args++;
360+
}
361+
362+
ADD_SIZE(sizeof(zend_arg_info) * num_args);
363+
for (uint32_t i = 0; i < num_args; i++) {
364+
if (arg_info[i].name) {
365+
ADD_INTERNED_STRING(arg_info[i].name);
366+
}
367+
368+
zend_persist_type_calc(&arg_info[i].type);
369+
if (arg_info[i].doc_comment) {
370+
ADD_INTERNED_STRING(arg_info[i].doc_comment);
371+
}
372+
}
373+
}
374+
}
375+
346376
return;
347377
}
348378
}

0 commit comments

Comments
 (0)