]> granicus.if.org Git - php/commitdiff
Reorder conditions to make "fast paths" shorter
authorDmitry Stogov <dmitry@zend.com>
Tue, 13 Jan 2015 12:31:42 +0000 (15:31 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 13 Jan 2015 12:31:42 +0000 (15:31 +0300)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 10f871e87b9c5c17d90da2e53d89220f72966c01..fb49a49faf79124ac29ae0e0393c1a21341e2733 100644 (file)
@@ -1414,42 +1414,43 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV)
                        ZEND_VM_C_GOTO(fetch_obj_r_no_object);
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-ZEND_VM_C_LABEL(fetch_obj_r_no_object):
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (OP2_TYPE == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (OP2_TYPE == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+ZEND_VM_C_LABEL(fetch_obj_r_no_object):
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        FREE_OP2();
        FREE_OP1();
@@ -1528,41 +1529,43 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
                        ZEND_VM_C_GOTO(fetch_obj_is_no_object);
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-ZEND_VM_C_LABEL(fetch_obj_is_no_object):
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (OP2_TYPE == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (OP2_TYPE == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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 (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+ZEND_VM_C_LABEL(fetch_obj_is_no_object):
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
 
-                       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));
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        FREE_OP2();
        FREE_OP1();
@@ -2347,7 +2350,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
        called_scope = obj->ce;
 
        if (OP2_TYPE != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
index 92b46be520d8bdf575ecd1d559283c2e3d0b78db..8936f79e900aa12dcf3fda06fac76957052001dc 100644 (file)
@@ -3994,42 +3994,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -4058,41 +4059,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -6898,42 +6901,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -6962,41 +6966,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -8031,42 +8037,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
 
@@ -8096,41 +8103,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCOD
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
 
@@ -9358,42 +9367,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op1);
        CHECK_EXCEPTION();
@@ -10418,42 +10428,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op1);
        CHECK_EXCEPTION();
@@ -10840,42 +10851,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_H
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
        zval_ptr_dtor_nogc(free_op1);
@@ -13023,42 +13035,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op1);
        CHECK_EXCEPTION();
@@ -15894,42 +15907,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op1);
        CHECK_EXCEPTION();
@@ -17425,42 +17439,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_H
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
        zval_ptr_dtor_nogc(free_op1);
@@ -18687,42 +18702,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -18800,41 +18816,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -19039,7 +19057,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O
        called_scope = obj->ce;
 
        if (IS_CONST != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
@@ -20869,42 +20887,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -20982,41 +21001,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -21223,7 +21244,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO
        called_scope = obj->ce;
 
        if (IS_CV != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
@@ -22253,42 +22274,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCOD
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
 
@@ -22365,43 +22387,45 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCO
                        }
                } else {
                        goto fetch_obj_is_no_object;
-               }
-       }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+               }
+       }
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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 (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
 
@@ -22610,7 +22634,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_
        called_scope = obj->ce;
 
        if ((IS_TMP_VAR|IS_VAR) != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
@@ -25549,42 +25573,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -25662,41 +25687,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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 (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
 
-                       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));
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -26002,7 +26029,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD
        called_scope = obj->ce;
 
        if (IS_CONST != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
@@ -29733,42 +29760,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       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));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -29846,41 +29874,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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 (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
 
-                       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));
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
 
        CHECK_EXCEPTION();
@@ -30212,7 +30242,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H
        called_scope = obj->ce;
 
        if (IS_CV != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
@@ -31776,42 +31806,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HA
                        goto fetch_obj_r_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_r_no_object:
-               zend_error(E_NOTICE, "Trying to get property of non-object");
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_r_no_object:
+                       zend_error(E_NOTICE, "Trying to get property of non-object");
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
 
@@ -31890,41 +31921,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_H
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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 (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
 
@@ -32162,7 +32195,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCO
        called_scope = obj->ce;
 
        if ((IS_TMP_VAR|IS_VAR) != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
@@ -33638,41 +33671,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCOD
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CONST == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CONST == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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 (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
 
-                       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));
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op1);
        CHECK_EXCEPTION();
@@ -33798,7 +33833,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_O
        called_scope = obj->ce;
 
        if (IS_CONST != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
@@ -35271,41 +35306,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_H
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if (IS_CV == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 (IS_CV == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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 (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
 
-                       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));
+                       retval = zobj->handlers->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));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op1);
        CHECK_EXCEPTION();
@@ -35394,7 +35431,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCO
        called_scope = obj->ce;
 
        if (IS_CV != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {
@@ -35911,41 +35948,43 @@ static int ZEND_FASTCALL  ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCO
                        goto fetch_obj_is_no_object;
                }
        }
-       if (UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
-fetch_obj_is_no_object:
-               ZVAL_NULL(EX_VAR(opline->result.var));
-       } else {
+
+       /* here we are sure we are dealing with an object */
+       do {
+               zend_object *zobj = Z_OBJ_P(container);
                zval *retval;
 
-               /* here we are sure we are dealing with an object */
-               do {
-                       if ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
-                               EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
-                               uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
-                               zend_object *zobj = Z_OBJ_P(container);
-
-                               if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
-                                       retval = OBJ_PROP(zobj, prop_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 ((IS_TMP_VAR|IS_VAR) == IS_CONST &&
+                       EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) {
+                       uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1);
+
+                       if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
+                               retval = OBJ_PROP(zobj, prop_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;
                                }
                        }
+               }
 
-                       retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
+               if (UNEXPECTED(zobj->handlers->read_property == NULL)) {
+fetch_obj_is_no_object:
+                       ZVAL_NULL(EX_VAR(opline->result.var));
+               } else {
+
+                       retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var));
 
                        if (retval != EX_VAR(opline->result.var)) {
                                ZVAL_COPY(EX_VAR(opline->result.var), retval);
                        }
-               } while (0);
-       }
+               }
+       } while (0);
 
        zval_ptr_dtor_nogc(free_op2);
        zval_ptr_dtor_nogc(free_op1);
@@ -36035,7 +36074,7 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_
        called_scope = obj->ce;
 
        if ((IS_TMP_VAR|IS_VAR) != IS_CONST ||
-           EXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
+           UNEXPECTED((fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(function_name), called_scope)) == NULL)) {
            zend_object *orig_obj = obj;
 
                if (UNEXPECTED(obj->handlers->get_method == NULL)) {