]> granicus.if.org Git - php/commitdiff
Improved object property access.
authorDmitry Stogov <dmitry@zend.com>
Thu, 6 Nov 2014 11:50:03 +0000 (14:50 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 6 Nov 2014 11:50:03 +0000 (14:50 +0300)
Zend/zend_API.c
Zend/zend_builtin_functions.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_inheritance.c
Zend/zend_object_handlers.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/reflection/php_reflection.c

index 3643bfc8e2ebe4637558ef2b85577be761eda13f..e22b55745126e1a710043abcbcfb0dd6c9822725 100644 (file)
@@ -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)) {
index ddec6a7ddbbf0a0450296c995a92e37e6b12bcc5..ecb8f4e0d1d7e18c09c33eec59d7e606656aaaad 100644 (file)
@@ -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;
index bc9b88227f69605c1a865264b333508f4fffae78..f9a66a37d8086627c3e8f82dab522bf001b6ebe5 100644 (file)
@@ -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;
index 61a605971e8937d9a93ea6edf766c757bb6b93da..1551789c4811a95c7e72697145fbeb41abe10561 100644 (file)
@@ -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) {
index c6f8c6ae158453cd4baf164dcdb14f08d8afe715..7d9d1aade89d626c93ddc8724d918fea0e95833e 100644 (file)
@@ -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);
 
index 6b4e8f1a973eeece06e25397b3139a5868d37b1c..12a9562c0a13ebffabdaf0406a7870befc7028b8 100644 (file)
@@ -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;
                        }
index 60983e516f98b9cb70051683246861b3632c0bbd..b6d2b82cdea2c03eb15cfb324d4fa2616cb73464 100644 (file)
@@ -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));
index c4d4b135d92c867df4913c20734c6b9f7181b2eb..8257789cd209d1df868d15974ab30000f3ba157c 100644 (file)
@@ -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));
index 3d44c35b62957e46e3596d3505eba21a0c86a2b3..b972c2899c7e62f81092f40a31c77e6328faef4b 100644 (file)
@@ -3363,7 +3363,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
                        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];
+                               prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)];
                        }
                }
                if (!prop) {