Skip to content

Commit a4fa00e

Browse files
committed
Reuse wrong string offset logic in jit
JIT contains a copy of this function that effectively only differs by fetching current_execute_data from EG. We can do that in the VM version as well, as this is just used to throw an error. Export the VM function and reuse it in JIT.
1 parent 68b874d commit a4fa00e

File tree

3 files changed

+7
-109
lines changed

3 files changed

+7
-109
lines changed

Zend/zend_execute.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,10 +1539,10 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type
15391539
return offset;
15401540
}
15411541

1542-
static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D)
1542+
ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void)
15431543
{
15441544
const char *msg = NULL;
1545-
const zend_op *opline = EX(opline);
1545+
const zend_op *opline = EG(current_execute_data)->opline;
15461546
uint32_t var;
15471547

15481548
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -2183,7 +2183,7 @@ static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim
21832183
zend_use_new_element_for_string();
21842184
} else {
21852185
zend_check_string_offset(dim, BP_VAR_RW EXECUTE_DATA_CC);
2186-
zend_wrong_string_offset(EXECUTE_DATA_C);
2186+
zend_wrong_string_offset_error();
21872187
}
21882188
} else {
21892189
zend_use_scalar_as_array();
@@ -2379,7 +2379,7 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *
23792379
zend_use_new_element_for_string();
23802380
} else {
23812381
zend_check_string_offset(dim, type EXECUTE_DATA_CC);
2382-
zend_wrong_string_offset(EXECUTE_DATA_C);
2382+
zend_wrong_string_offset_error();
23832383
}
23842384
ZVAL_UNDEF(result);
23852385
} else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {

Zend/zend_execute.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(zend_property_info *prop,
7171
ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(zend_property_info *prop1, zend_property_info *prop2, zval *zv);
7272
ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht, zend_long lval);
7373
ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht, zend_string *offset);
74+
ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void);
7475

7576
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(zend_property_info *info);
7677

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 2 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -864,107 +864,6 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_is_helper(zval *container, zval
864864
}
865865
}
866866

867-
static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
868-
{
869-
const char *msg = NULL;
870-
const zend_op *opline = EG(current_execute_data)->opline;
871-
const zend_op *end;
872-
uint32_t var;
873-
874-
switch (opline->opcode) {
875-
case ZEND_ASSIGN_OP:
876-
case ZEND_ASSIGN_DIM_OP:
877-
case ZEND_ASSIGN_OBJ_OP:
878-
case ZEND_ASSIGN_STATIC_PROP_OP:
879-
msg = "Cannot use assign-op operators with string offsets";
880-
break;
881-
case ZEND_FETCH_DIM_W:
882-
case ZEND_FETCH_DIM_RW:
883-
case ZEND_FETCH_DIM_FUNC_ARG:
884-
case ZEND_FETCH_DIM_UNSET:
885-
case ZEND_FETCH_LIST_W:
886-
/* TODO: Encode the "reason" into opline->extended_value??? */
887-
var = opline->result.var;
888-
opline++;
889-
end = EG(current_execute_data)->func->op_array.opcodes +
890-
EG(current_execute_data)->func->op_array.last;
891-
while (opline < end) {
892-
if (opline->op1_type == IS_VAR && opline->op1.var == var) {
893-
switch (opline->opcode) {
894-
case ZEND_FETCH_OBJ_W:
895-
case ZEND_FETCH_OBJ_RW:
896-
case ZEND_FETCH_OBJ_FUNC_ARG:
897-
case ZEND_FETCH_OBJ_UNSET:
898-
case ZEND_ASSIGN_OBJ:
899-
case ZEND_ASSIGN_OBJ_OP:
900-
case ZEND_ASSIGN_OBJ_REF:
901-
msg = "Cannot use string offset as an object";
902-
break;
903-
case ZEND_FETCH_DIM_W:
904-
case ZEND_FETCH_DIM_RW:
905-
case ZEND_FETCH_DIM_FUNC_ARG:
906-
case ZEND_FETCH_DIM_UNSET:
907-
case ZEND_FETCH_LIST_W:
908-
case ZEND_ASSIGN_DIM:
909-
case ZEND_ASSIGN_DIM_OP:
910-
msg = "Cannot use string offset as an array";
911-
break;
912-
case ZEND_ASSIGN_OP:
913-
case ZEND_ASSIGN_STATIC_PROP_OP:
914-
msg = "Cannot use assign-op operators with string offsets";
915-
break;
916-
case ZEND_PRE_INC_OBJ:
917-
case ZEND_PRE_DEC_OBJ:
918-
case ZEND_POST_INC_OBJ:
919-
case ZEND_POST_DEC_OBJ:
920-
case ZEND_PRE_INC:
921-
case ZEND_PRE_DEC:
922-
case ZEND_POST_INC:
923-
case ZEND_POST_DEC:
924-
msg = "Cannot increment/decrement string offsets";
925-
break;
926-
case ZEND_ASSIGN_REF:
927-
case ZEND_ADD_ARRAY_ELEMENT:
928-
case ZEND_INIT_ARRAY:
929-
case ZEND_MAKE_REF:
930-
msg = "Cannot create references to/from string offsets";
931-
break;
932-
case ZEND_RETURN_BY_REF:
933-
case ZEND_VERIFY_RETURN_TYPE:
934-
msg = "Cannot return string offsets by reference";
935-
break;
936-
case ZEND_UNSET_DIM:
937-
case ZEND_UNSET_OBJ:
938-
msg = "Cannot unset string offsets";
939-
break;
940-
case ZEND_YIELD:
941-
msg = "Cannot yield string offsets by reference";
942-
break;
943-
case ZEND_SEND_REF:
944-
case ZEND_SEND_VAR_EX:
945-
case ZEND_SEND_FUNC_ARG:
946-
msg = "Only variables can be passed by reference";
947-
break;
948-
case ZEND_FE_RESET_RW:
949-
msg = "Cannot iterate on string offsets by reference";
950-
break;
951-
EMPTY_SWITCH_DEFAULT_CASE();
952-
}
953-
break;
954-
}
955-
if (opline->op2_type == IS_VAR && opline->op2.var == var) {
956-
ZEND_ASSERT(opline->opcode == ZEND_ASSIGN_REF);
957-
msg = "Cannot create references to/from string offsets";
958-
break;
959-
}
960-
}
961-
break;
962-
EMPTY_SWITCH_DEFAULT_CASE();
963-
}
964-
ZEND_ASSERT(msg != NULL);
965-
zend_throw_error(NULL, "%s", msg);
966-
}
967-
968867
static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, zval *value, zval *result)
969868
{
970869
zend_string *old_str;
@@ -1092,9 +991,7 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval
1092991
if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
1093992
zend_check_string_offset(dim/*, BP_VAR_RW*/);
1094993
}
1095-
if (!EG(exception)) {
1096-
zend_wrong_string_offset();
1097-
}
994+
zend_wrong_string_offset_error();
1098995
}
1099996
ZVAL_UNDEF(result);
1100997
} else if (Z_TYPE_P(object_ptr) == IS_FALSE) {
@@ -1225,7 +1122,7 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d
12251122
if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
12261123
zend_check_string_offset(dim/*, BP_VAR_RW*/);
12271124
}
1228-
zend_wrong_string_offset();
1125+
zend_wrong_string_offset_error();
12291126
}
12301127
} else if (Z_TYPE_P(container) == IS_FALSE) {
12311128
zend_false_to_array_deprecated();

0 commit comments

Comments
 (0)