diff --git a/Zend/Optimizer/compact_literals.c b/Zend/Optimizer/compact_literals.c index d0aaccec7ce2..be5092fbcfd4 100644 --- a/Zend/Optimizer/compact_literals.c +++ b/Zend/Optimizer/compact_literals.c @@ -740,6 +740,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx cache_size += 2 * sizeof(void *); } break; + case ZEND_FETCH_DIM_R: + if (opline->op1_type != IS_CONST && opline->op2_type == IS_CONST) { + opline->extended_value = cache_size; + cache_size += sizeof(void *); + } + break; } opline++; } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 0669d106f15e..c4fad5b8acc6 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3082,6 +3082,9 @@ static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t opline = zend_delayed_emit_op(result, ZEND_FETCH_DIM_R, &var_node, &dim_node); zend_adjust_for_fetch_type(opline, result, type); + if (type == BP_VAR_R && opline->op1_type != IS_CONST && opline->op2_type == IS_CONST) { + opline->extended_value = zend_alloc_cache_slot(); + } if (by_ref) { opline->extended_value = ZEND_FETCH_DIM_REF; } @@ -8361,10 +8364,10 @@ static zend_op_array *zend_compile_func_decl_ex( "nodiscard", sizeof("nodiscard")-1 ); - + if (nodiscard_attribute) { op_array->fn_flags |= ZEND_ACC_NODISCARD; - } + } } /* Do not leak the class scope into free standing functions, even if they are dynamically diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9c2ba0038b4a..0d2faceaf9dd 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -10265,6 +10265,100 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, ((op->op1_type == IS_CONST) ? !Z_R ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_FETCH_DIM_R, (op->op1_type != IS_CONST && op->op2_type == IS_CONST && !(op2_info & (MAY_BE_ANY-MAY_BE_STRING-MAY_BE_LONG))), ZEND_FETCH_DIM_R_CACHED_INDEX, TMPVAR|CV, CONST, CACHE_SLOT) +{ + USE_OPLINE + + zval *container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + zval *dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + zval *value; + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +ZEND_VM_C_LABEL(fetch_dim_r_const_index_array):; + HashTable *ht = Z_ARRVAL_P(container); + if (Z_TYPE_P(dim) == IS_LONG) { + zend_long offset = Z_LVAL_P(dim); + if (HT_IS_PACKED(ht)) { + if (EXPECTED((zend_ulong)offset < (zend_ulong)ht->nNumUsed)) { + value = &ht->arPacked[offset]; + if (EXPECTED(Z_TYPE_P(value) != IS_UNDEF)) { +ZEND_VM_C_LABEL(fetch_dim_r_cached_index_found): + ZVAL_COPY_DEREF(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(); + } + } + } + ZEND_VM_C_GOTO(fetch_dim_r_cached_index_undef); + } + uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value); + if (cached_offset && ht->nNumUsed >= cached_offset) { + Bucket *b = &ht->arData[cached_offset - 1]; + if (!b->key && b->h == offset) { + value = &b->val; + ZEND_VM_C_GOTO(fetch_dim_r_cached_index_found); + } + } + + value = _zend_hash_index_find(ht, offset); +ZEND_VM_C_LABEL(fetch_dim_r_cached_index_check): + if (EXPECTED(value)) { + Bucket *bucket = (Bucket*)((uintptr_t)value - XtOffsetOf(Bucket, val)); + CACHE_PTR(opline->extended_value, (void *)(bucket - ht->arData + 1)); + ZEND_VM_C_GOTO(fetch_dim_r_cached_index_found); + } else { + ZEND_VM_C_GOTO(fetch_dim_r_cached_index_undef); + } + } else { + if (UNEXPECTED(HT_IS_PACKED(ht))) { + ZEND_VM_C_GOTO(fetch_dim_r_cached_index_undef); + } + uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value); + if (cached_offset && ht->nNumUsed >= cached_offset) { + Bucket *b = &ht->arData[cached_offset - 1]; + if (b->key && zend_string_equals(b->key, Z_STR_P(dim))) { + value = &b->val; + ZEND_VM_C_GOTO(fetch_dim_r_cached_index_found); + } + } + + value = zend_hash_find(ht, Z_STR_P(dim)); + ZEND_VM_C_GOTO(fetch_dim_r_cached_index_check); + } + } else if (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_const_index_array); + } else { + ZEND_VM_C_GOTO(fetch_dim_r_const_index_slow); + } + } else { +ZEND_VM_C_LABEL(fetch_dim_r_const_index_slow): + if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +ZEND_VM_C_LABEL(fetch_dim_r_cached_index_undef): + SAVE_OPLINE(); + ZVAL_NULL(EX_VAR(opline->result.var)); + if (Z_TYPE_P(dim) == IS_LONG) { + zend_undefined_offset(Z_LVAL_P(dim)); + } else { + zend_undefined_index(Z_STR_P(dim)); + } + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + ZEND_VM_HOT_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|TMPVARCV, SPEC(NO_CONST_CONST)) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 226e0446abbd..e8ff178717b1 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -17116,6 +17116,100 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_H ZEND_VM_SMART_BRANCH(result, 1); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *dim = RT_CONSTANT(opline, opline->op2); + zval *value; + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_const_index_array:; + HashTable *ht = Z_ARRVAL_P(container); + if (Z_TYPE_P(dim) == IS_LONG) { + zend_long offset = Z_LVAL_P(dim); + if (HT_IS_PACKED(ht)) { + if (EXPECTED((zend_ulong)offset < (zend_ulong)ht->nNumUsed)) { + value = &ht->arPacked[offset]; + if (EXPECTED(Z_TYPE_P(value) != IS_UNDEF)) { +fetch_dim_r_cached_index_found: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } + } + goto fetch_dim_r_cached_index_undef; + } + uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value); + if (cached_offset && ht->nNumUsed >= cached_offset) { + Bucket *b = &ht->arData[cached_offset - 1]; + if (!b->key && b->h == offset) { + value = &b->val; + goto fetch_dim_r_cached_index_found; + } + } + + value = _zend_hash_index_find(ht, offset); +fetch_dim_r_cached_index_check: + if (EXPECTED(value)) { + Bucket *bucket = (Bucket*)((uintptr_t)value - XtOffsetOf(Bucket, val)); + CACHE_PTR(opline->extended_value, (void *)(bucket - ht->arData + 1)); + goto fetch_dim_r_cached_index_found; + } else { + goto fetch_dim_r_cached_index_undef; + } + } else { + if (UNEXPECTED(HT_IS_PACKED(ht))) { + goto fetch_dim_r_cached_index_undef; + } + uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value); + if (cached_offset && ht->nNumUsed >= cached_offset) { + Bucket *b = &ht->arData[cached_offset - 1]; + if (b->key && zend_string_equals(b->key, Z_STR_P(dim))) { + value = &b->val; + goto fetch_dim_r_cached_index_found; + } + } + + value = zend_hash_find(ht, Z_STR_P(dim)); + goto fetch_dim_r_cached_index_check; + } + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_const_index_array; + } else { + goto fetch_dim_r_const_index_slow; + } + } else { +fetch_dim_r_const_index_slow: + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_cached_index_undef: + SAVE_OPLINE(); + ZVAL_NULL(EX_VAR(opline->result.var)); + if (Z_TYPE_P(dim) == IS_LONG) { + zend_undefined_offset(Z_LVAL_P(dim)); + } else { + zend_undefined_index(Z_STR_P(dim)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -45819,6 +45913,100 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_ ZEND_VM_SMART_BRANCH(!result, 0); } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *container = EX_VAR(opline->op1.var); + zval *dim = RT_CONSTANT(opline, opline->op2); + zval *value; + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_const_index_array:; + HashTable *ht = Z_ARRVAL_P(container); + if (Z_TYPE_P(dim) == IS_LONG) { + zend_long offset = Z_LVAL_P(dim); + if (HT_IS_PACKED(ht)) { + if (EXPECTED((zend_ulong)offset < (zend_ulong)ht->nNumUsed)) { + value = &ht->arPacked[offset]; + if (EXPECTED(Z_TYPE_P(value) != IS_UNDEF)) { +fetch_dim_r_cached_index_found: + ZVAL_COPY_DEREF(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(); + } + } + } + goto fetch_dim_r_cached_index_undef; + } + uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value); + if (cached_offset && ht->nNumUsed >= cached_offset) { + Bucket *b = &ht->arData[cached_offset - 1]; + if (!b->key && b->h == offset) { + value = &b->val; + goto fetch_dim_r_cached_index_found; + } + } + + value = _zend_hash_index_find(ht, offset); +fetch_dim_r_cached_index_check: + if (EXPECTED(value)) { + Bucket *bucket = (Bucket*)((uintptr_t)value - XtOffsetOf(Bucket, val)); + CACHE_PTR(opline->extended_value, (void *)(bucket - ht->arData + 1)); + goto fetch_dim_r_cached_index_found; + } else { + goto fetch_dim_r_cached_index_undef; + } + } else { + if (UNEXPECTED(HT_IS_PACKED(ht))) { + goto fetch_dim_r_cached_index_undef; + } + uintptr_t cached_offset = (uintptr_t)CACHED_PTR(opline->extended_value); + if (cached_offset && ht->nNumUsed >= cached_offset) { + Bucket *b = &ht->arData[cached_offset - 1]; + if (b->key && zend_string_equals(b->key, Z_STR_P(dim))) { + value = &b->val; + goto fetch_dim_r_cached_index_found; + } + } + + value = zend_hash_find(ht, Z_STR_P(dim)); + goto fetch_dim_r_cached_index_check; + } + } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_const_index_array; + } else { + goto fetch_dim_r_const_index_slow; + } + } else { +fetch_dim_r_const_index_slow: + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + +fetch_dim_r_cached_index_undef: + SAVE_OPLINE(); + ZVAL_NULL(EX_VAR(opline->result.var)); + if (Z_TYPE_P(dim) == IS_LONG) { + zend_undefined_offset(Z_LVAL_P(dim)); + } else { + zend_undefined_index(Z_STR_P(dim)); + } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -58483,6 +58671,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_CV_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -60816,6 +61009,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST): + VM_TRACE(ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST) + ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST): VM_TRACE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -63398,6 +63596,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_CV_CONST): + VM_TRACE(ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_CV_CONST) + ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_CV_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST): VM_TRACE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -67675,6 +67878,11 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST_HANDLER, + ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_CV_CONST_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, @@ -67761,7 +67969,7 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, - 3487, + 3492, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, 1276 | SPEC_RULE_OP2, @@ -67795,7 +68003,7 @@ void zend_vm_init(void) 1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1584 | SPEC_RULE_OP1, 1589, - 3487, + 3492, 1590 | SPEC_RULE_OP1, 1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -67927,51 +68135,51 @@ void zend_vm_init(void) 2575, 2576, 2577, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, - 3487, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, + 3492, }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -68353,35 +68561,37 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t break; case ZEND_SEND_VAL: if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3483; + spec = 3488; } break; case ZEND_SEND_VAR_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3478 | SPEC_RULE_OP1; + spec = 3483 | SPEC_RULE_OP1; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 3485 | SPEC_RULE_RETVAL; + spec = 3490 | SPEC_RULE_RETVAL; } 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))) { + if (op->op1_type != IS_CONST && op->op2_type == IS_CONST && !(op2_info & (MAY_BE_ANY-MAY_BE_STRING-MAY_BE_LONG))) { + spec = 3448 | SPEC_RULE_OP1; + } else if (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3448 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3453 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAL_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3484; + spec = 3489; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3473 | SPEC_RULE_OP1; + spec = 3478 | SPEC_RULE_OP1; } break; case ZEND_COUNT: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index cbbc6a477278..f3b0455ff55a 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -1848,27 +1848,30 @@ _(3444, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ _(3445, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ _(3447, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3450, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3452, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3453, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3449, ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST) \ + _(3450, ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_TMPVAR_CONST) \ + _(3452, ZEND_FETCH_DIM_R_CACHED_INDEX_SPEC_CV_CONST) \ + _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ _(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3460, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3462, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ - _(3469, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3470, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3472, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3475, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3477, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3480, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3482, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3483, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3484, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3485, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3486, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3486+1, ZEND_NULL) + _(3463, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3464, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3465, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3467, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3473, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3474, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3475, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3477, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3480, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3482, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3485, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3487, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3488, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3489, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3490, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3491, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3491+1, ZEND_NULL)