ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data;
- zval *object, *property, *value, tmp;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr;
+ zval *value, *container, *dim;
SAVE_OPLINE();
- object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
-
- if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
-
- property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
- value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
- do {
- if (Z_ISREF_P(object)) {
- object = Z_REFVAL_P(object);
- if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
- break;
- }
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+ SEPARATE_ARRAY(container);
+assign_dim_op_new_array:
+ dim = RT_CONSTANT(opline, opline->op2);
+ if (IS_CONST == IS_UNUSED) {
+ var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
+ if (UNEXPECTED(!var_ptr)) {
+ zend_cannot_add_element();
+ goto assign_dim_op_ret_null;
}
- if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE ||
- (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
- zend_object *obj;
-
- zval_ptr_dtor(object);
- object_init(object);
- Z_ADDREF_P(object);
- obj = Z_OBJ_P(object);
- zend_error(E_WARNING, "Creating default object from empty value");
- if (GC_REFCOUNT(obj) == 1) {
- /* the enclosing container was deleted, obj is unreferenced */
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- zval_ptr_dtor_nogc(free_op_data);
- OBJ_RELEASE(obj);
- goto exit_assign_obj;
- }
- Z_DELREF_P(object);
+ } else {
+ if (IS_CONST == IS_CONST) {
+ var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
} else {
- if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) {
- zend_string *property_name = zval_get_string(property);
- zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- zval_ptr_dtor_nogc(free_op_data);
- goto exit_assign_obj;
+ var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
}
- } while (0);
- }
+ if (UNEXPECTED(!var_ptr)) {
+ goto assign_dim_op_ret_null;
+ }
+ ZVAL_DEREF(var_ptr);
+ }
- if (IS_CV == IS_CONST &&
- EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) {
- uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*));
- zend_object *zobj = Z_OBJ_P(object);
- zval *property_val;
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
- if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
- property_val = OBJ_PROP(zobj, prop_offset);
- if (Z_TYPE_P(property_val) != IS_UNDEF) {
-fast_assign_obj:
- value = zend_assign_to_variable(property_val, value, IS_VAR);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), value);
- }
- goto exit_assign_obj;
- }
- } else {
- if (EXPECTED(zobj->properties != NULL)) {
- if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
- if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
- GC_REFCOUNT(zobj->properties)--;
- }
- zobj->properties = zend_array_dup(zobj->properties);
- }
- property_val = zend_hash_find(zobj->properties, Z_STR_P(property));
- if (property_val) {
- goto fast_assign_obj;
- }
+ binary_op(var_ptr, var_ptr, value);
+
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
+ } else {
+ if (EXPECTED(Z_ISREF_P(container))) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto assign_dim_op_array;
}
+ } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+ container = GET_OP1_UNDEF_CV(container, BP_VAR_RW);
+assign_dim_op_convert_to_array:
+ ZVAL_ARR(container, zend_new_array(8));
+ goto assign_dim_op_new_array;
+ }
- if (!zobj->ce->__set) {
+ dim = RT_CONSTANT(opline, opline->op2);
- if (EXPECTED(zobj->properties == NULL)) {
- rebuild_object_properties(zobj);
- }
- if (IS_VAR == IS_CONST) {
- if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) {
- Z_ADDREF_P(value);
- }
- } else if (IS_VAR != IS_TMP_VAR) {
- if (Z_ISREF_P(value)) {
- if (IS_VAR == IS_VAR) {
- zend_reference *ref = Z_REF_P(value);
- if (--GC_REFCOUNT(ref) == 0) {
- ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value));
- efree_size(ref, sizeof(zend_reference));
- value = &tmp;
- } else {
- value = Z_REFVAL_P(value);
- if (Z_REFCOUNTED_P(value)) {
- Z_ADDREF_P(value);
- }
- }
- } else {
- value = Z_REFVAL_P(value);
- if (Z_REFCOUNTED_P(value)) {
- Z_ADDREF_P(value);
- }
- }
- } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(value)) {
- Z_ADDREF_P(value);
+ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+ zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC);
+ } else {
+ if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ if (IS_CONST == IS_UNUSED) {
+ zend_use_new_element_for_string();
+ } else {
+ zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
- zend_wrong_string_offset(EXECUTE_DATA_C);
++ if (EXPECTED(EG(exception) == NULL)) {
++ zend_wrong_string_offset(EXECUTE_DATA_C);
+ }
}
- zend_hash_add_new(zobj->properties, Z_STR_P(property), value);
+ UNDEF_RESULT();
+ } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+ goto assign_dim_op_convert_to_array;
+ } else {
+ if (UNEXPECTED(IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) {
+ zend_use_scalar_as_array();
+ }
+assign_dim_op_ret_null:
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), value);
+ ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto exit_assign_obj;
}
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
}
}
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data;
- zval *object, *property, *value, tmp;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr;
+ zval *value, *container, *dim;
SAVE_OPLINE();
- object = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+ SEPARATE_ARRAY(container);
+assign_dim_op_new_array:
+ dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
+ if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+ var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
+ if (UNEXPECTED(!var_ptr)) {
+ zend_cannot_add_element();
+ goto assign_dim_op_ret_null;
+ }
+ } else {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ } else {
+ var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ }
+ if (UNEXPECTED(!var_ptr)) {
+ goto assign_dim_op_ret_null;
+ }
+ ZVAL_DEREF(var_ptr);
+ }
- property = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
- value = _get_zval_ptr_var((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC);
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
- if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
- do {
- if (Z_ISREF_P(object)) {
- object = Z_REFVAL_P(object);
- if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
- break;
- }
+ binary_op(var_ptr, var_ptr, value);
+
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
+ } else {
+ if (EXPECTED(Z_ISREF_P(container))) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto assign_dim_op_array;
}
- if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE ||
- (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
- zend_object *obj;
+ } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+ container = GET_OP1_UNDEF_CV(container, BP_VAR_RW);
+assign_dim_op_convert_to_array:
+ ZVAL_ARR(container, zend_new_array(8));
+ goto assign_dim_op_new_array;
+ }
+
+ dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
- zval_ptr_dtor(object);
- object_init(object);
- Z_ADDREF_P(object);
- obj = Z_OBJ_P(object);
- zend_error(E_WARNING, "Creating default object from empty value");
- if (GC_REFCOUNT(obj) == 1) {
- /* the enclosing container was deleted, obj is unreferenced */
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+ zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC);
+ } else {
+ if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+ zend_use_new_element_for_string();
+ } else {
+ zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
- zend_wrong_string_offset(EXECUTE_DATA_C);
++ if (EXPECTED(EG(exception) == NULL)) {
++ zend_wrong_string_offset(EXECUTE_DATA_C);
+ }
- zval_ptr_dtor_nogc(free_op_data);
- OBJ_RELEASE(obj);
- goto exit_assign_obj;
}
- Z_DELREF_P(object);
+ UNDEF_RESULT();
+ } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+ goto assign_dim_op_convert_to_array;
} else {
- if (IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) {
- zend_string *property_name = zval_get_string(property);
- zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
+ if (UNEXPECTED(IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) {
+ zend_use_scalar_as_array();
}
+assign_dim_op_ret_null:
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
{
USE_OPLINE
- SAVE_OPLINE();
- if (IS_UNUSED != IS_UNUSED) {
-
- zval *ptr = NULL;
-
- do {
- if (Z_TYPE_P(ptr) == IS_LONG) {
- EG(exit_status) = Z_LVAL_P(ptr);
- } else {
- if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) {
- ptr = Z_REFVAL_P(ptr);
- if (Z_TYPE_P(ptr) == IS_LONG) {
- EG(exit_status) = Z_LVAL_P(ptr);
- break;
- }
- }
- zend_print_variable(ptr);
- }
- } while (0);
+ zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+ SAVE_OPLINE();
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+ ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
}
- zend_bailout();
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
-}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
-{
- USE_OPLINE
- zend_free_op free_op_data1;
- zval *object;
- zval *property;
- zval *value;
- zval *zptr;
+ /* Destroy the previously yielded value */
+ zval_ptr_dtor(&generator->value);
- SAVE_OPLINE();
- object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C);
+ /* Destroy the previously yielded key */
+ zval_ptr_dtor(&generator->key);
- if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
- property = EX_CONSTANT(opline->op2);
+ if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR & (IS_CONST|IS_TMP_VAR)) {
+ zval *value;
- do {
- value = get_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
- ZVAL_DEREF(object);
- if (UNEXPECTED(!make_real_object(object))) {
- zend_string *property_name = zval_get_string(property);
- zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (IS_VAR == IS_CONST) {
+ if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+ Z_ADDREF(generator->value);
+ }
}
- break;
+ } else {
+ zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !Z_ISREF_P(value_ptr)))) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+ ZVAL_COPY(&generator->value, value_ptr);
+ } else {
+ if (Z_ISREF_P(value_ptr)) {
+ Z_ADDREF_P(value_ptr);
+ } else {
+ ZVAL_MAKE_REF_EX(value_ptr, 2);
+ }
+ ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
+ }
+
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
}
- }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- /* here we are sure we are dealing with an object */
- if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
- && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
- if (UNEXPECTED(Z_ISERROR_P(zptr))) {
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST) {
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+ Z_ADDREF(generator->value);
}
+ } else if (IS_VAR == IS_TMP_VAR) {
+ ZVAL_COPY_VALUE(&generator->value, value);
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+ zval_ptr_dtor_nogc(free_op1);
} else {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- binary_op(zptr, zptr, value);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (IS_VAR == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
}
- } else {
- zend_assign_op_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), value, binary_op, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
}
- } while (0);
-
- FREE_OP(free_op_data1);
+ } else {
+ /* If no value was specified yield null */
+ ZVAL_NULL(&generator->value);
+ }
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
- /* assign_obj has two opcodes! */
- ZEND_VM_NEXT_OPCODE_EX(1, 2);
-}
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST) {
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) {
+ Z_ADDREF(generator->key);
+ }
+ } else if (IS_TMP_VAR == IS_TMP_VAR) {
+ ZVAL_COPY_VALUE(&generator->key, key);
+ } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
-static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
-{
-#if 1 && IS_CONST == IS_UNUSED
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-#else
-# if 0 || IS_UNUSED != IS_UNUSED
- USE_OPLINE
+ } else {
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (IS_TMP_VAR == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ }
+ }
- if (EXPECTED(0)) {
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL(generator->key);
+ }
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+ ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
}
- if (EXPECTED(0)) {
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
+ } else {
+ generator->send_target = NULL;
}
-# endif
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-#endif
-}
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-}
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ ZEND_VM_RETURN();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-}
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
+ int result;
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ SAVE_OPLINE();
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
+ result = fast_is_identical_function(op1, op2);
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_SMART_BRANCH(result, 1);
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-}
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *op1, *op2;
+ int result;
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ SAVE_OPLINE();
+ op1 = _get_zval_ptr_var_deref(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ op2 = _get_zval_ptr_var_deref(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
+ result = fast_is_not_identical_function(op1, op2);
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_SMART_BRANCH(result, 1);
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-}
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *value;
+ zval *variable_ptr;
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-}
+ SAVE_OPLINE();
+ value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
+ variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-}
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) {
+ zval_ptr_dtor_nogc(free_op2);
+ if (UNEXPECTED(0)) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ } else {
+ value = zend_assign_to_variable(variable_ptr, value, IS_VAR);
+ if (UNEXPECTED(0)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
+ }
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ /* zend_assign_to_variable() always takes care of op2, never free it! */
+ }
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-}
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *value;
+ zval *variable_ptr;
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_UNUSED_CONST_OBJ_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_UNUSED_CONST_OBJ(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ SAVE_OPLINE();
+ value = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
+ variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) {
+ zval_ptr_dtor_nogc(free_op2);
+ if (UNEXPECTED(1)) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ } else {
+ value = zend_assign_to_variable(variable_ptr, value, IS_VAR);
+ if (UNEXPECTED(1)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
+ }
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ /* zend_assign_to_variable() always takes care of op2, never free it! */
+ }
+
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
-
- zval *object;
- zval *property;
- zval *zptr;
+ zend_free_op free_op1, free_op2;
+ zval *variable_ptr;
+ zval *value_ptr;
SAVE_OPLINE();
- object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C);
+ value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
+ variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(variable_ptr))) {
+ variable_ptr = &EG(uninitialized_zval);
+ } else if (IS_VAR == IS_VAR &&
+ UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
- property = EX_CONSTANT(opline->op2);
+ zend_throw_error(NULL, "Cannot assign by reference to overloaded object");
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);};
+ UNDEF_RESULT();
+ HANDLE_EXCEPTION();
+ } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(value_ptr))) {
+ variable_ptr = &EG(uninitialized_zval);
+ } else if (IS_VAR == IS_VAR &&
+ opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ UNEXPECTED(!Z_ISREF_P(value_ptr))) {
- do {
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
- ZVAL_DEREF(object);
- if (UNEXPECTED(!make_real_object(object))) {
- zend_string *property_name = zval_get_string(property);
- zend_error(E_WARNING, "Attempt to increment/decrement property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- break;
- }
+ if (UNEXPECTED(!zend_wrong_assign_to_variable_reference(variable_ptr, value_ptr, IS_VAR OPLINE_CC EXECUTE_DATA_CC))) {
+ if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);};
+ UNDEF_RESULT();
+ HANDLE_EXCEPTION();
}
- /* here we are sure we are dealing with an object */
- if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
- && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
- if (UNEXPECTED(Z_ISERROR_P(zptr))) {
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- }
- } else {
- if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
- if (inc) {
- fast_long_increment_function(zptr);
- } else {
- fast_long_decrement_function(zptr);
+ /* op2 freed by assign_to_variable */
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_assign_to_variable_reference(variable_ptr, value_ptr);
+ }
+
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr);
+ }
+
+ if (UNEXPECTED(free_op2)) {zval_ptr_dtor_nogc(free_op2);};
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
+
+ SAVE_OPLINE();
+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+ ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
+ }
+
+ /* Destroy the previously yielded value */
+ zval_ptr_dtor(&generator->value);
+
+ /* Destroy the previously yielded key */
+ zval_ptr_dtor(&generator->key);
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR & (IS_CONST|IS_TMP_VAR)) {
+ zval *value;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (IS_VAR == IS_CONST) {
+ if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+ Z_ADDREF(generator->value);
}
- } else {
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ }
+ } else {
+ zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- if (inc) {
- increment_function(zptr);
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !Z_ISREF_P(value_ptr)))) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+ ZVAL_COPY(&generator->value, value_ptr);
+ } else {
+ if (Z_ISREF_P(value_ptr)) {
+ Z_ADDREF_P(value_ptr);
} else {
- decrement_function(zptr);
+ ZVAL_MAKE_REF_EX(value_ptr, 2);
}
+ ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST) {
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) {
+ Z_ADDREF(generator->value);
+ }
+ } else if (IS_VAR == IS_TMP_VAR) {
+ ZVAL_COPY_VALUE(&generator->value, value);
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) {
+ ZVAL_COPY(&generator->value, Z_REFVAL_P(value));
+ zval_ptr_dtor_nogc(free_op1);
+ } else {
+ ZVAL_COPY_VALUE(&generator->value, value);
+ if (IS_VAR == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
}
+ }
+ } else {
+ /* If no value was specified yield null */
+ ZVAL_NULL(&generator->value);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST) {
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->key))) {
+ Z_ADDREF(generator->key);
+ }
+ } else if (IS_VAR == IS_TMP_VAR) {
+ ZVAL_COPY_VALUE(&generator->key, key);
+ } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(key)) {
+ ZVAL_COPY(&generator->key, Z_REFVAL_P(key));
+ zval_ptr_dtor_nogc(free_op2);
} else {
- zend_pre_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL));
+ ZVAL_COPY_VALUE(&generator->key, key);
+ if (IS_VAR == IS_CV) {
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ }
}
- } while (0);
+ if (Z_TYPE(generator->key) == IS_LONG
+ && Z_LVAL(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL(generator->key);
+ }
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+ ZVAL_LONG(&generator->key, generator->largest_used_integer_key);
+ }
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = EX_VAR(opline->result.var);
+ ZVAL_NULL(generator->send_target);
+ } else {
+ generator->send_target = NULL;
+ }
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
-}
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- ZEND_VM_TAIL_CALL(zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(int inc ZEND_OPCODE_HANDLER_ARGS_DC)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
-
- zval *object;
- zval *property;
- zval *zptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr;
+ zval *value, *container, *dim;
SAVE_OPLINE();
- object = _get_obj_zval_ptr_unused(EXECUTE_DATA_C);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+ SEPARATE_ARRAY(container);
+assign_dim_op_new_array:
+ dim = NULL;
+ if (IS_UNUSED == IS_UNUSED) {
+ var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
+ if (UNEXPECTED(!var_ptr)) {
+ zend_cannot_add_element();
+ goto assign_dim_op_ret_null;
+ }
+ } else {
+ if (IS_UNUSED == IS_CONST) {
+ var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ } else {
+ var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ }
+ if (UNEXPECTED(!var_ptr)) {
+ goto assign_dim_op_ret_null;
+ }
+ ZVAL_DEREF(var_ptr);
+ }
- property = EX_CONSTANT(opline->op2);
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
- do {
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
- ZVAL_DEREF(object);
- if (UNEXPECTED(!make_real_object(object))) {
- zend_string *property_name = zval_get_string(property);
- zend_error(E_WARNING, "Attempt to increment/decrement property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
- ZVAL_NULL(EX_VAR(opline->result.var));
- break;
+ binary_op(var_ptr, var_ptr, value);
+
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
+ } else {
+ if (EXPECTED(Z_ISREF_P(container))) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto assign_dim_op_array;
}
+ } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+ container = GET_OP1_UNDEF_CV(container, BP_VAR_RW);
+assign_dim_op_convert_to_array:
+ ZVAL_ARR(container, zend_new_array(8));
+ goto assign_dim_op_new_array;
}
- /* here we are sure we are dealing with an object */
+ dim = NULL;
- if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
- && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) {
- if (UNEXPECTED(Z_ISERROR_P(zptr))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- } else {
- if (EXPECTED(Z_TYPE_P(zptr) == IS_LONG)) {
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- if (inc) {
- fast_long_increment_function(zptr);
- } else {
- fast_long_decrement_function(zptr);
- }
+ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+ zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC);
+ } else {
+ if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ if (IS_UNUSED == IS_UNUSED) {
+ zend_use_new_element_for_string();
} else {
- ZVAL_DEREF(zptr);
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr);
- zval_opt_copy_ctor(zptr);
- if (inc) {
- increment_function(zptr);
- } else {
- decrement_function(zptr);
+ zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
- zend_wrong_string_offset(EXECUTE_DATA_C);
++ if (EXPECTED(EG(exception) == NULL)) {
++ zend_wrong_string_offset(EXECUTE_DATA_C);
+ }
}
+ UNDEF_RESULT();
+ } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+ goto assign_dim_op_convert_to_array;
+ } else {
+ if (UNEXPECTED(IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) {
+ zend_use_scalar_as_array();
+ }
+assign_dim_op_ret_null:
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
}
- } else {
- zend_post_incdec_overloaded_property(object, property, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), inc, EX_VAR(opline->result.var));
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
}
- } while (0);
-
+ }
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
- ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_CONST(1 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+#if 1 && IS_UNUSED == IS_UNUSED
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+#else
+# if 0 || IS_VAR != IS_UNUSED
+# if 0
+ /* opline->extended_value checks are specialized, don't need opline */
+ USE_OPLINE
+# endif
+
+ if (EXPECTED(0)) {
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_simple_helper_SPEC_VAR_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ }
+ if (EXPECTED(1)) {
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ }
+# endif
+
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(binary_op ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+#endif
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_ADD_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- ZEND_VM_TAIL_CALL(zend_post_incdec_property_helper_SPEC_UNUSED_CONST(0 ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(add_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SUB_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- USE_OPLINE
-
- zval *container;
-
- zval *offset;
-
- SAVE_OPLINE();
- container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C);
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(sub_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MUL_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(mul_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- offset = EX_CONSTANT(opline->op2);
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIV_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(div_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- if (IS_UNUSED == IS_CONST ||
- (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
- if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
- goto fetch_obj_r_no_object;
- }
- } else {
- goto fetch_obj_r_no_object;
- }
- }
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_MOD_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(mod_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- /* here we are sure we are dealing with an object */
- do {
- zend_object *zobj = Z_OBJ_P(container);
- zval *retval;
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SL_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(shift_left_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- if (IS_CONST == IS_CONST &&
- EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
- uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*));
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_SR_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(shift_right_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
- retval = OBJ_PROP(zobj, prop_offset);
- if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) {
- ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval);
- break;
- }
- } else if (EXPECTED(zobj->properties != NULL)) {
- retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
- if (EXPECTED(retval)) {
- ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval);
- break;
- }
- }
- }
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_CONCAT_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(concat_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
- zend_string *property_name;
-fetch_obj_r_no_object:
- property_name = zval_get_string(offset);
- zend_error(E_NOTICE, "Trying to get property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
- ZVAL_NULL(EX_VAR(opline->result.var));
- } else {
- retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_OR_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(bitwise_or_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- if (retval != EX_VAR(opline->result.var)) {
- ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval);
- }
- }
- } while (0);
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_AND_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(bitwise_and_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_BW_XOR_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(bitwise_xor_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
+}
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_POW_SPEC_VAR_UNUSED_DIM_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ ZEND_VM_TAIL_CALL(zend_binary_assign_op_helper_SPEC_VAR_UNUSED_DIM(pow_function ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op1;
}
} while (0);
-#ifdef ZTS
- if (ce->type == ZEND_INTERNAL_CLASS) {
- ZVAL_DUP(EX_VAR(opline->result.var), value);
- } else {
- ZVAL_COPY(EX_VAR(opline->result.var), value);
- }
-#else
- ZVAL_COPY(EX_VAR(opline->result.var), value);
-#endif
+ FREE_OP(free_op_data1);
- ZEND_VM_NEXT_OPCODE();
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ /* assign_obj has two opcodes! */
+ ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
-
- zval *container;
- zval *offset;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr;
+ zval *value, *container, *dim;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C);
- if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
- offset = EX_CONSTANT(opline->op2);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- do {
- if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
- if (Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- if (Z_TYPE_P(container) != IS_OBJECT) {
- break;
- }
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+ SEPARATE_ARRAY(container);
+assign_dim_op_new_array:
+ dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC);
+ if (IS_CV == IS_UNUSED) {
+ var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
+ if (UNEXPECTED(!var_ptr)) {
+ zend_cannot_add_element();
+ goto assign_dim_op_ret_null;
+ }
+ } else {
+ if (IS_CV == IS_CONST) {
+ var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
} else {
- break;
+ var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ }
+ if (UNEXPECTED(!var_ptr)) {
+ goto assign_dim_op_ret_null;
}
+ ZVAL_DEREF(var_ptr);
}
- if (Z_OBJ_HT_P(container)->unset_property) {
- Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- } else {
- zend_string *property_name = zval_get_string(offset);
- zend_error(E_NOTICE, "Trying to unset property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
+
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+
+ binary_op(var_ptr, var_ptr, value);
+
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
+ } else {
+ if (EXPECTED(Z_ISREF_P(container))) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto assign_dim_op_array;
+ }
+ } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+ container = GET_OP1_UNDEF_CV(container, BP_VAR_RW);
+assign_dim_op_convert_to_array:
+ ZVAL_ARR(container, zend_new_array(8));
+ goto assign_dim_op_new_array;
}
- } while (0);
+ dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+ zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC);
+ } else {
+ if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ if (IS_CV == IS_UNUSED) {
+ zend_use_new_element_for_string();
+ } else {
+ zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
- zend_wrong_string_offset(EXECUTE_DATA_C);
++ if (EXPECTED(EG(exception) == NULL)) {
++ zend_wrong_string_offset(EXECUTE_DATA_C);
++ }
+ }
+ UNDEF_RESULT();
+ } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+ goto assign_dim_op_convert_to_array;
+ } else {
+ if (UNEXPECTED(IS_VAR != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) {
+ zend_use_scalar_as_array();
+ }
+assign_dim_op_ret_null:
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ }
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+ }
+ }
+
+ FREE_OP(free_op_data1);
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper_SPEC_VAR_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
-
- zval *container;
- int result;
- zval *offset;
+ zend_free_op free_op1;
+ zval *var_ptr;
+ zval *value;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_unused(EXECUTE_DATA_C);
+ value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
+ if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISERROR_P(var_ptr))) {
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ } else {
+ ZVAL_DEREF(var_ptr);
- offset = EX_CONSTANT(opline->op2);
+ binary_op(var_ptr, var_ptr, value);
- if (IS_UNUSED == IS_CONST ||
- (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
- if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
- container = Z_REFVAL_P(container);
- if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
- goto isset_no_object;
- }
- } else {
- goto isset_no_object;
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
}
}
- if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) {
- zend_string *property_name = zval_get_string(offset);
- zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
-isset_no_object:
- result = ((opline->extended_value & ZEND_ISSET) == 0);
- } else {
- result =
- ((opline->extended_value & ZEND_ISSET) == 0) ^
- Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL));
- }
-
- ZEND_VM_SMART_BRANCH(result, 1);
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC);
} else {
if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- if (IS_UNUSED == IS_UNUSED) {
- zend_throw_error(NULL, "[] operator not supported for strings");
+ if (IS_CONST == IS_UNUSED) {
+ zend_use_new_element_for_string();
} else {
zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
- zend_wrong_string_offset(EXECUTE_DATA_C);
+ if (EXPECTED(EG(exception) == NULL)) {
+ zend_wrong_string_offset(EXECUTE_DATA_C);
+ }
}
UNDEF_RESULT();
} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
- zend_free_op free_op_data;
- zval *object, *property, *value, tmp;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr;
+ zval *value, *container, *dim;
SAVE_OPLINE();
- object = _get_zval_ptr_cv_undef_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
+ container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC);
- if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
- ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
- }
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+ SEPARATE_ARRAY(container);
+assign_dim_op_new_array:
+ dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
+ if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+ var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
+ if (UNEXPECTED(!var_ptr)) {
+ zend_cannot_add_element();
+ goto assign_dim_op_ret_null;
+ }
+ } else {
+ if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
+ var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ } else {
+ var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ }
+ if (UNEXPECTED(!var_ptr)) {
+ goto assign_dim_op_ret_null;
+ }
+ ZVAL_DEREF(var_ptr);
+ }
- property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
- value = _get_zval_ptr_tmp((opline+1)->op1.var, &free_op_data EXECUTE_DATA_CC);
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
- if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
- do {
- if (Z_ISREF_P(object)) {
- object = Z_REFVAL_P(object);
- if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
- break;
- }
+ binary_op(var_ptr, var_ptr, value);
+
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
+ } else {
+ if (EXPECTED(Z_ISREF_P(container))) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto assign_dim_op_array;
}
- if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE ||
- (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
- zend_object *obj;
+ } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+ container = GET_OP1_UNDEF_CV(container, BP_VAR_RW);
+assign_dim_op_convert_to_array:
+ ZVAL_ARR(container, zend_new_array(8));
+ goto assign_dim_op_new_array;
+ }
+
+ dim = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC);
- zval_ptr_dtor(object);
- object_init(object);
- Z_ADDREF_P(object);
- obj = Z_OBJ_P(object);
- zend_error(E_WARNING, "Creating default object from empty value");
- if (GC_REFCOUNT(obj) == 1) {
- /* the enclosing container was deleted, obj is unreferenced */
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_NULL(EX_VAR(opline->result.var));
+ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+ zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC);
+ } else {
+ if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
+ zend_use_new_element_for_string();
+ } else {
+ zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
- zend_wrong_string_offset(EXECUTE_DATA_C);
++ if (EXPECTED(EG(exception) == NULL)) {
++ zend_wrong_string_offset(EXECUTE_DATA_C);
+ }
- zval_ptr_dtor_nogc(free_op_data);
- OBJ_RELEASE(obj);
- goto exit_assign_obj;
}
- Z_DELREF_P(object);
+ UNDEF_RESULT();
+ } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+ goto assign_dim_op_convert_to_array;
} else {
- if (IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(object))) {
- zend_string *property_name = zval_get_string(property);
- zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name));
- zend_string_release(property_name);
+ if (UNEXPECTED(IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) {
+ zend_use_scalar_as_array();
}
+assign_dim_op_ret_null:
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC);
} else {
if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) {
- zend_throw_error(NULL, "[] operator not supported for strings");
+ if (IS_UNUSED == IS_UNUSED) {
+ zend_use_new_element_for_string();
} else {
zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
- zend_wrong_string_offset(EXECUTE_DATA_C);
+ if (EXPECTED(EG(exception) == NULL)) {
+ zend_wrong_string_offset(EXECUTE_DATA_C);
+ }
}
UNDEF_RESULT();
} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1;
- zval *op1;
- op1 = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) {
- ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1));
- ZEND_VM_NEXT_OPCODE();
- }
+ zval *op1, *op2;
SAVE_OPLINE();
- bitwise_not_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC));
- zval_ptr_dtor_nogc(free_op1);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
+ op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
+ op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
+ boolean_xor_function(EX_VAR(opline->result.var), op1, op2);
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zval *val;
- zend_free_op free_op1;
- val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
- if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZVAL_FALSE(EX_VAR(opline->result.var));
- } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
- ZVAL_TRUE(EX_VAR(opline->result.var));
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
- SAVE_OPLINE();
- GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- }
- } else {
- SAVE_OPLINE();
- ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val));
- zval_ptr_dtor_nogc(free_op1);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
- }
- ZEND_VM_NEXT_OPCODE();
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
- zend_free_op free_op1;
- zval *z;
+ zend_free_op free_op_data1;
+ zval *object;
+ zval *property;
+ zval *value;
+ zval *zptr;
SAVE_OPLINE();
- z = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
-
- if (Z_TYPE_P(z) == IS_STRING) {
- zend_string *str = Z_STR_P(z);
-
- if (ZSTR_LEN(str) != 0) {
- zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
- }
- } else {
- zend_string *str = _zval_get_string_func(z);
+ object = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC);
- if (ZSTR_LEN(str) != 0) {
- zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
- } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
- GET_OP1_UNDEF_CV(z, BP_VAR_R);
- }
- zend_string_release(str);
+ if (IS_CV == IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) {
+ ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
}
- zval_ptr_dtor_nogc(free_op1);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
-}
+ property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *val;
+ do {
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
- val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (Z_ISREF_P(object)) {
+ object = Z_REFVAL_P(object);
+ if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
+ goto assign_op_object;
+ }
+ }
+ if (UNEXPECTED(!make_real_object(object, property OPLINE_CC EXECUTE_DATA_CC))) {
+ break;
+ }
+ }
- if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_NEXT_OPCODE(opline + 1);
- ZEND_VM_CONTINUE();
- } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
- SAVE_OPLINE();
- GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ /* here we are sure we are dealing with an object */
+assign_op_object:
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) {
+ if (UNEXPECTED(Z_ISERROR_P(zptr))) {
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ } else {
+ ZVAL_DEREF(zptr);
+
+ binary_op(zptr, zptr, value);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ }
} else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ zend_assign_op_overloaded_property(object, property, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL), value, binary_op OPLINE_CC EXECUTE_DATA_CC);
}
- }
+ } while (0);
- SAVE_OPLINE();
- if (i_zend_is_true(val)) {
- opline++;
- } else {
- opline = OP_JMP_ADDR(opline, opline->op2);
- }
- zval_ptr_dtor_nogc(free_op1);
- ZEND_VM_JMP(opline);
+ FREE_OP(free_op_data1);
+
+
+ /* assign_obj has two opcodes! */
+ ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(binary_op_type binary_op ZEND_OPCODE_HANDLER_ARGS_DC)
{
USE_OPLINE
- zend_free_op free_op1;
- zval *val;
+ zend_free_op free_op_data1;
+ zval *var_ptr;
+ zval *value, *container, *dim;
- val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ SAVE_OPLINE();
+ container = _get_zval_ptr_cv_undef_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC);
- if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
- } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
- SAVE_OPLINE();
- GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+assign_dim_op_array:
+ SEPARATE_ARRAY(container);
+assign_dim_op_new_array:
+ dim = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC);
+ if (IS_CV == IS_UNUSED) {
+ var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
+ if (UNEXPECTED(!var_ptr)) {
+ zend_cannot_add_element();
+ goto assign_dim_op_ret_null;
+ }
} else {
- ZEND_VM_NEXT_OPCODE();
+ if (IS_CV == IS_CONST) {
+ var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ } else {
+ var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC);
+ }
+ if (UNEXPECTED(!var_ptr)) {
+ goto assign_dim_op_ret_null;
+ }
+ ZVAL_DEREF(var_ptr);
}
- }
-
- SAVE_OPLINE();
- if (i_zend_is_true(val)) {
- opline = OP_JMP_ADDR(opline, opline->op2);
- } else {
- opline++;
- }
- zval_ptr_dtor_nogc(free_op1);
- ZEND_VM_JMP(opline);
-}
-static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *val;
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
- val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ binary_op(var_ptr, var_ptr, value);
- if (EXPECTED(Z_TYPE_INFO_P(val) == IS_TRUE)) {
- ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
- ZEND_VM_CONTINUE();
- } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
- SAVE_OPLINE();
- GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
- } else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
}
- }
-
- SAVE_OPLINE();
- if (i_zend_is_true(val)) {
- opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value);
} else {
- opline = OP_JMP_ADDR(opline, opline->op2);
- }
- zval_ptr_dtor_nogc(free_op1);
- ZEND_VM_JMP(opline);
-}
-
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *val;
- int ret;
+ if (EXPECTED(Z_ISREF_P(container))) {
+ container = Z_REFVAL_P(container);
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ goto assign_dim_op_array;
+ }
+ } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
+ container = GET_OP1_UNDEF_CV(container, BP_VAR_RW);
+assign_dim_op_convert_to_array:
+ ZVAL_ARR(container, zend_new_array(8));
+ goto assign_dim_op_new_array;
+ }
- val = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
+ dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC);
- if (Z_TYPE_INFO_P(val) == IS_TRUE) {
- ZVAL_TRUE(EX_VAR(opline->result.var));
- ZEND_VM_NEXT_OPCODE();
- } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
- ZVAL_FALSE(EX_VAR(opline->result.var));
- if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
- SAVE_OPLINE();
- GET_OP1_UNDEF_CV(val, BP_VAR_R);
- ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
+ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
+ zend_binary_assign_op_obj_dim(container, dim, value, UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, binary_op EXECUTE_DATA_CC);
} else {
- ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
- ZEND_VM_CONTINUE();
+ if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+ if (IS_CV == IS_UNUSED) {
+ zend_use_new_element_for_string();
+ } else {
+ zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
- zend_wrong_string_offset(EXECUTE_DATA_C);
++ if (EXPECTED(EG(exception) == NULL)) {
++ zend_wrong_string_offset(EXECUTE_DATA_C);
++ }
+ }
+ UNDEF_RESULT();
+ } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
+ goto assign_dim_op_convert_to_array;
+ } else {
+ if (UNEXPECTED(IS_CV != IS_VAR || EXPECTED(!Z_ISERROR_P(container)))) {
+ zend_use_scalar_as_array();
+ }
+assign_dim_op_ret_null:
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ }
+ value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
}
}