Skip to content

Commit cdc4ea2

Browse files
committed
JIT support for undefined index/offset handling
1 parent f497b69 commit cdc4ea2

File tree

4 files changed

+40
-18
lines changed

4 files changed

+40
-18
lines changed

Zend/zend_execute.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,8 +1909,7 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_index(const
19091909
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(offset));
19101910
}
19111911

1912-
static zend_never_inline ZEND_COLD int ZEND_FASTCALL zend_undefined_offset_write(
1913-
HashTable *ht, zend_long lval)
1912+
ZEND_API ZEND_COLD int ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht, zend_long lval)
19141913
{
19151914
/* The array may be destroyed while throwing the notice.
19161915
* Temporarily increase the refcount to detect this situation. */
@@ -1928,8 +1927,7 @@ static zend_never_inline ZEND_COLD int ZEND_FASTCALL zend_undefined_offset_write
19281927
return SUCCESS;
19291928
}
19301929

1931-
static zend_never_inline ZEND_COLD int ZEND_FASTCALL zend_undefined_index_write(
1932-
HashTable *ht, zend_string *offset)
1930+
ZEND_API ZEND_COLD int ZEND_FASTCALL zend_undefined_index_write(HashTable *ht, zend_string *offset)
19331931
{
19341932
/* The array may be destroyed while throwing the notice.
19351933
* Temporarily increase the refcount to detect this situation. */

Zend/zend_execute.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ ZEND_API zend_bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref(zend_propert
6464

6565
ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(zend_property_info *prop, zval *zv);
6666
ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(zend_property_info *prop1, zend_property_info *prop2, zval *zv);
67+
ZEND_API ZEND_COLD int ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht, zend_long lval);
68+
ZEND_API ZEND_COLD int ZEND_FASTCALL zend_undefined_index_write(HashTable *ht, zend_string *offset);
6769

6870
ZEND_API zend_bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, zend_bool strict, zend_bool is_internal_arg);
6971
ZEND_API ZEND_COLD void zend_verify_arg_error(

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,10 @@ static zval* ZEND_FASTCALL zend_jit_hash_index_lookup_rw(HashTable *ht, zend_lon
129129
zval *retval = _zend_hash_index_find(ht, idx);
130130

131131
if (!retval) {
132-
zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, idx);
133-
retval = zend_hash_index_update(ht, idx, &EG(uninitialized_zval));
132+
if (UNEXPECTED(zend_undefined_offset_write(ht, idx) == FAILURE)) {
133+
return NULL;
134+
}
135+
retval = zend_hash_index_add_new(ht, idx, &EG(uninitialized_zval));
134136
}
135137
return retval;
136138
}
@@ -153,12 +155,16 @@ static zval* ZEND_FASTCALL zend_jit_hash_lookup_rw(HashTable *ht, zend_string *s
153155
if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) {
154156
retval = Z_INDIRECT_P(retval);
155157
if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
156-
zend_error(E_NOTICE,"Undefined index: %s", ZSTR_VAL(str));
158+
if (UNEXPECTED(zend_undefined_index_write(ht, str) == FAILURE)) {
159+
return NULL;
160+
}
157161
ZVAL_NULL(retval);
158162
}
159163
}
160164
} else {
161-
zend_error(E_NOTICE,"Undefined index: %s", ZSTR_VAL(str));
165+
if (UNEXPECTED(zend_undefined_index_write(ht, str) == FAILURE)) {
166+
return NULL;
167+
}
162168
retval = zend_hash_update(ht, str, &EG(uninitialized_zval));
163169
}
164170
return retval;
@@ -202,8 +208,10 @@ static zval* ZEND_FASTCALL zend_jit_symtable_lookup_rw(HashTable *ht, zend_strin
202208
if (_zend_handle_numeric_str_ex(str->val, str->len, &idx)) {
203209
retval = zend_hash_index_find(ht, idx);
204210
if (!retval) {
205-
zend_error(E_NOTICE,"Undefined index: %s", ZSTR_VAL(str));
206-
retval = zend_hash_index_update(ht, idx, &EG(uninitialized_zval));
211+
if (UNEXPECTED(zend_undefined_index_write(ht, str) == FAILURE)) {
212+
return NULL;
213+
}
214+
retval = zend_hash_index_add_new(ht, idx, &EG(uninitialized_zval));
207215
}
208216
return retval;
209217
}
@@ -214,13 +222,17 @@ static zval* ZEND_FASTCALL zend_jit_symtable_lookup_rw(HashTable *ht, zend_strin
214222
if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) {
215223
retval = Z_INDIRECT_P(retval);
216224
if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
217-
zend_error(E_NOTICE,"Undefined index: %s", ZSTR_VAL(str));
225+
if (UNEXPECTED(zend_undefined_index_write(ht, str) == FAILURE)) {
226+
return NULL;
227+
}
218228
ZVAL_NULL(retval);
219229
}
220230
}
221231
} else {
222-
zend_error(E_NOTICE,"Undefined index: %s", ZSTR_VAL(str));
223-
retval = zend_hash_update(ht, str, &EG(uninitialized_zval));
232+
if (UNEXPECTED(zend_undefined_index_write(ht, str) == FAILURE)) {
233+
return NULL;
234+
}
235+
retval = zend_hash_add_new(ht, str, &EG(uninitialized_zval));
224236
}
225237
return retval;
226238
}
@@ -531,13 +543,17 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di
531543
if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) {
532544
retval = Z_INDIRECT_P(retval);
533545
if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
534-
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(offset_key));
546+
if (UNEXPECTED(zend_undefined_index_write(ht, offset_key) == FAILURE)) {
547+
return NULL;
548+
}
535549
ZVAL_NULL(retval);
536550
}
537551
}
538552
} else {
539-
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(offset_key));
540-
retval = zend_hash_update(ht, offset_key, &EG(uninitialized_zval));
553+
if (UNEXPECTED(zend_undefined_index_write(ht, offset_key) == FAILURE)) {
554+
return NULL;
555+
}
556+
retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval));
541557
}
542558
return retval;
543559

@@ -546,8 +562,10 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di
546562
return retval;
547563

548564
num_undef:
549-
zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
550-
retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval));
565+
if (UNEXPECTED(zend_undefined_offset_write(ht, hval) == FAILURE)) {
566+
return NULL;
567+
}
568+
retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
551569
return retval;
552570
}
553571

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4976,6 +4976,8 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
49764976
|4:
49774977
| SAVE_VALID_OPLINE opline, r0
49784978
| EXT_CALL zend_jit_hash_index_lookup_rw, r0
4979+
| test r0, r0
4980+
| jz >9
49794981
}
49804982
break;
49814983
case BP_VAR_W:
@@ -5099,6 +5101,8 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
50995101
} else {
51005102
| EXT_CALL zend_jit_hash_lookup_rw, r0
51015103
}
5104+
| test r0, r0
5105+
| jz >9
51025106
break;
51035107
case BP_VAR_W:
51045108
if (opline->op2_type != IS_CONST) {

0 commit comments

Comments
 (0)