mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Handle non-integer/string opcodes
This commit is contained in:
parent
e572d2d0ad
commit
0085884a61
4 changed files with 461 additions and 63 deletions
|
@ -2753,10 +2753,6 @@ static void zend_compile_keyed_list_assign(zend_ast_list *list, znode *expr_node
|
|||
zend_compile_expr(&dim_node, key_ast);
|
||||
zend_handle_numeric_op(&dim_node);
|
||||
|
||||
if (Z_TYPE(dim_node.u.constant) != IS_LONG && Z_TYPE(dim_node.u.constant) != IS_STRING) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Key must be an integer or string literal");
|
||||
}
|
||||
|
||||
if (expr_node->op_type == IS_CONST) {
|
||||
Z_TRY_ADDREF(expr_node->u.constant);
|
||||
}
|
||||
|
|
|
@ -2062,11 +2062,13 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
|
|||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST)
|
||||
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST|TMPVAR)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_free_op free_op1;
|
||||
zend_free_op free_op2;
|
||||
zval *container;
|
||||
zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
|
@ -2074,31 +2076,61 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST)
|
|||
ZEND_VM_C_LABEL(try_fetch_list):
|
||||
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
|
||||
zval *value;
|
||||
|
||||
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
|
||||
zend_string *str;
|
||||
zend_ulong hval;
|
||||
|
||||
ZEND_VM_C_LABEL(assign_again_list):
|
||||
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
|
||||
hval = Z_LVAL_P(offset);
|
||||
ZEND_VM_C_LABEL(num_index_list):
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
|
||||
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
|
||||
str = Z_STR_P(offset);
|
||||
ZEND_VM_C_LABEL(str_index_list):
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), str);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
if (UNEXPECTED(str != Z_STR_P(offset))) {
|
||||
zend_string_release(str);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
ZEND_VM_C_GOTO(assign_again_list);
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
str = ZSTR_EMPTY_ALLOC();
|
||||
ZEND_VM_C_GOTO(str_index_list);
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
ZEND_VM_C_GOTO(num_index_list);
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
ZEND_VM_C_GOTO(num_index_list);
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
ZEND_VM_C_GOTO(num_index_list);
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
} else {
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
zend_error(E_WARNING, "Illegal offset type");
|
||||
}
|
||||
} else if (OP1_TYPE != IS_CONST &&
|
||||
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
|
||||
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
|
||||
|
||||
if (retval) {
|
||||
if (result != retval) {
|
||||
|
@ -2116,6 +2148,7 @@ ZEND_VM_C_LABEL(try_fetch_list):
|
|||
}
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
}
|
||||
FREE_OP2();
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
|
|
|
@ -5746,7 +5746,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HA
|
|||
{
|
||||
USE_OPLINE
|
||||
|
||||
|
||||
zval *container;
|
||||
zval *offset = EX_CONSTANT(opline->op2);
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = EX_CONSTANT(opline->op1);
|
||||
|
@ -5754,31 +5756,61 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HA
|
|||
try_fetch_list:
|
||||
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
|
||||
zval *value;
|
||||
zend_string *str;
|
||||
zend_ulong hval;
|
||||
|
||||
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
|
||||
assign_again_list:
|
||||
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
|
||||
hval = Z_LVAL_P(offset);
|
||||
num_index_list:
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
|
||||
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
|
||||
str = Z_STR_P(offset);
|
||||
str_index_list:
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), str);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
if (UNEXPECTED(str != Z_STR_P(offset))) {
|
||||
zend_string_release(str);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
goto assign_again_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
str = ZSTR_EMPTY_ALLOC();
|
||||
goto str_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
} else {
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
zend_error(E_WARNING, "Illegal offset type");
|
||||
}
|
||||
} else if (IS_CONST != IS_CONST &&
|
||||
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
|
||||
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
|
||||
|
||||
if (retval) {
|
||||
if (result != retval) {
|
||||
|
@ -5796,6 +5828,7 @@ try_fetch_list:
|
|||
}
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
|
@ -11323,6 +11356,96 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_
|
|||
}
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
zend_free_op free_op2;
|
||||
zval *container;
|
||||
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = EX_CONSTANT(opline->op1);
|
||||
|
||||
try_fetch_list:
|
||||
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
|
||||
zval *value;
|
||||
zend_string *str;
|
||||
zend_ulong hval;
|
||||
|
||||
assign_again_list:
|
||||
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
|
||||
hval = Z_LVAL_P(offset);
|
||||
num_index_list:
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
|
||||
str = Z_STR_P(offset);
|
||||
str_index_list:
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), str);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
if (UNEXPECTED(str != Z_STR_P(offset))) {
|
||||
zend_string_release(str);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
goto assign_again_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
str = ZSTR_EMPTY_ALLOC();
|
||||
goto str_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Illegal offset type");
|
||||
}
|
||||
} else if (IS_CONST != IS_CONST &&
|
||||
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
|
||||
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
|
||||
|
||||
if (retval) {
|
||||
if (result != retval) {
|
||||
ZVAL_COPY(result, retval);
|
||||
}
|
||||
} else {
|
||||
ZVAL_NULL(result);
|
||||
}
|
||||
} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) {
|
||||
container = Z_REFVAL_P(container);
|
||||
goto try_fetch_list;
|
||||
} else {
|
||||
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
|
||||
GET_OP1_UNDEF_CV(container, BP_VAR_R);
|
||||
}
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
}
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
@ -37872,7 +37995,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDL
|
|||
{
|
||||
USE_OPLINE
|
||||
|
||||
|
||||
zval *container;
|
||||
zval *offset = EX_CONSTANT(opline->op2);
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
|
||||
|
@ -37880,31 +38005,61 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDL
|
|||
try_fetch_list:
|
||||
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
|
||||
zval *value;
|
||||
zend_string *str;
|
||||
zend_ulong hval;
|
||||
|
||||
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
|
||||
assign_again_list:
|
||||
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
|
||||
hval = Z_LVAL_P(offset);
|
||||
num_index_list:
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
|
||||
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
|
||||
str = Z_STR_P(offset);
|
||||
str_index_list:
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), str);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
if (UNEXPECTED(str != Z_STR_P(offset))) {
|
||||
zend_string_release(str);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
goto assign_again_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
str = ZSTR_EMPTY_ALLOC();
|
||||
goto str_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
} else {
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
zend_error(E_WARNING, "Illegal offset type");
|
||||
}
|
||||
} else if (IS_CV != IS_CONST &&
|
||||
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
|
||||
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
|
||||
|
||||
if (retval) {
|
||||
if (result != retval) {
|
||||
|
@ -37922,6 +38077,7 @@ try_fetch_list:
|
|||
}
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
|
@ -47819,6 +47975,96 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR
|
|||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
zend_free_op free_op2;
|
||||
zval *container;
|
||||
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
|
||||
|
||||
try_fetch_list:
|
||||
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
|
||||
zval *value;
|
||||
zend_string *str;
|
||||
zend_ulong hval;
|
||||
|
||||
assign_again_list:
|
||||
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
|
||||
hval = Z_LVAL_P(offset);
|
||||
num_index_list:
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
|
||||
str = Z_STR_P(offset);
|
||||
str_index_list:
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), str);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
if (UNEXPECTED(str != Z_STR_P(offset))) {
|
||||
zend_string_release(str);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
goto assign_again_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
str = ZSTR_EMPTY_ALLOC();
|
||||
goto str_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Illegal offset type");
|
||||
}
|
||||
} else if (IS_CV != IS_CONST &&
|
||||
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
|
||||
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
|
||||
|
||||
if (retval) {
|
||||
if (result != retval) {
|
||||
ZVAL_COPY(result, retval);
|
||||
}
|
||||
} else {
|
||||
ZVAL_NULL(result);
|
||||
}
|
||||
} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) {
|
||||
container = Z_REFVAL_P(container);
|
||||
goto try_fetch_list;
|
||||
} else {
|
||||
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
|
||||
GET_OP1_UNDEF_CV(container, BP_VAR_R);
|
||||
}
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
}
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
@ -50936,7 +51182,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_
|
|||
{
|
||||
USE_OPLINE
|
||||
zend_free_op free_op1;
|
||||
|
||||
zval *container;
|
||||
zval *offset = EX_CONSTANT(opline->op2);
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
|
||||
|
@ -51044,31 +51292,61 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_H
|
|||
try_fetch_list:
|
||||
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
|
||||
zval *value;
|
||||
zend_string *str;
|
||||
zend_ulong hval;
|
||||
|
||||
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
|
||||
assign_again_list:
|
||||
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
|
||||
hval = Z_LVAL_P(offset);
|
||||
num_index_list:
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
|
||||
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
|
||||
str = Z_STR_P(offset);
|
||||
str_index_list:
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), str);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
if (UNEXPECTED(str != Z_STR_P(offset))) {
|
||||
zend_string_release(str);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
goto assign_again_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
str = ZSTR_EMPTY_ALLOC();
|
||||
goto str_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
} else {
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
zend_error(E_WARNING, "Illegal offset type");
|
||||
}
|
||||
} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
|
||||
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
|
||||
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
|
||||
|
||||
if (retval) {
|
||||
if (result != retval) {
|
||||
|
@ -51086,6 +51364,7 @@ try_fetch_list:
|
|||
}
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
|
@ -54483,6 +54762,96 @@ fetch_obj_is_no_object:
|
|||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_free_op free_op1;
|
||||
zend_free_op free_op2;
|
||||
zval *container;
|
||||
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
|
||||
|
||||
SAVE_OPLINE();
|
||||
container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
|
||||
|
||||
try_fetch_list:
|
||||
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
|
||||
zval *value;
|
||||
zend_string *str;
|
||||
zend_ulong hval;
|
||||
|
||||
assign_again_list:
|
||||
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
|
||||
hval = Z_LVAL_P(offset);
|
||||
num_index_list:
|
||||
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
|
||||
str = Z_STR_P(offset);
|
||||
str_index_list:
|
||||
value = zend_hash_find(Z_ARRVAL_P(container), str);
|
||||
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), value);
|
||||
}
|
||||
if (UNEXPECTED(str != Z_STR_P(offset))) {
|
||||
zend_string_release(str);
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
|
||||
offset = Z_REFVAL_P(offset);
|
||||
goto assign_again_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_NULL) {
|
||||
str = ZSTR_EMPTY_ALLOC();
|
||||
goto str_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
|
||||
hval = zend_dval_to_lval(Z_DVAL_P(offset));
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_FALSE) {
|
||||
hval = 0;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_TRUE) {
|
||||
hval = 1;
|
||||
goto num_index_list;
|
||||
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
|
||||
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
|
||||
hval = Z_RES_HANDLE_P(offset);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Illegal offset type");
|
||||
}
|
||||
} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
|
||||
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
|
||||
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
|
||||
|
||||
if (retval) {
|
||||
if (result != retval) {
|
||||
ZVAL_COPY(result, retval);
|
||||
}
|
||||
} else {
|
||||
ZVAL_NULL(result);
|
||||
}
|
||||
} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) {
|
||||
container = Z_REFVAL_P(container);
|
||||
goto try_fetch_list;
|
||||
} else {
|
||||
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
|
||||
GET_OP1_UNDEF_CV(container, BP_VAR_R);
|
||||
}
|
||||
ZVAL_NULL(EX_VAR(opline->result.var));
|
||||
}
|
||||
zval_ptr_dtor_nogc(free_op2);
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
@ -57534,18 +57903,18 @@ void zend_init_opcodes_handlers(void)
|
|||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_CONST_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
|
@ -57554,8 +57923,8 @@ void zend_init_opcodes_handlers(void)
|
|||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_CV_CONST_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER,
|
||||
ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
|
|
|
@ -307,7 +307,7 @@ static uint32_t zend_vm_opcodes_flags[184] = {
|
|||
0x00010107,
|
||||
0x00000701,
|
||||
0x00000751,
|
||||
0x00000307,
|
||||
0x00000707,
|
||||
0x06000301,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue