Created
September 8, 2014 11:26
-
-
Save dstogov/d9c309f2d683de6cd7c3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c | |
index 586edde..9f6016b 100644 | |
--- a/Zend/zend_execute.c | |
+++ b/Zend/zend_execute.c | |
@@ -755,42 +755,8 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p | |
FREE_OP_IF_VAR(free_value); | |
} | |
-static zend_always_inline zend_long zend_fetch_dimension_str_offset(zval *dim, int type TSRMLS_DC) | |
+static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, int value_type, zval *result TSRMLS_DC) | |
{ | |
- zend_long offset; | |
- | |
- if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) { | |
- switch(Z_TYPE_P(dim)) { | |
- case IS_STRING: | |
- if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) { | |
- break; | |
- } | |
- if (type != BP_VAR_UNSET) { | |
- zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim)); | |
- } | |
- break; | |
- case IS_DOUBLE: | |
- case IS_NULL: | |
- case IS_FALSE: | |
- case IS_TRUE: | |
- zend_error(E_NOTICE, "String offset cast occurred"); | |
- break; | |
- default: | |
- zend_error(E_WARNING, "Illegal offset type"); | |
- break; | |
- } | |
- | |
- offset = zval_get_long(dim); | |
- } else { | |
- offset = Z_LVAL_P(dim); | |
- } | |
- | |
- return offset; | |
-} | |
- | |
-static void zend_assign_to_string_offset(zval *str_offset, zend_long offset, zval *value, int value_type, zval *result TSRMLS_DC) | |
-{ | |
- zval *str = Z_STR_OFFSET_STR_P(str_offset); | |
zend_string *old_str; | |
if (offset < 0) { | |
@@ -1135,7 +1101,7 @@ str_index: | |
return retval; | |
} | |
-static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref TSRMLS_DC) | |
+static zend_always_inline zval *zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref, int allow_str_offset TSRMLS_DC) | |
{ | |
zval *retval; | |
zval *container = container_ptr; | |
@@ -1175,17 +1141,40 @@ convert_to_array: | |
zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
} | |
- if (type != BP_VAR_UNSET) { | |
- SEPARATE_STRING(container); | |
- } | |
- | |
- /* This is a dummy, the offset is broken if we're here. | |
- What matters is merely the IS_STR_OFFSET type set below.*/ | |
- offset = zend_fetch_dimension_str_offset(dim, type TSRMLS_CC); | |
+ if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) { | |
+ switch(Z_TYPE_P(dim)) { | |
+ case IS_STRING: | |
+ if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) { | |
+ break; | |
+ } | |
+ if (type != BP_VAR_UNSET) { | |
+ zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim)); | |
+ } | |
+ break; | |
+ case IS_DOUBLE: | |
+ case IS_NULL: | |
+ case IS_FALSE: | |
+ case IS_TRUE: | |
+ zend_error(E_NOTICE, "String offset cast occurred"); | |
+ break; | |
+ default: | |
+ zend_error(E_WARNING, "Illegal offset type"); | |
+ break; | |
+ } | |
- if (!IS_INTERNED(Z_STR_P(container))) zend_string_addref(Z_STR_P(container)); | |
- ZVAL_STR_OFFSET(result, container, offset); | |
+ offset = zval_get_long(dim); | |
+ } else { | |
+ offset = Z_LVAL_P(dim); | |
+ } | |
+ if (allow_str_offset) { | |
+ SEPARATE_STRING(container); | |
+ if (!IS_INTERNED(Z_STR_P(container))) zend_string_addref(Z_STR_P(container)); | |
+ ZVAL_LONG(result, offset); | |
+ return container; /* assignment to string offset */ | |
+ } else { | |
+ ZVAL_INDIRECT(result, NULL); /* wrong string offset */ | |
+ } | |
} else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (!Z_OBJ_HT_P(container)->read_dimension) { | |
zend_error_noreturn(E_ERROR, "Cannot use object as array"); | |
@@ -1250,26 +1239,27 @@ convert_to_array: | |
ZVAL_INDIRECT(result, &EG(error_zval)); | |
} | |
} | |
+ return NULL; /* not an assignment string offset */ | |
} | |
-static zend_never_inline void zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC) | |
+static zend_never_inline zval *zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type, int allow_str_offset TSRMLS_DC) | |
{ | |
- zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0 TSRMLS_CC); | |
+ return zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0, allow_str_offset TSRMLS_CC); | |
} | |
static zend_never_inline void zend_fetch_dimension_address_W_ref(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC) | |
{ | |
- zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 1 TSRMLS_CC); | |
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 1, 0 TSRMLS_CC); | |
} | |
static zend_never_inline void zend_fetch_dimension_address_RW(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC) | |
{ | |
- zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW, 0 TSRMLS_CC); | |
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW, 0, 0 TSRMLS_CC); | |
} | |
static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC) | |
{ | |
- zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET, 0 TSRMLS_CC); | |
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET, 0, 0 TSRMLS_CC); | |
} | |
static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC) | |
diff --git a/Zend/zend_types.h b/Zend/zend_types.h | |
index 389d3e5..f8d80c9 100644 | |
--- a/Zend/zend_types.h | |
+++ b/Zend/zend_types.h | |
@@ -239,7 +239,6 @@ struct _zend_ast_ref { | |
/* internal types */ | |
#define IS_INDIRECT 15 | |
-#define IS_STR_OFFSET 16 | |
#define IS_PTR 17 | |
static inline zend_uchar zval_get_type(const zval* pz) { | |
@@ -651,15 +650,6 @@ static inline zend_uchar zval_get_type(const zval* pz) { | |
Z_TYPE_INFO_P(z) = IS_PTR; \ | |
} while (0) | |
- | |
-#define Z_STR_OFFSET_STR(zval) Z_INDIRECT(zval) | |
-#define Z_STR_OFFSET_STR_P(zval_p) Z_STR_OFFSET_STR(*(zval_p)) | |
- | |
-#define ZVAL_STR_OFFSET(z, s, i) do { \ | |
- Z_STR_OFFSET_STR_P(z) = (s); \ | |
- Z_TYPE_INFO_P(z) = IS_STR_OFFSET; \ | |
- } while (0) | |
- | |
#endif /* ZEND_TYPES_H */ | |
/* | |
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h | |
index d37ab7c..6919aa9 100644 | |
--- a/Zend/zend_vm_def.h | |
+++ b/Zend/zend_vm_def.h | |
@@ -335,7 +335,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR | |
zval *value; | |
int have_get_ptr = 0; | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -430,7 +430,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR | |
SAVE_OPLINE(); | |
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (OP1_TYPE == IS_VAR && !OP1_FREE) { | |
@@ -445,7 +445,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -497,7 +497,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU | |
value = GET_OP2_ZVAL_PTR(BP_VAR_R); | |
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -692,7 +692,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR| | |
property = GET_OP2_ZVAL_PTR(BP_VAR_R); | |
retval = EX_VAR(opline->result.var); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -784,7 +784,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR | |
property = GET_OP2_ZVAL_PTR(BP_VAR_R); | |
retval = EX_VAR(opline->result.var); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -867,6 +867,10 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) | |
SAVE_OPLINE(); | |
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
fast_increment_function(var_ptr); | |
if (RETURN_VALUE_USED(opline)) { | |
@@ -875,9 +879,6 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY) | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
if (RETURN_VALUE_USED(opline)) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
@@ -922,6 +923,10 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) | |
SAVE_OPLINE(); | |
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
fast_decrement_function(var_ptr); | |
if (RETURN_VALUE_USED(opline)) { | |
@@ -930,9 +935,6 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY) | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
if (RETURN_VALUE_USED(opline)) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
@@ -977,15 +979,16 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY) | |
SAVE_OPLINE(); | |
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); | |
fast_increment_function(var_ptr); | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
FREE_OP1_VAR_PTR(); | |
@@ -1031,15 +1034,16 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY) | |
SAVE_OPLINE(); | |
var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); | |
fast_decrement_function(var_ptr); | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
FREE_OP1_VAR_PTR(); | |
@@ -1279,11 +1283,11 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV) | |
SAVE_OPLINE(); | |
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); | |
} | |
@@ -1305,7 +1309,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV) | |
SAVE_OPLINE(); | |
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); | |
@@ -1349,7 +1353,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNU | |
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE, 0 TSRMLS_CC); | |
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -1377,7 +1381,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV) | |
SAVE_OPLINE(); | |
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_UNSET); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); | |
@@ -1439,7 +1443,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV) | |
property = GET_OP2_ZVAL_PTR(BP_VAR_R); | |
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -1464,7 +1468,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV) | |
property = GET_OP2_ZVAL_PTR(BP_VAR_R); | |
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -1526,7 +1530,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP| | |
if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -1552,7 +1556,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV) | |
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET); | |
property = GET_OP2_ZVAL_PTR(BP_VAR_R); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -1598,7 +1602,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) | |
object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W); | |
property_name = GET_OP2_ZVAL_PTR(BP_VAR_R); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -1619,7 +1623,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV) | |
SAVE_OPLINE(); | |
object_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -1635,57 +1639,38 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV) | |
zend_free_op free_op2, free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R); | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
+ zval *variable_ptr; | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE, 1 TSRMLS_CC); | |
FREE_OP2(); | |
- | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
FREE_OP1_VAR_PTR(); | |
/* assign_dim has two opcodes! */ | |
@@ -1768,8 +1753,8 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) | |
UNEXPECTED(!Z_ISREF_P(variable_ptr))) { | |
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); | |
} | |
- if ((OP2_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || | |
- (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { | |
+ if ((OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) || | |
+ (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); | |
} | |
if ((OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || | |
@@ -2898,7 +2883,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) | |
retval_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); | |
} | |
@@ -3134,7 +3119,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) | |
SAVE_OPLINE(); | |
varptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(varptr) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(varptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); | |
} | |
@@ -3933,7 +3918,7 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS | |
if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -4357,6 +4342,9 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV) | |
SAVE_OPLINE(); | |
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET); | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (OP1_TYPE != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -4435,7 +4423,6 @@ ZEND_VM_C_LABEL(numeric_index_dim): | |
FREE_OP2(); | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -4456,7 +4443,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV) | |
SAVE_OPLINE(); | |
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET); | |
- if (OP1_TYPE == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = GET_OP2_ZVAL_PTR(BP_VAR_R); | |
@@ -5667,7 +5654,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE | |
} else { | |
zval *value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); | |
- if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h | |
index 8076183..493e16b 100644 | |
--- a/Zend/zend_vm_execute.h | |
+++ b/Zend/zend_vm_execute.h | |
@@ -2653,7 +2653,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND | |
retval_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); | |
} | |
@@ -3938,7 +3938,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_ | |
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, 0 TSRMLS_CC); | |
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -4042,7 +4042,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_ | |
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -4359,7 +4359,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O | |
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -4838,7 +4838,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -5266,7 +5266,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP | |
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, 0 TSRMLS_CC); | |
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -5372,7 +5372,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP | |
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -5572,7 +5572,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC | |
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -5868,7 +5868,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -6449,7 +6449,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP | |
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, 0 TSRMLS_CC); | |
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -6555,7 +6555,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP | |
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -6755,7 +6755,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC | |
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -7203,7 +7203,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -7477,7 +7477,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND | |
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, 0 TSRMLS_CC); | |
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -7622,7 +7622,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ | |
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -7948,7 +7948,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -8361,7 +8361,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC | |
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, 0 TSRMLS_CC); | |
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -8465,7 +8465,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC | |
if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -8716,7 +8716,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO | |
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -9010,7 +9010,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -9403,7 +9403,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE | |
retval_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); | |
} | |
@@ -10710,7 +10710,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP | |
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, 0 TSRMLS_CC); | |
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -10814,7 +10814,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP | |
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -10985,7 +10985,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC | |
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -11431,7 +11431,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -11859,7 +11859,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO | |
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, 0 TSRMLS_CC); | |
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -11965,7 +11965,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO | |
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -12122,7 +12122,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD | |
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -12418,7 +12418,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -12999,7 +12999,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO | |
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, 0 TSRMLS_CC); | |
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -13105,7 +13105,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO | |
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -13262,7 +13262,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD | |
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -13710,7 +13710,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -13984,7 +13984,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O | |
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, 0 TSRMLS_CC); | |
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -14013,7 +14013,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP | |
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -14314,7 +14314,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -14727,7 +14727,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD | |
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, 0 TSRMLS_CC); | |
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -14831,7 +14831,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD | |
if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -14985,7 +14985,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE | |
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -15279,7 +15279,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -15419,6 +15419,10 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS | |
SAVE_OPLINE(); | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
fast_increment_function(var_ptr); | |
if (RETURN_VALUE_USED(opline)) { | |
@@ -15427,9 +15431,6 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
if (RETURN_VALUE_USED(opline)) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
@@ -15474,6 +15475,10 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS | |
SAVE_OPLINE(); | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
fast_decrement_function(var_ptr); | |
if (RETURN_VALUE_USED(opline)) { | |
@@ -15482,9 +15487,6 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
if (RETURN_VALUE_USED(opline)) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
@@ -15529,15 +15531,16 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG | |
SAVE_OPLINE(); | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); | |
fast_increment_function(var_ptr); | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; | |
@@ -15583,15 +15586,16 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG | |
SAVE_OPLINE(); | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); | |
fast_decrement_function(var_ptr); | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; | |
@@ -15890,7 +15894,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE | |
retval_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); | |
} | |
@@ -16020,7 +16024,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG | |
SAVE_OPLINE(); | |
varptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(varptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(varptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); | |
} | |
@@ -17314,7 +17318,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -17408,7 +17412,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { | |
@@ -17423,7 +17427,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -17475,7 +17479,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar | |
value = opline->op2.zv; | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -17670,7 +17674,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t | |
property = opline->op2.zv; | |
retval = EX_VAR(opline->result.var); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -17761,7 +17765,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ | |
property = opline->op2.zv; | |
retval = EX_VAR(opline->result.var); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -18013,11 +18017,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
} | |
@@ -18039,7 +18043,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
@@ -18083,7 +18087,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP | |
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, 0 TSRMLS_CC); | |
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -18111,7 +18115,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
@@ -18172,7 +18176,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA | |
property = opline->op2.zv; | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -18197,7 +18201,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H | |
property = opline->op2.zv; | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -18258,7 +18262,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP | |
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -18284,7 +18288,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
property = opline->op2.zv; | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -18308,7 +18312,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN | |
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
property_name = opline->op2.zv; | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -18329,7 +18333,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -18345,56 +18349,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN | |
zend_free_op free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = opline->op2.zv; | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
- | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
+ zval *variable_ptr; | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST, 1 TSRMLS_CC); | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; | |
/* assign_dim has two opcodes! */ | |
@@ -18750,7 +18736,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC | |
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -18941,6 +18927,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_VAR != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -19019,7 +19008,6 @@ numeric_index_dim: | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -19040,7 +19028,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = opline->op2.zv; | |
@@ -19324,7 +19312,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ | |
} else { | |
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -19719,7 +19707,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -19814,7 +19802,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { | |
@@ -19829,7 +19817,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -19881,7 +19869,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ | |
value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -20076,7 +20064,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -20168,7 +20156,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -20268,11 +20256,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
} | |
@@ -20294,7 +20282,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
@@ -20338,7 +20326,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO | |
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, 0 TSRMLS_CC); | |
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -20366,7 +20354,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
@@ -20428,7 +20416,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -20453,7 +20441,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -20515,7 +20503,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO | |
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -20541,7 +20529,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -20565,7 +20553,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL | |
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -20586,7 +20574,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -20602,57 +20590,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL | |
zend_free_op free_op2, free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
- | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
+ zval *variable_ptr; | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR, 1 TSRMLS_CC); | |
zval_dtor(free_op2.var); | |
- | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; | |
/* assign_dim has two opcodes! */ | |
@@ -20913,7 +20882,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD | |
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -21032,6 +21001,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_VAR != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -21110,7 +21082,6 @@ numeric_index_dim: | |
zval_dtor(free_op2.var); | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -21131,7 +21102,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
@@ -21337,7 +21308,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR | |
} else { | |
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -21732,7 +21703,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -21827,7 +21798,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { | |
@@ -21842,7 +21813,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -21894,7 +21865,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ | |
value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -22089,7 +22060,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -22181,7 +22152,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -22434,11 +22405,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
} | |
@@ -22460,7 +22431,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
@@ -22504,7 +22475,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO | |
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, 0 TSRMLS_CC); | |
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -22532,7 +22503,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
@@ -22594,7 +22565,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -22619,7 +22590,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -22681,7 +22652,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO | |
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -22707,7 +22678,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -22731,7 +22702,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL | |
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -22752,7 +22723,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -22768,57 +22739,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL | |
zend_free_op free_op2, free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
- | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
+ zval *variable_ptr; | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR, 1 TSRMLS_CC); | |
zval_ptr_dtor_nogc(free_op2.var); | |
- | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; | |
/* assign_dim has two opcodes! */ | |
@@ -22901,8 +22853,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL | |
UNEXPECTED(!Z_ISREF_P(variable_ptr))) { | |
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); | |
} | |
- if ((IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || | |
- (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { | |
+ if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) || | |
+ (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); | |
} | |
if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || | |
@@ -23143,7 +23095,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD | |
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -23334,6 +23286,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_VAR != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -23412,7 +23367,6 @@ numeric_index_dim: | |
zval_ptr_dtor_nogc(free_op2.var); | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -23433,7 +23387,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
@@ -23719,7 +23673,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR | |
} else { | |
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -23839,7 +23793,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -23933,7 +23887,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { | |
@@ -23948,7 +23902,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -24000,7 +23954,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina | |
value = NULL; | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -24343,11 +24297,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
} | |
@@ -24369,7 +24323,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_ | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
@@ -24398,7 +24352,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O | |
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, 0 TSRMLS_CC); | |
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -24426,7 +24380,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -24442,56 +24396,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA | |
zend_free_op free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = NULL; | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
+ zval *variable_ptr; | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED, 1 TSRMLS_CC); | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; | |
/* assign_dim has two opcodes! */ | |
@@ -24626,7 +24562,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP | |
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -24945,7 +24881,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER | |
} else { | |
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -25325,7 +25261,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -25419,7 +25355,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { | |
@@ -25434,7 +25370,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -25486,7 +25422,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o | |
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -25681,7 +25617,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -25772,7 +25708,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -25871,11 +25807,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
} | |
@@ -25897,7 +25833,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
@@ -25941,7 +25877,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD | |
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, 0 TSRMLS_CC); | |
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -25969,7 +25905,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
@@ -26030,7 +25966,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -26055,7 +25991,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -26116,7 +26052,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD | |
if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -26142,7 +26078,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -26166,7 +26102,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE | |
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -26187,7 +26123,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -26203,56 +26139,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE | |
zend_free_op free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
- | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
+ zval *variable_ptr; | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV, 1 TSRMLS_CC); | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; | |
/* assign_dim has two opcodes! */ | |
@@ -26334,8 +26252,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE | |
UNEXPECTED(!Z_ISREF_P(variable_ptr))) { | |
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); | |
} | |
- if ((IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || | |
- (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { | |
+ if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) || | |
+ (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); | |
} | |
if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || | |
@@ -26573,7 +26491,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE | |
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -26692,6 +26610,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_VAR != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -26770,7 +26691,6 @@ numeric_index_dim: | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -26791,7 +26711,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
@@ -26995,7 +26915,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG | |
} else { | |
zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); | |
- if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -27195,7 +27115,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -27288,7 +27208,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_UNUSED == IS_VAR && !0) { | |
@@ -27303,7 +27223,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -27355,7 +27275,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi | |
value = opline->op2.zv; | |
var_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -27550,7 +27470,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde | |
property = opline->op2.zv; | |
retval = EX_VAR(opline->result.var); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -27641,7 +27561,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd | |
property = opline->op2.zv; | |
retval = EX_VAR(opline->result.var); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -27762,7 +27682,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE | |
property = opline->op2.zv; | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -27787,7 +27707,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD | |
property = opline->op2.zv; | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -27848,7 +27768,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND | |
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -27874,7 +27794,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
property = opline->op2.zv; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -27898,7 +27818,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_ | |
object = _get_obj_zval_ptr_unused(TSRMLS_C); | |
property_name = opline->op2.zv; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -28156,6 +28076,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_UNUSED != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -28234,7 +28157,6 @@ numeric_index_dim: | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -28255,7 +28177,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = opline->op2.zv; | |
@@ -28459,7 +28381,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -28563,7 +28485,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -28657,7 +28579,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_UNUSED == IS_VAR && !0) { | |
@@ -28672,7 +28594,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -28724,7 +28646,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina | |
value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
var_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -28919,7 +28841,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -29011,7 +28933,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -29134,7 +29056,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -29159,7 +29081,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -29221,7 +29143,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O | |
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -29247,7 +29169,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -29271,7 +29193,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA | |
object = _get_obj_zval_ptr_unused(TSRMLS_C); | |
property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -29439,6 +29361,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_UNUSED != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -29517,7 +29442,6 @@ numeric_index_dim: | |
zval_dtor(free_op2.var); | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -29538,7 +29462,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
@@ -29744,7 +29668,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -29848,7 +29772,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -29942,7 +29866,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_UNUSED == IS_VAR && !0) { | |
@@ -29957,7 +29881,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -30009,7 +29933,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina | |
value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
var_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -30204,7 +30128,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -30296,7 +30220,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -30419,7 +30343,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -30444,7 +30368,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -30506,7 +30430,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O | |
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -30532,7 +30456,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -30556,7 +30480,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA | |
object = _get_obj_zval_ptr_unused(TSRMLS_C); | |
property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -30724,6 +30648,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_UNUSED != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -30802,7 +30729,6 @@ numeric_index_dim: | |
zval_ptr_dtor_nogc(free_op2.var); | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -30823,7 +30749,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
@@ -31029,7 +30955,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -31133,7 +31059,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -31226,7 +31152,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_UNUSED == IS_VAR && !0) { | |
@@ -31241,7 +31167,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -31293,7 +31219,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b | |
value = NULL; | |
var_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -31545,7 +31471,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -31649,7 +31575,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -31742,7 +31668,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_UNUSED == IS_VAR && !0) { | |
@@ -31757,7 +31683,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -31809,7 +31735,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar | |
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
var_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -32004,7 +31930,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -32095,7 +32021,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -32216,7 +32142,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -32241,7 +32167,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -32302,7 +32228,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP | |
if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -32328,7 +32254,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -32352,7 +32278,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN | |
object = _get_obj_zval_ptr_unused(TSRMLS_C); | |
property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -32518,6 +32444,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_UNUSED != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -32596,7 +32525,6 @@ numeric_index_dim: | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -32617,7 +32545,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_obj_zval_ptr_unused(TSRMLS_C); | |
- if (IS_UNUSED == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
@@ -32821,7 +32749,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ | |
} else { | |
zval *value_ptr = NULL; | |
- if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -32951,6 +32879,10 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
SAVE_OPLINE(); | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
fast_increment_function(var_ptr); | |
if (RETURN_VALUE_USED(opline)) { | |
@@ -32959,9 +32891,6 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
if (RETURN_VALUE_USED(opline)) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
@@ -33005,6 +32934,10 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
SAVE_OPLINE(); | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
fast_decrement_function(var_ptr); | |
if (RETURN_VALUE_USED(opline)) { | |
@@ -33013,9 +32946,6 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
if (RETURN_VALUE_USED(opline)) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
@@ -33059,15 +32989,16 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS | |
SAVE_OPLINE(); | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); | |
fast_increment_function(var_ptr); | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
@@ -33112,15 +33043,16 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS | |
SAVE_OPLINE(); | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
+ } | |
+ | |
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { | |
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); | |
fast_decrement_function(var_ptr); | |
ZEND_VM_NEXT_OPCODE(); | |
} | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
- zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
- } | |
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { | |
ZVAL_NULL(EX_VAR(opline->result.var)); | |
@@ -33403,7 +33335,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER | |
retval_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); | |
} | |
@@ -33532,7 +33464,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS | |
SAVE_OPLINE(); | |
varptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(varptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(varptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); | |
} | |
@@ -34660,7 +34592,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -34753,7 +34685,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_CV == IS_VAR && !0) { | |
@@ -34768,7 +34700,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -34820,7 +34752,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary | |
value = opline->op2.zv; | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -35015,7 +34947,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t | |
property = opline->op2.zv; | |
retval = EX_VAR(opline->result.var); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -35106,7 +35038,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t | |
property = opline->op2.zv; | |
retval = EX_VAR(opline->result.var); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -35358,11 +35290,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
} | |
@@ -35384,7 +35316,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
@@ -35428,7 +35360,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC | |
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, 0 TSRMLS_CC); | |
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -35456,7 +35388,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); | |
@@ -35517,7 +35449,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN | |
property = opline->op2.zv; | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -35542,7 +35474,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA | |
property = opline->op2.zv; | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -35603,7 +35535,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC | |
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -35629,7 +35561,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
property = opline->op2.zv; | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -35653,7 +35585,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND | |
object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
property_name = opline->op2.zv; | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -35674,7 +35606,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -35690,56 +35622,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND | |
zend_free_op free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = opline->op2.zv; | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
- | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
+ zval *variable_ptr; | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST, 1 TSRMLS_CC); | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
/* assign_dim has two opcodes! */ | |
@@ -35881,7 +35795,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO | |
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -36072,6 +35986,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_CV != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -36150,7 +36067,6 @@ numeric_index_dim: | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -36171,7 +36087,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = opline->op2.zv; | |
@@ -36455,7 +36371,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A | |
} else { | |
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -36879,7 +36795,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -36973,7 +36889,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_CV == IS_VAR && !0) { | |
@@ -36988,7 +36904,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -37040,7 +36956,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o | |
value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -37235,7 +37151,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -37327,7 +37243,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -37427,11 +37343,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
} | |
@@ -37453,7 +37369,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
@@ -37497,7 +37413,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD | |
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, 0 TSRMLS_CC); | |
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -37525,7 +37441,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); | |
@@ -37587,7 +37503,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -37612,7 +37528,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -37674,7 +37590,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD | |
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -37700,7 +37616,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -37724,7 +37640,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE | |
object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -37745,7 +37661,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -37761,57 +37677,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE | |
zend_free_op free_op2, free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
- | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
+ zval *variable_ptr; | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR, 1 TSRMLS_CC); | |
zval_dtor(free_op2.var); | |
- | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
/* assign_dim has two opcodes! */ | |
@@ -37955,7 +37852,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE | |
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -38074,6 +37971,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_CV != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -38152,7 +38052,6 @@ numeric_index_dim: | |
zval_dtor(free_op2.var); | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -38173,7 +38072,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
@@ -38379,7 +38278,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG | |
} else { | |
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -38773,7 +38672,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -38867,7 +38766,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_CV == IS_VAR && !0) { | |
@@ -38882,7 +38781,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -38934,7 +38833,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o | |
value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -39129,7 +39028,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -39221,7 +39120,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -39474,11 +39373,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
} | |
@@ -39500,7 +39399,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
@@ -39544,7 +39443,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD | |
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, 0 TSRMLS_CC); | |
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -39572,7 +39471,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); | |
@@ -39634,7 +39533,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -39659,7 +39558,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -39721,7 +39620,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD | |
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -39747,7 +39646,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -39771,7 +39670,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE | |
object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -39792,7 +39691,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -39808,57 +39707,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE | |
zend_free_op free_op2, free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
- | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
+ zval *variable_ptr; | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR, 1 TSRMLS_CC); | |
zval_ptr_dtor_nogc(free_op2.var); | |
- | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
/* assign_dim has two opcodes! */ | |
@@ -39941,8 +39821,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE | |
UNEXPECTED(!Z_ISREF_P(variable_ptr))) { | |
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); | |
} | |
- if ((IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || | |
- (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { | |
+ if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) || | |
+ (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); | |
} | |
if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || | |
@@ -40065,7 +39945,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE | |
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -40256,6 +40136,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_CV != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -40334,7 +40217,6 @@ numeric_index_dim: | |
zval_ptr_dtor_nogc(free_op2.var); | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -40355,7 +40237,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); | |
@@ -40641,7 +40523,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG | |
} else { | |
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -40760,7 +40642,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -40853,7 +40735,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_CV == IS_VAR && !0) { | |
@@ -40868,7 +40750,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -40920,7 +40802,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar | |
value = NULL; | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -41263,11 +41145,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
} | |
@@ -41289,7 +41171,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
@@ -41318,7 +41200,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP | |
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, 0 TSRMLS_CC); | |
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -41346,7 +41228,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -41362,56 +41244,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN | |
zend_free_op free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = NULL; | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
+ zval *variable_ptr; | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
- | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED, 1 TSRMLS_CC); | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
/* assign_dim has two opcodes! */ | |
@@ -41430,7 +41294,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC | |
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -41731,7 +41595,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ | |
} else { | |
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
@@ -42110,7 +41974,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar | |
zval *value; | |
int have_get_ptr = 0; | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -42203,7 +42067,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { | |
if (IS_CV == IS_VAR && !0) { | |
@@ -42218,7 +42082,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar | |
var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
} | |
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -42270,7 +42134,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op | |
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); | |
} | |
@@ -42465,7 +42329,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -42556,7 +42420,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
retval = EX_VAR(opline->result.var); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); | |
} | |
@@ -42655,11 +42519,11 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (EXPECTED(opline->extended_value == 0)) { | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, 0 TSRMLS_CC); | |
} else { | |
zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
} | |
@@ -42681,7 +42545,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
@@ -42725,7 +42589,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE | |
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, 0 TSRMLS_CC); | |
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { | |
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); | |
} | |
@@ -42753,7 +42617,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); | |
@@ -42814,7 +42678,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
@@ -42839,7 +42703,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); | |
@@ -42900,7 +42764,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE | |
if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { | |
zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); | |
} | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); | |
@@ -42926,7 +42790,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); | |
} | |
zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); | |
@@ -42950,7 +42814,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER | |
object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); | |
@@ -42971,7 +42835,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER | |
SAVE_OPLINE(); | |
object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); | |
} | |
if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { | |
@@ -42987,56 +42851,38 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER | |
zend_free_op free_op_data1, free_op_data2; | |
zval *value; | |
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
- zval *variable_ptr = EX_VAR((opline+1)->op2.var); | |
- zend_long offset = 0; | |
- | |
- if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) || (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_STRING)) { | |
- ZVAL_DEREF(object_ptr); | |
- | |
- if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) { | |
- goto string_failed; | |
- } | |
- if (dim == NULL) { | |
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings"); | |
- } | |
- | |
- SEPARATE_STRING(object_ptr); | |
+ zval *variable_ptr; | |
- offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC); | |
- | |
- if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr)); | |
- ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset); | |
- } else { | |
-string_failed: | |
- zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC); | |
- } | |
+ variable_ptr = zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV, 1 TSRMLS_CC); | |
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); | |
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
- if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { | |
- zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
- } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
- if (IS_TMP_FREE(free_op_data1)) { | |
- zval_dtor(value); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_NULL(EX_VAR(opline->result.var)); | |
- } | |
- FREE_OP_VAR_PTR(free_op_data2); | |
+ if (UNEXPECTED(variable_ptr != NULL)) { | |
+ zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); | |
} else { | |
- if ((opline+1)->op1_type == IS_TMP_VAR) { | |
- value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
- } else if ((opline+1)->op1_type == IS_CONST) { | |
- value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); | |
+ if (UNEXPECTED(variable_ptr == &EG(error_zval))) { | |
+ if (IS_TMP_FREE(free_op_data1)) { | |
+ zval_dtor(value); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_NULL(EX_VAR(opline->result.var)); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} else { | |
- value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
- } | |
- if (RETURN_VALUE_USED(opline)) { | |
- ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ if ((opline+1)->op1_type == IS_TMP_VAR) { | |
+ value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else if ((opline+1)->op1_type == IS_CONST) { | |
+ value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } else { | |
+ value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); | |
+ } | |
+ if (RETURN_VALUE_USED(opline)) { | |
+ ZVAL_COPY(EX_VAR(opline->result.var), value); | |
+ } | |
+ FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_VAR_PTR(free_op_data2); | |
} | |
- FREE_OP_IF_VAR(free_op_data1); | |
+ FREE_OP_IF_VAR(free_op_data1); | |
} | |
/* assign_dim has two opcodes! */ | |
@@ -43118,8 +42964,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER | |
UNEXPECTED(!Z_ISREF_P(variable_ptr))) { | |
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); | |
} | |
- if ((IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || | |
- (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { | |
+ if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) || | |
+ (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); | |
} | |
if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || | |
@@ -43239,7 +43085,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ | |
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && | |
(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { | |
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); | |
} | |
ZVAL_MAKE_REF(expr_ptr); | |
@@ -43358,6 +43204,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
+ zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
+ } | |
if (IS_CV != IS_UNUSED) { | |
ZVAL_DEREF(container); | |
SEPARATE_ZVAL_NOREF(container); | |
@@ -43436,7 +43285,6 @@ numeric_index_dim: | |
break; | |
case IS_STRING: | |
- case IS_STR_OFFSET: | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
ZEND_VM_CONTINUE(); /* bailed out before */ | |
default: | |
@@ -43457,7 +43305,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ | |
SAVE_OPLINE(); | |
container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); | |
} | |
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); | |
@@ -43661,7 +43509,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS | |
} else { | |
zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); | |
- if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { | |
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { | |
zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment