diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-11-06 14:50:03 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-11-06 14:50:03 +0300 |
commit | 75041379a6e73b22c094c3c9c7878a1c4e439725 (patch) | |
tree | 7266d09071014b1a0b52e01113a407450b987d8e /Zend | |
parent | 6b8328de740ce0bc116f322be5193b6b7b83927f (diff) | |
download | php-git-75041379a6e73b22c094c3c9c7878a1c4e439725.tar.gz |
Improved object property access.
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_API.c | 23 | ||||
-rw-r--r-- | Zend/zend_builtin_functions.c | 10 | ||||
-rw-r--r-- | Zend/zend_compile.h | 12 | ||||
-rw-r--r-- | Zend/zend_execute.c | 22 | ||||
-rw-r--r-- | Zend/zend_inheritance.c | 17 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 78 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 70 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 1352 |
8 files changed, 1289 insertions, 295 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 3643bfc8e2..e22b557451 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1207,7 +1207,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC for (i = 0; i < class_type->default_properties_count; i++) { if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) { - zval_update_class_constant(&class_type->default_properties_table[i], 0, i TSRMLS_CC); + zval_update_class_constant(&class_type->default_properties_table[i], 0, OBJ_PROP_TO_OFFSET(i) TSRMLS_CC); } } @@ -1251,8 +1251,9 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti if (property_info != ZEND_WRONG_PROPERTY_INFO && property_info && (property_info->flags & ZEND_ACC_STATIC) == 0) { - ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop); - ZVAL_INDIRECT(prop, &object->properties_table[property_info->offset]); + zval *slot = OBJ_PROP(object, property_info->offset); + ZVAL_COPY_VALUE(slot, prop); + ZVAL_INDIRECT(prop, slot); } } ZEND_HASH_FOREACH_END(); } @@ -1270,11 +1271,12 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties if (property_info != ZEND_WRONG_PROPERTY_INFO && property_info && (property_info->flags & ZEND_ACC_STATIC) == 0) { - zval_ptr_dtor(&object->properties_table[property_info->offset]); - ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop); - zval_add_ref(&object->properties_table[property_info->offset]); + zval *slot = OBJ_PROP(object, property_info->offset); + zval_ptr_dtor(slot); + ZVAL_COPY_VALUE(slot, prop); + zval_add_ref(slot); if (object->properties) { - ZVAL_INDIRECT(&tmp, &object->properties_table[property_info->offset]); + ZVAL_INDIRECT(&tmp, slot); zend_hash_update(object->properties, key, &tmp); } } else { @@ -3618,13 +3620,14 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL && (property_info_ptr->flags & ZEND_ACC_STATIC) == 0) { property_info->offset = property_info_ptr->offset; - zval_ptr_dtor(&ce->default_properties_table[property_info->offset]); + zval_ptr_dtor(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]); zend_hash_del(&ce->properties_info, name); } else { - property_info->offset = ce->default_properties_count++; + property_info->offset = OBJ_PROP_TO_OFFSET(ce->default_properties_count); + ce->default_properties_count++; ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS); } - ZVAL_COPY_VALUE(&ce->default_properties_table[property_info->offset], property); + ZVAL_COPY_VALUE(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)], property); } if (ce->type & ZEND_INTERNAL_CLASS) { switch(Z_TYPE_P(property)) { diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index ddec6a7ddb..ecb8f4e0d1 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -954,12 +954,10 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value continue; } prop = NULL; - if (prop_info->offset >= 0) { - if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) { - prop = &ce->default_static_members_table[prop_info->offset]; - } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) { - prop = &ce->default_properties_table[prop_info->offset]; - } + if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) { + prop = &ce->default_static_members_table[prop_info->offset]; + } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) { + prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; } if (!prop || Z_TYPE_P(prop) == IS_UNDEF) { continue; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index bc9b88227f..f9a66a37d8 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -227,13 +227,23 @@ typedef struct _zend_try_catch_element { char *zend_visibility_string(uint32_t fn_flags); typedef struct _zend_property_info { + uint32_t offset; /* property offset for object properties or + property index for static properties */ uint32_t flags; - int offset; zend_string *name; zend_string *doc_comment; zend_class_entry *ce; } zend_property_info; +#define OBJ_PROP(obj, offset) \ + ((zval*)((char*)(obj) + offset)) +#define OBJ_PROP_NUM(obj, num) \ + (&(obj)->properties_table[(num)]) +#define OBJ_PROP_TO_OFFSET(num) \ + ((uint32_t)(zend_uintptr_t)OBJ_PROP_NUM(((zend_object*)NULL), num)) +#define OBJ_PROP_TO_NUM(offset) \ + ((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) + typedef struct _zend_arg_info { const char *name; // TODO: convert into zend_string ??? uint32_t name_len; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 61a605971e..1551789c48 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1292,7 +1292,7 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval * zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC); } -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) +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) { if (container_op_type != IS_UNUSED) { ZVAL_DEREF(container); @@ -1316,6 +1316,26 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } } } + if (prop_op_type == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 1); + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_INDIRECT(result, retval); + return; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr)); + if (EXPECTED(retval)) { + ZVAL_INDIRECT(result, retval); + return; + } + } + } if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) { zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot TSRMLS_CC); if (NULL == ptr) { diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index c6f8c6ae15..7d9d1aade8 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -602,9 +602,12 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) { 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"); } else if ((child_info->flags & ZEND_ACC_STATIC) == 0) { - zval_ptr_dtor(&(ce->default_properties_table[parent_info->offset])); - ce->default_properties_table[parent_info->offset] = ce->default_properties_table[child_info->offset]; - ZVAL_UNDEF(&ce->default_properties_table[child_info->offset]); + int parent_num = OBJ_PROP_TO_NUM(parent_info->offset); + int child_num = OBJ_PROP_TO_NUM(child_info->offset); + + zval_ptr_dtor(&(ce->default_properties_table[parent_num])); + ce->default_properties_table[parent_num] = ce->default_properties_table[child_num]; + ZVAL_UNDEF(&ce->default_properties_table[child_num]); child_info->offset = parent_info->offset; } 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 if (property_info->flags & ZEND_ACC_STATIC) { property_info->offset += parent_ce->default_static_members_count; } else { - property_info->offset += parent_ce->default_properties_count; + property_info->offset += parent_ce->default_properties_count * sizeof(zval); } } } ZEND_HASH_FOREACH_END(); @@ -1421,8 +1424,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { || (Z_LVAL(compare_result) != 0); } else { not_compatible = (FAILURE == compare_function(&compare_result, - &ce->default_properties_table[coliding_prop->offset], - &ce->traits[i]->default_properties_table[property_info->offset] TSRMLS_CC)) + &ce->default_properties_table[OBJ_PROP_TO_NUM(coliding_prop->offset)], + &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)] TSRMLS_CC)) || (Z_LVAL(compare_result) != 0); } } else { @@ -1454,7 +1457,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { if (flags & ZEND_ACC_STATIC) { prop_value = &ce->traits[i]->default_static_members_table[property_info->offset]; } else { - prop_value = &ce->traits[i]->default_properties_table[property_info->offset]; + prop_value = &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]; } if (Z_REFCOUNTED_P(prop_value)) Z_ADDREF_P(prop_value); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 6b4e8f1a97..12a9562c0a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -80,11 +80,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) { if (/*prop_info->ce == ce &&*/ (prop_info->flags & ZEND_ACC_STATIC) == 0 && - prop_info->offset >= 0 && - Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) { + Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) != IS_UNDEF) { zval zv; - ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]); + ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset)); zend_hash_add_new(zobj->properties, prop_info->name, &zv); } } ZEND_HASH_FOREACH_END(); @@ -94,11 +93,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ if (prop_info->ce == ce && (prop_info->flags & ZEND_ACC_STATIC) == 0 && (prop_info->flags & ZEND_ACC_PRIVATE) != 0 && - prop_info->offset >= 0 && - Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) { + Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) != IS_UNDEF) { zval zv; - ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]); + ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset)); zend_hash_add(zobj->properties, prop_info->name, &zv); } } ZEND_HASH_FOREACH_END(); @@ -288,7 +286,7 @@ static zend_always_inline zend_bool is_derived_class(zend_class_entry *child_cla } /* }}} */ -static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot TSRMLS_DC) /* {{{ */ +static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zend_string *member, int silent, int allow_static, void **cache_slot TSRMLS_DC) /* {{{ */ { zval *zv; zend_property_info *property_info = NULL; @@ -324,8 +322,13 @@ static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_ if (EXPECTED(zend_verify_property_access(property_info, ce TSRMLS_CC) != 0)) { if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED)) || UNEXPECTED((flags & ZEND_ACC_PRIVATE))) { - if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0) && !silent) { - zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name->val, member->val); + if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) { + if (!silent) { + zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name->val, member->val); + } + if (!allow_static) { + return NULL; + } } goto exit; } @@ -342,7 +345,9 @@ static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_ && (zv = zend_hash_find(&EG(scope)->properties_info, member)) != NULL && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) { property_info = (zend_property_info*)Z_PTR_P(zv); - goto exit; + if (!allow_static && UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0)) { + return NULL; + } } else if (UNEXPECTED(property_info == NULL)) { exit_dynamic: if (cache_slot) { @@ -354,9 +359,6 @@ exit_dynamic: if (!silent) { zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(flags), ce->name->val, member->val); } - if (cache_slot) { - CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, ZEND_WRONG_PROPERTY_INFO); - } return ZEND_WRONG_PROPERTY_INFO; } @@ -370,7 +372,7 @@ exit: ZEND_API zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_string *member, int silent TSRMLS_DC) /* {{{ */ { - return zend_get_property_info_quick(ce, member, silent, NULL TSRMLS_CC); + return zend_get_property_info_quick(ce, member, silent, 1, NULL TSRMLS_CC); } /* }}} */ @@ -388,7 +390,7 @@ ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_inf } else { member = zend_string_copy(prop_info_name); } - property_info = zend_get_property_info_quick(zobj->ce, member, 1, NULL TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, member, 1, 1, NULL TSRMLS_CC); zend_string_release(member); if (property_info == NULL) { /* undefined public property */ @@ -451,13 +453,11 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ #endif /* make zend_get_property_info silent if we have getter - we may want to use it */ - property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - - retval = &zobj->properties_table[property_info->offset]; + if (EXPECTED(property_info != NULL)) { + retval = OBJ_PROP(zobj, property_info->offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { goto exit; } @@ -534,13 +534,11 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, v cache_slot = NULL; } - property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__set != NULL), cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__set != NULL), 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - - variable_ptr = &zobj->properties_table[property_info->offset]; + if (EXPECTED(property_info != NULL)) { + variable_ptr = OBJ_PROP(zobj, property_info->offset); if (Z_TYPE_P(variable_ptr) != IS_UNDEF) { goto found; } @@ -638,7 +636,7 @@ write_std_property: if (EXPECTED(property_info != NULL) && EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - ZVAL_COPY_VALUE(&zobj->properties_table[property_info->offset], value); + ZVAL_COPY_VALUE(OBJ_PROP(zobj, property_info->offset), value); } else { if (!zobj->properties) { rebuild_object_properties(zobj); @@ -754,13 +752,11 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), name->val); #endif - property_info = zend_get_property_info_quick(zobj->ce, name, (zobj->ce->__get != NULL), cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, name, (zobj->ce->__get != NULL), 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - - retval = &zobj->properties_table[property_info->offset]; + if (EXPECTED(property_info != NULL)) { + retval = OBJ_PROP(zobj, property_info->offset); if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) { if (EXPECTED(!zobj->ce->__get) || UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) { @@ -816,15 +812,15 @@ static void zend_std_unset_property(zval *object, zval *member, void **cache_slo cache_slot = NULL; } - property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__unset != NULL), cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__unset != NULL), 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { + if (EXPECTED(property_info != NULL)) { + zval *slot = OBJ_PROP(zobj, property_info->offset); - if (Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) { - zval_ptr_dtor(&zobj->properties_table[property_info->offset]); - ZVAL_UNDEF(&zobj->properties_table[property_info->offset]); + if (Z_TYPE_P(slot) != IS_UNDEF) { + zval_ptr_dtor(slot); + ZVAL_UNDEF(slot); goto exit; } } else if (EXPECTED(zobj->properties != NULL) && @@ -1413,13 +1409,11 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists, cache_slot = NULL; } - property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), 1, cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), 1, 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - - value = &zobj->properties_table[property_info->offset]; + if (EXPECTED(property_info != NULL)) { + value = OBJ_PROP(zobj, property_info->offset); if (Z_TYPE_P(value) != IS_UNDEF) { goto found; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 60983e516f..b6d2b82cde 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1324,11 +1324,33 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (OP2_TYPE == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } FREE_OP2(); @@ -1352,7 +1374,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV) zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -1376,7 +1398,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 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, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -1393,6 +1415,8 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR_DEREF(BP_VAR_IS); @@ -1405,11 +1429,33 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (OP2_TYPE == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } FREE_OP2(); @@ -1438,7 +1484,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP| 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, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -1464,7 +1510,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV) 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, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index c4d4b135d9..8257789cd2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3984,11 +3984,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -4003,6 +4025,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = opline->op1.zv; @@ -4015,11 +4039,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -4047,7 +4093,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -5332,11 +5378,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -5352,6 +5420,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = opline->op1.zv; @@ -5364,11 +5434,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -5397,7 +5489,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -6525,11 +6617,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -6545,6 +6659,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = opline->op1.zv; @@ -6557,11 +6673,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -6590,7 +6728,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -8443,11 +8581,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -8462,6 +8622,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = opline->op1.zv; @@ -8474,11 +8636,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -8506,7 +8690,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -10770,11 +10954,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op1.var); @@ -10789,6 +10995,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -10801,11 +11009,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op1.var); @@ -10833,7 +11063,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -11994,11 +12224,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -12014,6 +12266,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -12026,11 +12280,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -12059,7 +12335,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -13160,11 +13436,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -13180,6 +13478,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -13192,11 +13492,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -13225,7 +13547,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -14943,11 +15265,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op1.var); @@ -14962,6 +15306,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -14974,11 +15320,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op1.var); @@ -15006,7 +15374,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18392,11 +18760,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op1.var); @@ -18419,7 +18809,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18443,7 +18833,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H 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, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18460,6 +18850,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -18472,11 +18864,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op1.var); @@ -18504,7 +18918,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18530,7 +18944,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD 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, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -20684,11 +21098,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -20712,7 +21148,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -20736,7 +21172,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN 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, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -20753,6 +21189,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -20765,11 +21203,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -20798,7 +21258,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -20824,7 +21284,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ 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, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22814,11 +23274,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -22842,7 +23324,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22866,7 +23348,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN 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, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22883,6 +23365,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -22895,11 +23379,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -22928,7 +23434,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22954,7 +23460,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ 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, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26204,11 +26710,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op1.var); @@ -26231,7 +26759,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26255,7 +26783,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND 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, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26272,6 +26800,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -26284,11 +26814,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op1.var); @@ -26316,7 +26868,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26342,7 +26894,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H 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, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -27908,11 +28460,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -27935,7 +28509,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -27959,7 +28533,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD 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, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -27976,6 +28550,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); @@ -27988,11 +28564,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -28020,7 +28618,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND 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, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -28046,7 +28644,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP 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, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29270,11 +29868,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -29298,7 +29918,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29322,7 +29942,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ 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, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29339,6 +29959,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); @@ -29351,11 +29973,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -29384,7 +30028,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O 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, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -29410,7 +30054,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO 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, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30545,11 +31189,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -30573,7 +31239,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30597,7 +31263,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ 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, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30614,6 +31280,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); @@ -30626,11 +31294,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -30659,7 +31349,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O 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, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30685,7 +31375,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO 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, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32307,11 +32997,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -32334,7 +33046,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32358,7 +33070,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H 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, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32375,6 +33087,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); @@ -32387,11 +33101,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -32419,7 +33155,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP 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, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32445,7 +33181,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD 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, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35510,11 +36246,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -35537,7 +36295,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35561,7 +36319,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA 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, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35578,6 +36336,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); @@ -35590,11 +36350,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -35622,7 +36404,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -35648,7 +36430,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE 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, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -37632,11 +38414,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -37660,7 +38464,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -37684,7 +38488,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND 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, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -37701,6 +38505,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); @@ -37713,11 +38519,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -37746,7 +38574,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -37772,7 +38600,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H 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, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -39634,11 +40462,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -39662,7 +40512,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -39686,7 +40536,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND 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, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -39703,6 +40553,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND zval *container; zend_free_op free_op2; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); @@ -39715,11 +40567,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } zval_ptr_dtor_nogc(free_op2.var); @@ -39748,7 +40622,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -39774,7 +40648,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H 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, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -42749,11 +43623,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -42776,7 +43672,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -42800,7 +43696,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL 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, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -42817,6 +43713,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL zval *container; zval *offset; + zval *retval; + zend_property_info *prop_info; SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); @@ -42829,11 +43727,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -42861,7 +43781,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_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 object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -42887,7 +43807,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA 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, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); |