Skip to content

Commit c6d6ee4

Browse files
committed
Break FETCH_LIST into two portions
1 parent 2b6d19e commit c6d6ee4

File tree

9 files changed

+287
-176
lines changed

9 files changed

+287
-176
lines changed

Zend/zend_compile.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ void zend_do_free(znode *op1) /* {{{ */
784784
}
785785
} else {
786786
while (opline >= CG(active_op_array)->opcodes) {
787-
if (opline->opcode == ZEND_FETCH_LIST &&
787+
if ((opline->opcode == ZEND_FETCH_LIST_R || opline->opcode == ZEND_FETCH_LIST_RW) &&
788788
opline->op1_type == IS_VAR &&
789789
opline->op1.var == op1->u.op.var) {
790790
zend_emit_op(NULL, ZEND_FREE, op1, NULL);
@@ -2088,7 +2088,8 @@ static void zend_check_live_ranges(zend_op *opline) /* {{{ */
20882088
opline->opcode == ZEND_ROPE_ADD ||
20892089
opline->opcode == ZEND_ROPE_END ||
20902090
opline->opcode == ZEND_END_SILENCE ||
2091-
opline->opcode == ZEND_FETCH_LIST ||
2091+
opline->opcode == ZEND_FETCH_LIST_R ||
2092+
opline->opcode == ZEND_FETCH_LIST_RW ||
20922093
opline->opcode == ZEND_VERIFY_RETURN_TYPE ||
20932094
opline->opcode == ZEND_BIND_LEXICAL) {
20942095
/* these opcodes are handled separately */
@@ -2848,7 +2849,6 @@ static void zend_compile_list_assign(
28482849
zend_bool has_elems = 0;
28492850
zend_bool is_keyed =
28502851
list->children > 0 && list->child[0] != NULL && list->child[0]->child[1] != NULL;
2851-
zend_op *opline;
28522852

28532853
for (i = 0; i < list->children; ++i) {
28542854
zend_ast *elem_ast = list->child[i];
@@ -2891,10 +2891,10 @@ static void zend_compile_list_assign(
28912891

28922892
zend_verify_list_assign_target(var_ast, old_style);
28932893

2894-
opline = zend_emit_op(&fetch_result, ZEND_FETCH_LIST, expr_node, &dim_node);
2895-
28962894
if (elem_ast->attr || (var_ast->kind == ZEND_AST_ARRAY && zend_set_list_assign_reference(var_ast))) {
2897-
opline->extended_value = ZEND_LIST_MAKE_WRITABLE;
2895+
zend_emit_op(&fetch_result, ZEND_FETCH_LIST_RW, expr_node, &dim_node);
2896+
} else {
2897+
zend_emit_op(&fetch_result, ZEND_FETCH_LIST_R, expr_node, &dim_node);
28982898
}
28992899

29002900
if (elem_ast->attr) {

Zend/zend_execute.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,13 +1921,14 @@ static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result,
19211921
zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1, 0);
19221922
}
19231923

1924-
static zend_never_inline void zend_fetch_dimension_address_LIST(zval *result, zval *container, zval *dim, int type)
1924+
static zend_never_inline void zend_fetch_dimension_address_LIST_R(zval *result, zval *container, zval *dim)
19251925
{
1926-
if (type == BP_VAR_RW) {
1927-
zend_fetch_dimension_address(result, container, dim, IS_TMP_VAR, type);
1928-
} else {
1929-
zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, type, 0, 0);
1930-
}
1926+
zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, BP_VAR_R, 0, 0);
1927+
}
1928+
1929+
static zend_never_inline void zend_fetch_dimension_address_LIST_RW(zval *result, zval *container, zval *dim)
1930+
{
1931+
zend_fetch_dimension_address(result, container, dim, IS_TMP_VAR, BP_VAR_RW);
19311932
}
19321933

19331934
ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim)

Zend/zend_vm_def.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,28 +2086,44 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
20862086
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
20872087
}
20882088

2089-
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
2089+
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
2090+
{
2091+
USE_OPLINE
2092+
zend_free_op free_op1, free_op2;
2093+
zval *container, retval;
2094+
2095+
SAVE_OPLINE();
2096+
container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
2097+
2098+
zend_fetch_dimension_address_LIST_R(&retval, container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R));
2099+
2100+
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &retval);
2101+
FREE_OP2();
2102+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
2103+
}
2104+
2105+
ZEND_VM_HANDLER(187, ZEND_FETCH_LIST_RW, VAR|CV, CONST|TMPVAR|CV)
20902106
{
20912107
USE_OPLINE
20922108
zend_free_op free_op1, free_op2;
20932109
zval *container, *retval_ptr, retval;
2094-
int type = opline->extended_value == ZEND_LIST_MAKE_WRITABLE ? BP_VAR_RW : BP_VAR_R;
20952110

20962111
SAVE_OPLINE();
2097-
container = GET_OP1_ZVAL_PTR_UNDEF(type);
2112+
container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_RW);
20982113

2099-
zend_fetch_dimension_address_LIST(&retval, container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), type);
2114+
zend_fetch_dimension_address_LIST_RW(&retval, container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R));
21002115

21012116
if (UNEXPECTED(Z_TYPE(retval) == IS_INDIRECT)) {
21022117
retval_ptr = Z_INDIRECT(retval);
21032118
if (EXPECTED(!Z_ISREF_P(retval_ptr))) {
21042119
ZVAL_MAKE_REF(retval_ptr);
21052120
}
2106-
GC_REFCOUNT(Z_REF_P(retval_ptr))++;
2121+
Z_ADDREF_P(retval_ptr);
21072122
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(retval_ptr));
21082123
} else {
21092124
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &retval);
21102125
}
2126+
21112127
FREE_OP2();
21122128
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
21132129
}

0 commit comments

Comments
 (0)