diff options
author | Dmitry Stogov <dmitry@zend.com> | 2016-05-18 15:06:49 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2016-05-18 15:06:49 +0300 |
commit | 88196e9151e440483c22ee3974621b51dddf7df1 (patch) | |
tree | 442acb9ce56e7eaa57b91f1515d9f525def5adcc | |
parent | 932c9520bc7ba53af840e1067be50d8c6478763a (diff) | |
download | php-git-88196e9151e440483c22ee3974621b51dddf7df1.tar.gz |
Added specialized handler for ZEND_FETCH_DIM_R opcode with only numeric indexes.
-rw-r--r-- | Zend/zend_vm_def.h | 48 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 472 |
2 files changed, 515 insertions, 5 deletions
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8522523d94..93ff58e807 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8463,4 +8463,52 @@ ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDE ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_FETCH_DIM_R, (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))), ZEND_FETCH_DIM_R_INDEX, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container, *dim, *value; + zend_long offset; + + container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +ZEND_VM_C_LABEL(fetch_dim_r_index_array): + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, ZEND_VM_C_LABEL(fetch_dim_r_index_undef)); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + ZEND_VM_C_GOTO(fetch_dim_r_index_array); + } else { + ZEND_VM_C_GOTO(fetch_dim_r_index_slow); + } + } else { +ZEND_VM_C_LABEL(fetch_dim_r_index_slow): + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +ZEND_VM_C_LABEL(fetch_dim_r_index_undef): + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2424a636dd..1b673b8c2a 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6280,6 +6280,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER ZEND_VM_RETURN(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container, *dim, *value; + zend_long offset; + + container = EX_CONSTANT(opline->op1); + dim = EX_CONSTANT(opline->op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -9848,6 +9896,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE ZEND_VM_RETURN(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container, *dim, *value; + zend_long offset; + + container = EX_CONSTANT(opline->op1); + dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -11525,6 +11621,54 @@ isset_no_object: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *container, *dim, *value; + zend_long offset; + + container = EX_CONSTANT(opline->op1); + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -42872,6 +43016,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + dim = EX_CONSTANT(opline->op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -49604,6 +49796,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_ ZEND_VM_RETURN(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -53508,6 +53748,54 @@ isset_no_object: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var); + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -55543,6 +55831,54 @@ try_instanceof: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + dim = EX_CONSTANT(opline->op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE @@ -57633,6 +57969,54 @@ isset_no_object: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -58822,6 +59206,54 @@ isset_no_object: ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval *container, *dim, *value; + zend_long offset; + + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + offset = zval_get_long(dim); + } + ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef); + ZVAL_COPY(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset); + zval_ptr_dtor_nogc(free_op1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -64198,6 +64630,31 @@ void zend_init_opcodes_handlers(void) ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER }; static const uint32_t specs[] = { @@ -64250,9 +64707,9 @@ void zend_init_opcodes_handlers(void) 1423 | SPEC_RULE_OP1, 1428 | SPEC_RULE_OP1, 1433 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4446, - 4446, - 4446, + 4471, + 4471, + 4471, 1458 | SPEC_RULE_OP1, 1463 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1488 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -64301,7 +64758,7 @@ void zend_init_opcodes_handlers(void) 2197 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2222 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2247 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4446, + 4471, 2272, 2273, 2274, @@ -64385,7 +64842,7 @@ void zend_init_opcodes_handlers(void) 3446 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3471 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 3496 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 4446 + 4471 }; zend_opcode_handlers = labels; zend_handlers_count = sizeof(labels) / sizeof(void*); @@ -64666,6 +65123,11 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint spec = 4431 | SPEC_RULE_OP1; } break; + case ZEND_FETCH_DIM_R: + if ((!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)))) { + spec = 4446 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + } + break; default: break; } |