Skip to content

Commit d22f3b1

Browse files
Merge branch 'master' into zppFailOnOverflow
2 parents 71566b9 + 12cf41c commit d22f3b1

33 files changed

+4052
-2951
lines changed

Zend/zend_API.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC
12111211

12121212
for (i = 0; i < class_type->default_properties_count; i++) {
12131213
if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) {
1214-
zval_update_class_constant(&class_type->default_properties_table[i], 0, i TSRMLS_CC);
1214+
zval_update_class_constant(&class_type->default_properties_table[i], 0, OBJ_PROP_TO_OFFSET(i) TSRMLS_CC);
12151215
}
12161216
}
12171217

@@ -1255,8 +1255,9 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti
12551255
if (property_info != ZEND_WRONG_PROPERTY_INFO &&
12561256
property_info &&
12571257
(property_info->flags & ZEND_ACC_STATIC) == 0) {
1258-
ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop);
1259-
ZVAL_INDIRECT(prop, &object->properties_table[property_info->offset]);
1258+
zval *slot = OBJ_PROP(object, property_info->offset);
1259+
ZVAL_COPY_VALUE(slot, prop);
1260+
ZVAL_INDIRECT(prop, slot);
12601261
}
12611262
} ZEND_HASH_FOREACH_END();
12621263
}
@@ -1274,11 +1275,12 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties
12741275
if (property_info != ZEND_WRONG_PROPERTY_INFO &&
12751276
property_info &&
12761277
(property_info->flags & ZEND_ACC_STATIC) == 0) {
1277-
zval_ptr_dtor(&object->properties_table[property_info->offset]);
1278-
ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop);
1279-
zval_add_ref(&object->properties_table[property_info->offset]);
1278+
zval *slot = OBJ_PROP(object, property_info->offset);
1279+
zval_ptr_dtor(slot);
1280+
ZVAL_COPY_VALUE(slot, prop);
1281+
zval_add_ref(slot);
12801282
if (object->properties) {
1281-
ZVAL_INDIRECT(&tmp, &object->properties_table[property_info->offset]);
1283+
ZVAL_INDIRECT(&tmp, slot);
12821284
zend_hash_update(object->properties, key, &tmp);
12831285
}
12841286
} else {
@@ -3622,13 +3624,14 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
36223624
if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
36233625
(property_info_ptr->flags & ZEND_ACC_STATIC) == 0) {
36243626
property_info->offset = property_info_ptr->offset;
3625-
zval_ptr_dtor(&ce->default_properties_table[property_info->offset]);
3627+
zval_ptr_dtor(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]);
36263628
zend_hash_del(&ce->properties_info, name);
36273629
} else {
3628-
property_info->offset = ce->default_properties_count++;
3630+
property_info->offset = OBJ_PROP_TO_OFFSET(ce->default_properties_count);
3631+
ce->default_properties_count++;
36293632
ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS);
36303633
}
3631-
ZVAL_COPY_VALUE(&ce->default_properties_table[property_info->offset], property);
3634+
ZVAL_COPY_VALUE(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)], property);
36323635
}
36333636
if (ce->type & ZEND_INTERNAL_CLASS) {
36343637
switch(Z_TYPE_P(property)) {

Zend/zend_builtin_functions.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -954,12 +954,10 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
954954
continue;
955955
}
956956
prop = NULL;
957-
if (prop_info->offset >= 0) {
958-
if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
959-
prop = &ce->default_static_members_table[prop_info->offset];
960-
} else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
961-
prop = &ce->default_properties_table[prop_info->offset];
962-
}
957+
if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) {
958+
prop = &ce->default_static_members_table[prop_info->offset];
959+
} else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) {
960+
prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
963961
}
964962
if (!prop || Z_TYPE_P(prop) == IS_UNDEF) {
965963
continue;

Zend/zend_compile.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,13 +227,23 @@ typedef struct _zend_try_catch_element {
227227
char *zend_visibility_string(uint32_t fn_flags);
228228

229229
typedef struct _zend_property_info {
230+
uint32_t offset; /* property offset for object properties or
231+
property index for static properties */
230232
uint32_t flags;
231-
int offset;
232233
zend_string *name;
233234
zend_string *doc_comment;
234235
zend_class_entry *ce;
235236
} zend_property_info;
236237

238+
#define OBJ_PROP(obj, offset) \
239+
((zval*)((char*)(obj) + offset))
240+
#define OBJ_PROP_NUM(obj, num) \
241+
(&(obj)->properties_table[(num)])
242+
#define OBJ_PROP_TO_OFFSET(num) \
243+
((uint32_t)(zend_uintptr_t)OBJ_PROP_NUM(((zend_object*)NULL), num))
244+
#define OBJ_PROP_TO_NUM(offset) \
245+
((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval))
246+
237247
typedef struct _zend_arg_info {
238248
const char *name; // TODO: convert into zend_string ???
239249
uint32_t name_len;

Zend/zend_config.w32.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ typedef unsigned int uint;
4747
#define HAVE_CLASS_ISTDIOSTREAM
4848
#define istdiostream stdiostream
4949

50+
#if _MSC_VER < 1900
5051
#define snprintf _snprintf
52+
#endif
5153
#if _MSC_VER < 1500
5254
#define vsnprintf _vsnprintf
5355
#endif

Zend/zend_execute.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,7 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *
12921292
zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC);
12931293
}
12941294

1295-
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, void **cache_slot, int type TSRMLS_DC)
1295+
static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type TSRMLS_DC)
12961296
{
12971297
if (container_op_type != IS_UNUSED) {
12981298
ZVAL_DEREF(container);
@@ -1316,6 +1316,26 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
13161316
}
13171317
}
13181318
}
1319+
if (prop_op_type == IS_CONST &&
1320+
EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) {
1321+
zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 1);
1322+
zend_object *zobj = Z_OBJ_P(container);
1323+
zval *retval;
1324+
1325+
if (EXPECTED(prop_info)) {
1326+
retval = OBJ_PROP(zobj, prop_info->offset);
1327+
if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
1328+
ZVAL_INDIRECT(result, retval);
1329+
return;
1330+
}
1331+
} else if (EXPECTED(zobj->properties != NULL)) {
1332+
retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr));
1333+
if (EXPECTED(retval)) {
1334+
ZVAL_INDIRECT(result, retval);
1335+
return;
1336+
}
1337+
}
1338+
}
13191339
if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) {
13201340
zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot TSRMLS_CC);
13211341
if (NULL == ptr) {

Zend/zend_hash.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ static const uint32_t uninitialized_bucket = {INVALID_IDX};
100100
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
101101
{
102102
/* Use big enough power of 2 */
103-
#ifdef PHP_WIN32
103+
#if defined(PHP_WIN32) && !defined(__clang__)
104104
if (nSize <= 8) {
105105
ht->nTableSize = 8;
106106
} else if (nSize >= 0x80000000) {
@@ -269,14 +269,12 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
269269

270270
IS_CONSISTENT(ht);
271271

272-
CHECK_INIT(ht, 0);
273-
if (ht->u.flags & HASH_FLAG_PACKED) {
272+
if (UNEXPECTED(ht->nTableMask == 0)) {
273+
CHECK_INIT(ht, 0);
274+
goto add_to_hash;
275+
} else if (ht->u.flags & HASH_FLAG_PACKED) {
274276
zend_hash_packed_to_hash(ht);
275-
}
276-
277-
h = zend_string_hash_val(key);
278-
279-
if ((flag & HASH_ADD_NEW) == 0) {
277+
} else if ((flag & HASH_ADD_NEW) == 0) {
280278
p = zend_hash_find_bucket(ht, key);
281279

282280
if (p) {
@@ -302,14 +300,15 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
302300

303301
ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
304302

303+
add_to_hash:
305304
HANDLE_BLOCK_INTERRUPTIONS();
306305
idx = ht->nNumUsed++;
307306
ht->nNumOfElements++;
308307
if (ht->nInternalPointer == INVALID_IDX) {
309308
ht->nInternalPointer = idx;
310309
}
311310
p = ht->arData + idx;
312-
p->h = h;
311+
p->h = h = zend_string_hash_val(key);
313312
p->key = key;
314313
zend_string_addref(key);
315314
ZVAL_COPY_VALUE(&p->val, pData);
@@ -423,9 +422,15 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
423422
#endif
424423

425424
IS_CONSISTENT(ht);
426-
CHECK_INIT(ht, h < ht->nTableSize);
427425

428-
if (ht->u.flags & HASH_FLAG_PACKED) {
426+
if (UNEXPECTED(ht->nTableMask == 0)) {
427+
CHECK_INIT(ht, h < ht->nTableSize);
428+
if (h < ht->nTableSize) {
429+
p = ht->arData + h;
430+
goto add_to_packed;
431+
}
432+
goto add_to_hash;
433+
} else if (ht->u.flags & HASH_FLAG_PACKED) {
429434
if (h < ht->nNumUsed) {
430435
p = ht->arData + h;
431436
if (Z_TYPE(p->val) != IS_UNDEF) {
@@ -453,6 +458,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
453458
goto convert_to_hash;
454459
}
455460

461+
add_to_packed:
456462
HANDLE_BLOCK_INTERRUPTIONS();
457463
/* incremental initialization of empty Buckets */
458464
if ((flag & (HASH_ADD_NEW|HASH_ADD_NEXT)) == (HASH_ADD_NEW|HASH_ADD_NEXT)) {
@@ -477,17 +483,14 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
477483
p->h = h;
478484
p->key = NULL;
479485
ZVAL_COPY_VALUE(&p->val, pData);
480-
Z_NEXT(p->val) = INVALID_IDX;
481486

482487
HANDLE_UNBLOCK_INTERRUPTIONS();
483488

484489
return &p->val;
485490

486491
convert_to_hash:
487492
zend_hash_packed_to_hash(ht);
488-
}
489-
490-
if ((flag & HASH_ADD_NEW) == 0) {
493+
} else if ((flag & HASH_ADD_NEW) == 0) {
491494
p = zend_hash_index_find_bucket(ht, h);
492495
if (p) {
493496
if (flag & HASH_ADD) {
@@ -509,6 +512,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
509512

510513
ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
511514

515+
add_to_hash:
512516
HANDLE_BLOCK_INTERRUPTIONS();
513517
idx = ht->nNumUsed++;
514518
ht->nNumOfElements++;

Zend/zend_inheritance.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -602,9 +602,12 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro
602602
if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) {
603603
zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name->val, key->val, zend_visibility_string(parent_info->flags), parent_ce->name->val, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
604604
} else if ((child_info->flags & ZEND_ACC_STATIC) == 0) {
605-
zval_ptr_dtor(&(ce->default_properties_table[parent_info->offset]));
606-
ce->default_properties_table[parent_info->offset] = ce->default_properties_table[child_info->offset];
607-
ZVAL_UNDEF(&ce->default_properties_table[child_info->offset]);
605+
int parent_num = OBJ_PROP_TO_NUM(parent_info->offset);
606+
int child_num = OBJ_PROP_TO_NUM(child_info->offset);
607+
608+
zval_ptr_dtor(&(ce->default_properties_table[parent_num]));
609+
ce->default_properties_table[parent_num] = ce->default_properties_table[child_num];
610+
ZVAL_UNDEF(&ce->default_properties_table[child_num]);
608611
child_info->offset = parent_info->offset;
609612
}
610613
return 0; /* Don't copy from parent */
@@ -797,7 +800,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
797800
if (property_info->flags & ZEND_ACC_STATIC) {
798801
property_info->offset += parent_ce->default_static_members_count;
799802
} else {
800-
property_info->offset += parent_ce->default_properties_count;
803+
property_info->offset += parent_ce->default_properties_count * sizeof(zval);
801804
}
802805
}
803806
} ZEND_HASH_FOREACH_END();
@@ -1421,8 +1424,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {
14211424
|| (Z_LVAL(compare_result) != 0);
14221425
} else {
14231426
not_compatible = (FAILURE == compare_function(&compare_result,
1424-
&ce->default_properties_table[coliding_prop->offset],
1425-
&ce->traits[i]->default_properties_table[property_info->offset] TSRMLS_CC))
1427+
&ce->default_properties_table[OBJ_PROP_TO_NUM(coliding_prop->offset)],
1428+
&ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)] TSRMLS_CC))
14261429
|| (Z_LVAL(compare_result) != 0);
14271430
}
14281431
} else {
@@ -1454,7 +1457,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {
14541457
if (flags & ZEND_ACC_STATIC) {
14551458
prop_value = &ce->traits[i]->default_static_members_table[property_info->offset];
14561459
} else {
1457-
prop_value = &ce->traits[i]->default_properties_table[property_info->offset];
1460+
prop_value = &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)];
14581461
}
14591462
if (Z_REFCOUNTED_P(prop_value)) Z_ADDREF_P(prop_value);
14601463

0 commit comments

Comments
 (0)