diff options
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r-- | Zend/zend_vm_execute.h | 1220 |
1 files changed, 751 insertions, 469 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9d7eae0311..24a4d67bf2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1146,6 +1146,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper ZEND_VM_LEAVE(); } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) { zend_detach_symbol_table(execute_data); + zend_destroy_static_vars(&EX(func)->op_array); destroy_op_array(&EX(func)->op_array); efree_size(EX(func), sizeof(zend_op_array)); #ifdef ZEND_PREFER_RELOAD @@ -1225,7 +1226,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif ret = 0 ? EX_VAR(opline->result.var) : &retval; @@ -1286,7 +1287,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif ret = 1 ? EX_VAR(opline->result.var) : &retval; @@ -1451,7 +1452,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif ret = 0 ? EX_VAR(opline->result.var) : &retval; @@ -1545,7 +1546,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif ret = 1 ? EX_VAR(opline->result.var) : &retval; @@ -1640,7 +1641,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_ EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; @@ -1744,7 +1745,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif ret = 0 ? EX_VAR(opline->result.var) : &retval; @@ -1852,7 +1853,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif ret = 1 ? EX_VAR(opline->result.var) : &retval; @@ -1960,7 +1961,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; @@ -2115,7 +2116,7 @@ send_again: HashTable *ht = Z_ARRVAL_P(args); zval *arg, *top; zend_string *name; - zend_bool have_named_params = 0; + bool have_named_params = 0; zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht)); @@ -2186,7 +2187,7 @@ send_again: } else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) { zend_class_entry *ce = Z_OBJCE_P(args); zend_object_iterator *iter; - zend_bool have_named_params = 0; + bool have_named_params = 0; if (!ce || !ce->get_iterator) { zend_type_error("Only arrays and Traversables can be unpacked"); @@ -2203,26 +2204,27 @@ send_again: HANDLE_EXCEPTION(); } - if (iter->funcs->rewind) { - iter->funcs->rewind(iter); + const zend_object_iterator_funcs *funcs = iter->funcs; + if (funcs->rewind) { + funcs->rewind(iter); } - for (; iter->funcs->valid(iter) == SUCCESS; ++arg_num) { + for (; funcs->valid(iter) == SUCCESS; ++arg_num) { zval *arg, *top; if (UNEXPECTED(EG(exception) != NULL)) { break; } - arg = iter->funcs->get_current_data(iter); + arg = funcs->get_current_data(iter); if (UNEXPECTED(EG(exception) != NULL)) { break; } zend_string *name = NULL; - if (iter->funcs->get_current_key) { + if (funcs->get_current_key) { zval key; - iter->funcs->get_current_key(iter, &key); + funcs->get_current_key(iter, &key); if (UNEXPECTED(EG(exception) != NULL)) { break; } @@ -2284,7 +2286,7 @@ send_again: ZEND_CALL_NUM_ARGS(EX(call))++; } - iter->funcs->move_forward(iter); + funcs->move_forward(iter); } zend_iterator_dtor(iter); @@ -2348,7 +2350,7 @@ send_array: arg_num = 1; param = ZEND_CALL_ARG(EX(call), 1); ZEND_HASH_FOREACH_VAL(ht, arg) { - zend_bool must_wrap = 0; + bool must_wrap = 0; if (skip > 0) { skip--; continue; @@ -2384,7 +2386,7 @@ send_array: FREE_OP(opline->op2_type, opline->op2.var); } else { zend_string *name; - zend_bool have_named_params; + bool have_named_params; zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht)); arg_num = 1; param = ZEND_CALL_ARG(EX(call), 1); @@ -2405,7 +2407,7 @@ send_array: HANDLE_EXCEPTION(); } - zend_bool must_wrap = 0; + bool must_wrap = 0; if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { if (UNEXPECTED(!Z_ISREF_P(arg))) { if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) { @@ -2452,7 +2454,7 @@ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mi HANDLE_EXCEPTION(); } -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_verify_recv_arg_type_helper_SPEC(zval *op_1 ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_verify_recv_arg_type_helper_SPEC(zval *op_1 ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE @@ -2499,9 +2501,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER( { USE_OPLINE zval *op1; + HashTable *result_ht; SAVE_OPLINE(); op1 = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); + result_ht = Z_ARRVAL_P(EX_VAR(opline->result.var)); add_unpack_again: if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) { @@ -2510,16 +2514,14 @@ add_unpack_again: zend_string *key; ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) { + val = Z_REFVAL_P(val); + } + Z_TRY_ADDREF_P(val); if (key) { - zend_throw_error(NULL, "Cannot unpack array with string keys"); - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); + zend_hash_update(result_ht, key, val); } else { - if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) { - val = Z_REFVAL_P(val); - } - Z_TRY_ADDREF_P(val); - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), val)) { + if (!zend_hash_next_index_insert(result_ht, val)) { zend_cannot_add_element(); zval_ptr_dtor_nogc(val); break; @@ -2544,48 +2546,59 @@ add_unpack_again: HANDLE_EXCEPTION(); } - if (iter->funcs->rewind) { - iter->funcs->rewind(iter); + const zend_object_iterator_funcs *funcs = iter->funcs; + if (funcs->rewind) { + funcs->rewind(iter); } - for (; iter->funcs->valid(iter) == SUCCESS; ) { + for (; funcs->valid(iter) == SUCCESS; ) { zval *val; if (UNEXPECTED(EG(exception) != NULL)) { break; } - val = iter->funcs->get_current_data(iter); + val = funcs->get_current_data(iter); if (UNEXPECTED(EG(exception) != NULL)) { break; } - if (iter->funcs->get_current_key) { - zval key; - iter->funcs->get_current_key(iter, &key); + zval key; + if (funcs->get_current_key) { + funcs->get_current_key(iter, &key); if (UNEXPECTED(EG(exception) != NULL)) { break; } - if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) { + if (UNEXPECTED(Z_TYPE(key) != IS_LONG && Z_TYPE(key) != IS_STRING)) { zend_throw_error(NULL, - (Z_TYPE(key) == IS_STRING) ? - "Cannot unpack Traversable with string keys" : - "Cannot unpack Traversable with non-integer keys"); + "Keys must be of type int|string during array unpacking"); zval_ptr_dtor(&key); break; } + } else { + ZVAL_UNDEF(&key); } ZVAL_DEREF(val); Z_TRY_ADDREF_P(val); - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), val)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(val); + zend_ulong num_key; + if (Z_TYPE(key) == IS_STRING && !ZEND_HANDLE_NUMERIC(Z_STR(key), num_key)) { + zend_hash_update(result_ht, Z_STR(key), val); + zval_ptr_dtor_str(&key); + } else { + if (!zend_hash_next_index_insert(result_ht, val)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(val); + break; + } } - iter->funcs->move_forward(iter); + funcs->move_forward(iter); + if (UNEXPECTED(EG(exception))) { + break; + } } zend_iterator_dtor(iter); @@ -2653,6 +2666,124 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_STATIC_PROP ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fe_fetch_object_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *array; + zval *value; + uint32_t value_type; + HashTable *fe_ht; + HashPosition pos; + Bucket *p; + zend_object_iterator *iter; + + array = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + + ZEND_ASSERT(Z_TYPE_P(array) == IS_OBJECT); + if ((iter = zend_iterator_unwrap(array)) == NULL) { + /* plain object */ + + fe_ht = Z_OBJPROP_P(array); + pos = zend_hash_iterator_pos(Z_FE_ITER_P(array), fe_ht); + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + goto fe_fetch_r_exit; + } + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + if (EXPECTED(value_type != IS_UNDEF)) { + if (UNEXPECTED(value_type == IS_INDIRECT)) { + value = Z_INDIRECT_P(value); + value_type = Z_TYPE_INFO_P(value); + if (EXPECTED(value_type != IS_UNDEF) + && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) { + break; + } + } else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0) + || !p->key + || zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) { + break; + } + } + p++; + } + EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos; + if (RETURN_VALUE_USED(opline)) { + if (UNEXPECTED(!p->key)) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); + } else if (ZSTR_VAL(p->key)[0]) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + } else { + const char *class_name, *prop_name; + size_t prop_name_len; + zend_unmangle_property_name_ex( + p->key, &class_name, &prop_name, &prop_name_len); + ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); + } + } + } else { + const zend_object_iterator_funcs *funcs = iter->funcs; + if (EXPECTED(++iter->index > 0)) { + /* This could cause an endless loop if index becomes zero again. + * In case that ever happens we need an additional flag. */ + funcs->move_forward(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + if (UNEXPECTED(funcs->valid(iter) == FAILURE)) { + /* reached end of iteration */ + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } +fe_fetch_r_exit: + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } + } + value = funcs->get_current_data(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + if (!value) { + /* failure in get_current_data */ + goto fe_fetch_r_exit; + } + if (RETURN_VALUE_USED(opline)) { + if (funcs->get_current_key) { + funcs->get_current_key(iter, EX_VAR(opline->result.var)); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + } else { + ZVAL_LONG(EX_VAR(opline->result.var), iter->index); + } + } + value_type = Z_TYPE_INFO_P(value); + } + + if (EXPECTED(opline->op2_type == IS_CV)) { + zval *variable_ptr = EX_VAR(opline->op2.var); + zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + } else { + zval *res = EX_VAR(opline->op2.var); + zend_refcounted *gc = Z_COUNTED_P(value); + + ZVAL_COPY_VALUE_EX(res, value, gc, value_type); + if (Z_TYPE_INFO_REFCOUNTED(value_type)) { + GC_ADDREF(gc); + } + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -2803,7 +2934,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE ce = Z_CE_P(zv); if (!(ce->ce_flags & ZEND_ACC_LINKED)) { SAVE_OPLINE(); - if (zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL) == FAILURE) { + ce = zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL, rtd_key); + if (!ce) { HANDLE_EXCEPTION(); } } @@ -2815,10 +2947,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_function *func; USE_OPLINE SAVE_OPLINE(); - do_bind_function(RT_CONSTANT(opline, opline->op1)); + func = (zend_function *) EX(func)->op_array.dynamic_func_defs[opline->op2.num]; + do_bind_function(func, RT_CONSTANT(opline, opline->op1)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -3167,7 +3301,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif if (ret == NULL) { @@ -3303,7 +3437,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_ EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + bool should_throw = zend_internal_call_should_throw(fbc, call); #endif if (ret == NULL) { @@ -4433,7 +4567,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_ } catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH); if (UNEXPECTED(catch_ce == NULL)) { - catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT); CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce); } @@ -4627,6 +4761,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H } else { ZVAL_EMPTY_ARRAY(result); } + } else if (Z_OBJ_P(expr)->properties == NULL + && Z_OBJ_HT_P(expr)->get_properties_for == NULL + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + /* Optimized version without rebulding properties HashTable */ + ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST); if (obj_ht) { @@ -4719,6 +4858,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN zend_vm_stack_free_call_frame(call); } + zend_destroy_static_vars(new_op_array); destroy_op_array(new_op_array); efree_size(new_op_array, sizeof(zend_op_array)); if (UNEXPECTED(EG(exception) != NULL)) { @@ -4788,6 +4928,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_ zend_vm_stack_free_call_frame(call); } + zend_destroy_static_vars(new_op_array); destroy_op_array(new_op_array); efree_size(new_op_array, sizeof(zend_op_array)); if (UNEXPECTED(EG(exception) != NULL)) { @@ -4851,7 +4992,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CONST_HANDLER( ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -4943,7 +5084,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); if (IS_CONST == IS_VAR) { @@ -5139,6 +5280,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_SPEC_CONST_HANDL ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_function *func; + zval *object; + zend_class_entry *called_scope; + + func = (zend_function *) EX(func)->op_array.dynamic_func_defs[opline->op2.num]; + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); + if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) || + (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) { + object = NULL; + } else { + object = &EX(This); + } + } else { + called_scope = Z_CE(EX(This)); + object = NULL; + } + zend_create_closure(EX_VAR(opline->result.var), func, + EX(func)->op_array.scope, called_scope, object); + + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -5251,10 +5418,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST value = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } ZEND_VM_NEXT_OPCODE(); } else { - zend_bool strict; + bool strict; if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { value = Z_REFVAL_P(value); @@ -5275,8 +5444,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CONST zend_string *str; zval tmp; + if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { + zend_error(E_DEPRECATED, + "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + ZVAL_LONG(EX_VAR(opline->result.var), 0); + break; + } + ZVAL_COPY(&tmp, value); - if (zend_parse_arg_str_weak(&tmp, &str)) { + if (zend_parse_arg_str_weak(&tmp, &str, 1)) { ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); zval_ptr_dtor(&tmp); break; @@ -5624,7 +5803,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); @@ -5639,7 +5818,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_ { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); @@ -6107,6 +6286,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -6838,7 +7022,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS } } - zv = zend_hash_find_ex(&ce->constants_table, Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); + zv = zend_hash_find_ex(CE_CONSTANTS_TABLE(ce), Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); if (EXPECTED(zv != NULL)) { c = Z_PTR_P(zv); scope = EX(func)->op_array.scope; @@ -7013,7 +7197,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -7121,7 +7305,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -7165,7 +7349,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CON if (UNEXPECTED(!zv)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name)); } else { - if (zend_do_link_class(ce, Z_STR_P(RT_CONSTANT(opline, opline->op2))) == FAILURE) { + ce = zend_do_link_class(ce, Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(lcname)); + if (!ce) { /* Reload bucket pointer, the hash table may have been reallocated */ zv = zend_hash_find(EG(class_table), Z_STR_P(lcname)); zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(lcname + 1)); @@ -7441,33 +7626,69 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CON HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CONST == IS_CONST); - } else if (opline->extended_value) { + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); + } + + if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { - result = NULL; + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + + ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + + ZEND_VM_SMART_BRANCH(result, 0); + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + ZEND_VM_SMART_BRANCH(result, 0); } else { zend_string *key; - zval key_tmp, *val; + zval key_tmp; - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + + ZEND_VM_SMART_BRANCH(result, 0); + } + } + + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&key_tmp, key); if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; + + ZEND_VM_SMART_BRANCH(1, 1); } } ZEND_HASH_FOREACH_END(); } - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(0, 1); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -8397,6 +8618,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -9169,7 +9395,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); + value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -9277,7 +9503,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TM zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -9473,8 +9699,9 @@ fetch_this: } else if (type == BP_VAR_IS) { retval = &EG(uninitialized_zval); } else { - zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(name)); - if (type == BP_VAR_RW) { + zend_error(E_WARNING, "Undefined %svariable $%s", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name)); + if (type == BP_VAR_RW && !EG(exception)) { retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); } else { retval = &EG(uninitialized_zval); @@ -9492,8 +9719,9 @@ fetch_this: } else if (type == BP_VAR_IS) { retval = &EG(uninitialized_zval); } else { - zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(name)); - if (type == BP_VAR_RW) { + zend_error(E_WARNING, "Undefined %svariable $%s", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name)); + if (type == BP_VAR_RW && !EG(exception)) { ZVAL_NULL(retval); } else { retval = &EG(uninitialized_zval); @@ -9763,7 +9991,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYP } SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); } @@ -10143,41 +10371,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U } /* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_function *func; - zval *zfunc; - zval *object; - zend_class_entry *called_scope; - - func = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(func == NULL)) { - zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1); - ZEND_ASSERT(zfunc != NULL); - func = Z_FUNC_P(zfunc); - ZEND_ASSERT(func->type == ZEND_USER_FUNCTION); - CACHE_PTR(opline->extended_value, func); - } - - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) || - (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) { - object = NULL; - } else { - object = &EX(This); - } - } else { - called_scope = Z_CE(EX(This)); - object = NULL; - } - zend_create_closure(EX_VAR(opline->result.var), func, - EX(func)->op_array.scope, called_scope, object); - - ZEND_VM_NEXT_OPCODE(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -10323,7 +10516,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CONST_ while (1) { if (Z_TYPE_P(op1) == IS_ARRAY) { - count = zend_array_count(Z_ARRVAL_P(op1)); + count = zend_hash_num_elements(Z_ARRVAL_P(op1)); break; } else if (Z_TYPE_P(op1) == IS_OBJECT) { zend_object *zobj = Z_OBJ_P(op1); @@ -10780,6 +10973,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -11551,7 +11749,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -11659,7 +11857,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -14292,6 +14490,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA zend_vm_stack_free_call_frame(call); } + zend_destroy_static_vars(new_op_array); destroy_op_array(new_op_array); efree_size(new_op_array, sizeof(zend_op_array)); if (UNEXPECTED(EG(exception) != NULL)) { @@ -14421,10 +14620,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEN value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } ZEND_VM_NEXT_OPCODE(); } else { - zend_bool strict; + bool strict; if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { value = Z_REFVAL_P(value); @@ -14445,8 +14646,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEN zend_string *str; zval tmp; + if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { + zend_error(E_DEPRECATED, + "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + ZVAL_LONG(EX_VAR(opline->result.var), 0); + break; + } + ZVAL_COPY(&tmp, value); - if (zend_parse_arg_str_weak(&tmp, &str)) { + if (zend_parse_arg_str_weak(&tmp, &str, 1)) { ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); zval_ptr_dtor(&tmp); break; @@ -15186,6 +15397,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -15697,7 +15913,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -15805,7 +16021,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -15836,7 +16052,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_H { USE_OPLINE zval *expr; - zend_bool result; + bool result; SAVE_OPLINE(); expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); @@ -15848,7 +16064,7 @@ try_instanceof: if (IS_CONST == IS_CONST) { ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { CACHE_PTR(opline->extended_value, ce); } @@ -16606,6 +16822,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -17089,7 +17310,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); + value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -17197,7 +17418,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_T zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -17229,7 +17450,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HAN { USE_OPLINE zval *expr; - zend_bool result; + bool result; SAVE_OPLINE(); expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); @@ -17241,7 +17462,7 @@ try_instanceof: if (IS_VAR == IS_CONST) { ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { CACHE_PTR(opline->extended_value, ce); } @@ -17314,8 +17535,9 @@ fetch_this: } else if (type == BP_VAR_IS) { retval = &EG(uninitialized_zval); } else { - zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(name)); - if (type == BP_VAR_RW) { + zend_error(E_WARNING, "Undefined %svariable $%s", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name)); + if (type == BP_VAR_RW && !EG(exception)) { retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); } else { retval = &EG(uninitialized_zval); @@ -17333,8 +17555,9 @@ fetch_this: } else if (type == BP_VAR_IS) { retval = &EG(uninitialized_zval); } else { - zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(name)); - if (type == BP_VAR_RW) { + zend_error(E_WARNING, "Undefined %svariable $%s", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name)); + if (type == BP_VAR_RW && !EG(exception)) { ZVAL_NULL(retval); } else { retval = &EG(uninitialized_zval); @@ -17510,7 +17733,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_ { USE_OPLINE zval *expr; - zend_bool result; + bool result; SAVE_OPLINE(); expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); @@ -17522,7 +17745,7 @@ try_instanceof: if (IS_UNUSED == IS_CONST) { ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { CACHE_PTR(opline->extended_value, ce); } @@ -17562,7 +17785,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDL while (1) { if (Z_TYPE_P(op1) == IS_ARRAY) { - count = zend_array_count(Z_ARRVAL_P(op1)); + count = zend_hash_num_elements(Z_ARRVAL_P(op1)); break; } else if (Z_TYPE_P(op1) == IS_OBJECT) { zend_object *zobj = Z_OBJ_P(op1); @@ -17916,6 +18139,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -18399,7 +18627,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -18507,7 +18735,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_C zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -18784,6 +19012,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC } else { ZVAL_EMPTY_ARRAY(result); } + } else if (Z_OBJ_P(expr)->properties == NULL + && Z_OBJ_HT_P(expr)->get_properties_for == NULL + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + /* Optimized version without rebulding properties HashTable */ + ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST); if (obj_ht) { @@ -18871,7 +19104,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); if (UNEXPECTED(EG(exception))) { @@ -18964,7 +19197,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(Z ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_VAR) { @@ -19133,7 +19366,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HA { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); @@ -19148,7 +19381,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_CONST_HAN { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); @@ -19162,7 +19395,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONS { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); @@ -19584,33 +19817,69 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_TMP_VAR == IS_CONST); - } else if (opline->extended_value) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); + } + + if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { - result = NULL; + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + ZEND_VM_SMART_BRANCH(result, 0); } else { zend_string *key; - zval key_tmp, *val; + zval key_tmp; - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } + + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&key_tmp, key); if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(1, 1); } } ZEND_HASH_FOREACH_END(); } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(0, 1); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -19985,7 +20254,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HAND { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); @@ -20000,7 +20269,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_TMP_HANDL { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); @@ -20014,7 +20283,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_ { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); @@ -20029,7 +20298,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_VAR_HANDL { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); @@ -20117,7 +20386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN } SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); } @@ -20462,7 +20731,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLE { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); @@ -21358,6 +21627,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC } else { ZVAL_EMPTY_ARRAY(result); } + } else if (Z_OBJ_P(expr)->properties == NULL + && Z_OBJ_HT_P(expr)->get_properties_for == NULL + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + /* Optimized version without rebulding properties HashTable */ + ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST); if (obj_ht) { @@ -21446,7 +21720,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZE zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); if (UNEXPECTED(EG(exception))) { @@ -21539,7 +21813,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); if (IS_VAR == IS_VAR) { zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); @@ -21567,7 +21841,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(Z } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *array; @@ -21578,135 +21852,41 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE Bucket *p; array = EX_VAR(opline->op1.var); - SAVE_OPLINE(); - if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) { - fe_ht = Z_ARRVAL_P(array); - pos = Z_FE_POS_P(array); - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ -fe_fetch_r_exit: - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF)) { - if (UNEXPECTED(value_type == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - } else { - break; - } - } - p++; + if (UNEXPECTED(Z_TYPE_P(array) != IS_ARRAY)) { + ZEND_VM_TAIL_CALL(zend_fe_fetch_object_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + fe_ht = Z_ARRVAL_P(array); + pos = Z_FE_POS_P(array); + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - Z_FE_POS_P(array) = pos; - if (RETURN_VALUE_USED(opline)) { - if (!p->key) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); - } + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; } - } else { - zend_object_iterator *iter; - - ZEND_ASSERT(Z_TYPE_P(array) == IS_OBJECT); - if ((iter = zend_iterator_unwrap(array)) == NULL) { - /* plain object */ - - fe_ht = Z_OBJPROP_P(array); - pos = zend_hash_iterator_pos(Z_FE_ITER_P(array), fe_ht); - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - goto fe_fetch_r_exit; - } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF)) { - if (UNEXPECTED(value_type == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF) - && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) { - break; - } - } else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0) - || !p->key - || zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) { - break; - } - } - p++; - } - EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos; - if (RETURN_VALUE_USED(opline)) { - if (UNEXPECTED(!p->key)) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else if (ZSTR_VAL(p->key)[0]) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); - } else { - const char *class_name, *prop_name; - size_t prop_name_len; - zend_unmangle_property_name_ex( - p->key, &class_name, &prop_name, &prop_name_len); - ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); - } - } + p++; + } + Z_FE_POS_P(array) = pos; + if (RETURN_VALUE_USED(opline)) { + if (!p->key) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else { - if (EXPECTED(++iter->index > 0)) { - /* This could cause an endless loop if index becomes zero again. - * In case that ever happens we need an additional flag. */ - iter->funcs->move_forward(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) { - /* reached end of iteration */ - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - goto fe_fetch_r_exit; - } - } - value = iter->funcs->get_current_data(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (!value) { - /* failure in get_current_data */ - goto fe_fetch_r_exit; - } - if (RETURN_VALUE_USED(opline)) { - if (iter->funcs->get_current_key) { - iter->funcs->get_current_key(iter, EX_VAR(opline->result.var)); - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - } else { - ZVAL_LONG(EX_VAR(opline->result.var), iter->index); - } - } - value_type = Z_TYPE_INFO_P(value); + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); } } if (EXPECTED(opline->op2_type == IS_CV)) { zval *variable_ptr = EX_VAR(opline->op2.var); + SAVE_OPLINE(); zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { zval *res = EX_VAR(opline->op2.var); zend_refcounted *gc = Z_COUNTED_P(value); @@ -21715,8 +21895,8 @@ fe_fetch_r_exit: if (Z_TYPE_INFO_REFCOUNTED(value_type)) { GC_ADDREF(gc); } + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -21745,16 +21925,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); if (EXPECTED(value_type != IS_UNDEF)) { - if (UNEXPECTED(value_type == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - } else { - break; - } + break; } p++; } @@ -21823,15 +21996,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z } } } else { + const zend_object_iterator_funcs *funcs = iter->funcs; if (++iter->index > 0) { /* This could cause an endless loop if index becomes zero again. * In case that ever happens we need an additional flag. */ - iter->funcs->move_forward(iter); + funcs->move_forward(iter); if (UNEXPECTED(EG(exception) != NULL)) { UNDEF_RESULT(); HANDLE_EXCEPTION(); } - if (UNEXPECTED(iter->funcs->valid(iter) == FAILURE)) { + if (UNEXPECTED(funcs->valid(iter) == FAILURE)) { /* reached end of iteration */ if (UNEXPECTED(EG(exception) != NULL)) { UNDEF_RESULT(); @@ -21840,7 +22014,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z goto fe_fetch_w_exit; } } - value = iter->funcs->get_current_data(iter); + value = funcs->get_current_data(iter); if (UNEXPECTED(EG(exception) != NULL)) { UNDEF_RESULT(); HANDLE_EXCEPTION(); @@ -21850,8 +22024,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z goto fe_fetch_w_exit; } if (RETURN_VALUE_USED(opline)) { - if (iter->funcs->get_current_key) { - iter->funcs->get_current_key(iter, EX_VAR(opline->result.var)); + if (funcs->get_current_key) { + funcs->get_current_key(iter, EX_VAR(opline->result.var)); if (UNEXPECTED(EG(exception) != NULL)) { UNDEF_RESULT(); HANDLE_EXCEPTION(); @@ -22044,7 +22218,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HA { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -22059,7 +22233,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_VAR_CONST_HAN { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -22073,7 +22247,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONS { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -24194,7 +24368,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ } } - zv = zend_hash_find_ex(&ce->constants_table, Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); + zv = zend_hash_find_ex(CE_CONSTANTS_TABLE(ce), Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); if (EXPECTED(zv != NULL)) { c = Z_PTR_P(zv); scope = EX(func)->op_array.scope; @@ -24370,11 +24544,8 @@ offset_again: } } str_index_dim: - if (ht == &EG(symbol_table)) { - zend_delete_global_variable(key); - } else { - zend_hash_del(ht, key); - } + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_dim: @@ -24395,6 +24566,7 @@ num_index_dim: hval = 1; goto num_index_dim; } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index_dim; } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { @@ -24606,33 +24778,69 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); + op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_VAR == IS_CONST); - } else if (opline->extended_value) { + if (IS_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); + } + + if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { - result = NULL; + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + if ((IS_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + ZEND_VM_SMART_BRANCH(result, 0); } else { zend_string *key; - zval key_tmp, *val; + zval key_tmp; - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if ((IS_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } + + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&key_tmp, key); if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(1, 1); } } ZEND_HASH_FOREACH_END(); } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(0, 1); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -26523,11 +26731,8 @@ offset_again: } } str_index_dim: - if (ht == &EG(symbol_table)) { - zend_delete_global_variable(key); - } else { - zend_hash_del(ht, key); - } + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_dim: @@ -26548,6 +26753,7 @@ num_index_dim: hval = 1; goto num_index_dim; } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index_dim; } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { @@ -26759,7 +26965,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HAND { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -26774,7 +26980,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_VAR_TMP_HANDL { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -26788,7 +26994,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_ { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -26843,7 +27049,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HAND { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -26858,7 +27064,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_VAR_VAR_HANDL { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -26872,7 +27078,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_ { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -27732,7 +27938,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN } SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); } @@ -28570,7 +28776,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_STRICT_SPEC_VAR_CV_HANDLE { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); @@ -30537,11 +30743,8 @@ offset_again: } } str_index_dim: - if (ht == &EG(symbol_table)) { - zend_delete_global_variable(key); - } else { - zend_hash_del(ht, key); - } + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_dim: @@ -30562,6 +30765,7 @@ num_index_dim: hval = 1; goto num_index_dim; } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index_dim; } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { @@ -30790,16 +30994,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_ pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); if (EXPECTED(value_type != IS_UNDEF)) { - if (UNEXPECTED(value_type == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - } else { - break; - } + break; } p++; } @@ -30842,16 +31039,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_ pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); if (EXPECTED(value_type != IS_UNDEF)) { - if (UNEXPECTED(value_type == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - } else { - break; - } + break; } p++; } @@ -31327,6 +31517,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -32637,7 +32832,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS } } - zv = zend_hash_find_ex(&ce->constants_table, Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); + zv = zend_hash_find_ex(CE_CONSTANTS_TABLE(ce), Z_STR_P(RT_CONSTANT(opline, opline->op2)), 1); if (EXPECTED(zv != NULL)) { c = Z_PTR_P(zv); scope = EX(func)->op_array.scope; @@ -33240,6 +33435,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -34932,7 +35132,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED } SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); } @@ -35247,6 +35447,16 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_THIS_SPEC_UN } } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + /* For symbol tables we need to deal with exactly the same problems as for property tables. */ + ZVAL_ARR(EX_VAR(opline->result.var), + zend_proptable_to_symtable(&EG(symbol_table), /* always_duplicate */ 1)); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -35729,6 +35939,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -38019,6 +38234,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO } else { ZVAL_EMPTY_ARRAY(result); } + } else if (Z_OBJ_P(expr)->properties == NULL + && Z_OBJ_HT_P(expr)->get_properties_for == NULL + && Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) { + /* Optimized version without rebulding properties HashTable */ + ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr))); } else { HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST); if (obj_ht) { @@ -38111,6 +38331,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE zend_vm_stack_free_call_frame(call); } + zend_destroy_static_vars(new_op_array); destroy_op_array(new_op_array); efree_size(new_op_array, sizeof(zend_op_array)); if (UNEXPECTED(EG(exception) != NULL)) { @@ -38174,7 +38395,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEN ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); @@ -38266,7 +38487,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); if (IS_CV == IS_VAR) { @@ -38530,10 +38751,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP value = EX_VAR(opline->op1.var); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } ZEND_VM_NEXT_OPCODE(); } else { - zend_bool strict; + bool strict; if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { value = Z_REFVAL_P(value); @@ -38554,8 +38777,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OP zend_string *str; zval tmp; + if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { + zend_error(E_DEPRECATED, + "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + ZVAL_LONG(EX_VAR(opline->result.var), 0); + break; + } + ZVAL_COPY(&tmp, value); - if (zend_parse_arg_str_weak(&tmp, &str)) { + if (zend_parse_arg_str_weak(&tmp, &str, 1)) { ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); zval_ptr_dtor(&tmp); break; @@ -38938,7 +39171,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HAN { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -38953,7 +39186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -39898,6 +40131,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -41808,11 +42046,8 @@ offset_again: } } str_index_dim: - if (ht == &EG(symbol_table)) { - zend_delete_global_variable(key); - } else { - zend_hash_del(ht, key); - } + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_dim: @@ -41833,6 +42068,7 @@ num_index_dim: hval = 1; goto num_index_dim; } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index_dim; } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { @@ -41940,7 +42176,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, IS_CONST == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -42048,7 +42284,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -42079,7 +42315,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDL { USE_OPLINE zval *expr; - zend_bool result; + bool result; SAVE_OPLINE(); expr = EX_VAR(opline->op1.var); @@ -42091,7 +42327,7 @@ try_instanceof: if (IS_CONST == IS_CONST) { ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { CACHE_PTR(opline->extended_value, ce); } @@ -42331,33 +42567,69 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CV == IS_CONST); - } else if (opline->extended_value) { + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); + } + + if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { - result = NULL; + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + + ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + + ZEND_VM_SMART_BRANCH(result, 0); + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + ZEND_VM_SMART_BRANCH(result, 0); } else { zend_string *key; - zval key_tmp, *val; + zval key_tmp; - result = NULL; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + + ZEND_VM_SMART_BRANCH(result, 0); + } + } + + SAVE_OPLINE(); + ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&key_tmp, key); if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; + + ZEND_VM_SMART_BRANCH(1, 1); } } ZEND_HASH_FOREACH_END(); } - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(0, 1); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -42367,7 +42639,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_C /* (Infinite recursion when comparing arrays is an uncatchable fatal error) */ USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); @@ -42380,7 +42652,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_ { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); @@ -43530,6 +43802,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -45254,11 +45531,8 @@ offset_again: } } str_index_dim: - if (ht == &EG(symbol_table)) { - zend_delete_global_variable(key); - } else { - zend_hash_del(ht, key); - } + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_dim: @@ -45279,6 +45553,7 @@ num_index_dim: hval = 1; goto num_index_dim; } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index_dim; } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { @@ -45388,7 +45663,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); + value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -45496,7 +45771,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVA zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -45652,7 +45927,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDL { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -45667,7 +45942,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_H { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -45722,7 +45997,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDL { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -45737,7 +46012,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_H { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -45827,7 +46102,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER { USE_OPLINE zval *expr; - zend_bool result; + bool result; SAVE_OPLINE(); expr = EX_VAR(opline->op1.var); @@ -45839,7 +46114,7 @@ try_instanceof: if (IS_VAR == IS_CONST) { ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { CACHE_PTR(opline->extended_value, ce); } @@ -45996,8 +46271,9 @@ fetch_this: } else if (type == BP_VAR_IS) { retval = &EG(uninitialized_zval); } else { - zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(name)); - if (type == BP_VAR_RW) { + zend_error(E_WARNING, "Undefined %svariable $%s", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name)); + if (type == BP_VAR_RW && !EG(exception)) { retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); } else { retval = &EG(uninitialized_zval); @@ -46015,8 +46291,9 @@ fetch_this: } else if (type == BP_VAR_IS) { retval = &EG(uninitialized_zval); } else { - zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(name)); - if (type == BP_VAR_RW) { + zend_error(E_WARNING, "Undefined %svariable $%s", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name)); + if (type == BP_VAR_RW && !EG(exception)) { ZVAL_NULL(retval); } else { retval = &EG(uninitialized_zval); @@ -46634,7 +46911,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU } SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, cache_slot, NULL, 1, 0))) { zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); } @@ -47119,7 +47396,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_UNUSED_HAND { USE_OPLINE zval *expr; - zend_bool result; + bool result; SAVE_OPLINE(); expr = EX_VAR(opline->op1.var); @@ -47131,7 +47408,7 @@ try_instanceof: if (IS_UNUSED == IS_CONST) { ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); if (EXPECTED(ce)) { CACHE_PTR(opline->extended_value, ce); } @@ -47294,16 +47571,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr); if (!ht) { - ZEND_ASSERT(EX(func)->op_array.fn_flags & (ZEND_ACC_IMMUTABLE|ZEND_ACC_PRELOADED)); ht = zend_array_dup(EX(func)->op_array.static_variables); ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht); - } else if (GC_REFCOUNT(ht) > 1) { - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_DELREF(ht); - } - ht = zend_array_dup(ht); - ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht); } + ZEND_ASSERT(GC_REFCOUNT(ht) == 1); value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT))); @@ -47394,7 +47665,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(Z while (1) { if (Z_TYPE_P(op1) == IS_ARRAY) { - count = zend_array_count(Z_ARRVAL_P(op1)); + count = zend_hash_num_elements(Z_ARRVAL_P(op1)); break; } else if (Z_TYPE_P(op1) == IS_OBJECT) { zend_object *zobj = Z_OBJ_P(op1); @@ -47619,7 +47890,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLE { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -47634,7 +47905,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HA { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); @@ -48579,6 +48850,11 @@ fetch_obj_r_fast_copy: } retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) { + zend_verify_internal_read_property_type(zobj, name, retval); + } +#endif if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); @@ -50377,11 +50653,8 @@ offset_again: } } str_index_dim: - if (ht == &EG(symbol_table)) { - zend_delete_global_variable(key); - } else { - zend_hash_del(ht, key); - } + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_dim: @@ -50402,6 +50675,7 @@ num_index_dim: hval = 1; goto num_index_dim; } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index_dim; } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { @@ -50509,7 +50783,7 @@ isset_again: goto num_index_prop; } } - value = zend_hash_find_ex_ind(ht, str, IS_CV == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: @@ -50617,7 +50891,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HA zval *key, *subject; HashTable *ht; - zend_bool result; + bool result; SAVE_OPLINE(); @@ -50774,7 +51048,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_C /* (Infinite recursion when comparing arrays is an uncatchable fatal error) */ USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; op1 = EX_VAR(opline->op1.var); op2 = EX_VAR(opline->op2.var); @@ -50787,7 +51061,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_ { USE_OPLINE zval *op1, *op2; - zend_bool result; + bool result; op1 = EX_VAR(opline->op1.var); op2 = EX_VAR(opline->op2.var); @@ -53148,7 +53422,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MAKE_REF_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_DECLARE_FUNCTION_SPEC_LABEL, - (void*)&&ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_LABEL, + (void*)&&ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_LABEL, (void*)&&ZEND_DECLARE_CONST_SPEC_CONST_CONST_LABEL, (void*)&&ZEND_DECLARE_CLASS_SPEC_CONST_LABEL, (void*)&&ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_LABEL, @@ -53405,6 +53679,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMP_NULL_SPEC_TMPVARCV_LABEL, (void*)&&ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_LABEL, + (void*)&&ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL, (void*)&&ZEND_JMP_FORWARD_SPEC_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -54458,6 +54733,7 @@ zend_leave_helper_SPEC_LABEL: ZEND_VM_LEAVE(); } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) { zend_detach_symbol_table(execute_data); + zend_destroy_static_vars(&EX(func)->op_array); destroy_op_array(&EX(func)->op_array); efree_size(EX(func), sizeof(zend_op_array)); #ifdef ZEND_PREFER_RELOAD @@ -54966,6 +55242,10 @@ zend_leave_helper_SPEC_LABEL: VM_TRACE(ZEND_DECLARE_CLASS_SPEC_CONST) ZEND_DECLARE_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST): + VM_TRACE(ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST) + ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_FROM_SPEC_CONST): VM_TRACE(ZEND_YIELD_FROM_SPEC_CONST) ZEND_YIELD_FROM_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -55442,10 +55722,6 @@ zend_leave_helper_SPEC_LABEL: VM_TRACE(ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED): - VM_TRACE(ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED) - ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_SPEC_CONST_UNUSED): VM_TRACE(ZEND_YIELD_SPEC_CONST_UNUSED) ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -57604,6 +57880,10 @@ zend_leave_helper_SPEC_LABEL: VM_TRACE(ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED) ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED): + VM_TRACE(ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) + ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + HYBRID_BREAK(); HYBRID_CASE(ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED): VM_TRACE(ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED) ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -61171,7 +61451,7 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLER, ZEND_DECLARE_FUNCTION_SPEC_HANDLER, - ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER, + ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_HANDLER, ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER, ZEND_DECLARE_CLASS_SPEC_CONST_HANDLER, ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER, @@ -61428,6 +61708,7 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_JMP_NULL_SPEC_TMPVARCV_HANDLER, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER, + ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER, ZEND_RECV_NOTYPE_SPEC_HANDLER, ZEND_JMP_FORWARD_SPEC_HANDLER, ZEND_NULL_HANDLER, @@ -62534,7 +62815,8 @@ void zend_vm_init(void) 2536 | SPEC_RULE_OP1, 2541 | SPEC_RULE_OP1, 2546, - 3450 + 2547, + 3451 }; #if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) zend_opcode_handler_funcs = labels; @@ -62707,7 +62989,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2549 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2550 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -62715,7 +62997,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2574 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2575 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -62723,7 +63005,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2599 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2600 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -62734,17 +63016,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2624 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2625 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2649 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2650 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2674 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2675 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -62755,17 +63037,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2699 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2700 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2724 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2725 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2749 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2750 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -62776,14 +63058,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2774 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2775 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2849 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2850 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3074 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3075 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -62794,14 +63076,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2924 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2925 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2999 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3000 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3079 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3080 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -62812,12 +63094,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2774 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2775 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2849 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2850 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -62828,12 +63110,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2924 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2925 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2999 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3000 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -62841,12 +63123,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3084 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3085 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3159 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3160 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -62854,74 +63136,74 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3234 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3235 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3309 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3310 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3396 | SPEC_RULE_OP1; + spec = 3397 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3401 | SPEC_RULE_OP1; + spec = 3402 | SPEC_RULE_OP1; } else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { - spec = 3406 | SPEC_RULE_OP1; + spec = 3407 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3384 | SPEC_RULE_RETVAL; + spec = 3385 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3386 | SPEC_RULE_RETVAL; + spec = 3387 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3388 | SPEC_RULE_RETVAL; + spec = 3389 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3390 | SPEC_RULE_RETVAL; + spec = 3391 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3392; - } else if (op1_info == MAY_BE_LONG) { spec = 3393; + } else if (op1_info == MAY_BE_LONG) { + spec = 3394; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3394; - } else if (op1_info == MAY_BE_LONG) { spec = 3395; + } else if (op1_info == MAY_BE_LONG) { + spec = 3396; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2548; + spec = 2549; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2547; + spec = 2548; } 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 = 3446; + spec = 3447; } 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 = 3441 | SPEC_RULE_OP1; + spec = 3442 | 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 = 3448 | SPEC_RULE_RETVAL; + spec = 3449 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -62929,17 +63211,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3411 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3412 | 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 = 3447; + spec = 3448; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3436 | SPEC_RULE_OP1; + spec = 3437 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: |