]> granicus.if.org Git - php/commitdiff
Embed FETCH_CLASS <string> into the following INSTANCEOF
authorDmitry Stogov <dmitry@zend.com>
Wed, 22 Oct 2014 13:23:43 +0000 (17:23 +0400)
committerDmitry Stogov <dmitry@zend.com>
Wed, 22 Oct 2014 13:23:43 +0000 (17:23 +0400)
Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/compact_literals.c
ext/opcache/Optimizer/zend_optimizer.c

index 0428b9534a55568e5078065c5f0f76e9a1e2a1e9..cc742a95ccac6c037f0d8de8ff90d9c9015a901d 100644 (file)
@@ -5414,10 +5414,22 @@ void zend_compile_instanceof(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
                        "instanceof expects an object instance, constant given");
        }
 
-       opline = zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
-       opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
+       if (zend_is_const_default_class_ref(class_ast)) {
+               class_node.op_type = IS_CONST;
+               ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast TSRMLS_CC));
+       } else {
+               zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
+       }
+
+       opline = zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, NULL TSRMLS_CC);
 
-       zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, &class_node TSRMLS_CC);
+       if (class_node.op_type == IS_CONST) {
+               opline->op2_type = IS_CONST;
+               opline->op2.constant = zend_add_class_name_literal(
+                       CG(active_op_array), Z_STR(class_node.u.constant) TSRMLS_CC);
+       } else {
+               SET_NODE(opline->op2, &class_node);
+       }
 }
 /* }}} */
 
index 5ee4a2a1e1dc4034a59489c48164b9d4bf381814..8f9ee1308af48b40ca7ef01127f7e318910d56b6 100644 (file)
@@ -2074,13 +2074,13 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
                        if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
                                Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
                        } else {
-                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
                                CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
                        }
                } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
                        Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
                } else if (Z_TYPE_P(class_name) == IS_STRING) {
-                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value TSRMLS_CC);
+                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), 0 TSRMLS_CC);
                } else {
                        if (UNEXPECTED(EG(exception) != NULL)) {
                                HANDLE_EXCEPTION();
@@ -5294,7 +5294,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY)
        ZEND_VM_NEXT_OPCODE();
 }
 
-ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY)
+ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, CONST|VAR)
 {
        USE_OPLINE
        zend_free_op free_op1;
@@ -5305,7 +5305,25 @@ ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|VAR|CV, ANY)
        expr = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
 
        if (Z_TYPE_P(expr) == IS_OBJECT) {
-               result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
+               zend_class_entry *ce;
+
+               if (OP2_TYPE == IS_CONST) {
+                       if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+                               ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                       } else {
+                               ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+                               if (UNEXPECTED(ce == NULL)) {
+                                       ZVAL_FALSE(EX_VAR(opline->result.var));
+                                       FREE_OP1();
+                                       CHECK_EXCEPTION();
+                                       ZEND_VM_NEXT_OPCODE();
+                               }
+                               CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+                       }
+               } else {
+                       ce = Z_CE_P(EX_VAR(opline->op2.var));
+               }
+               result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
        } else {
                result = 0;
        }
index 43dc7a725bba16a6ff6077684a14985a44bee7d9..1a4dd39698be74fd889562f74b760f4973a401b8 100644 (file)
@@ -1474,13 +1474,13 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE
                        if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
                                Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
                        } else {
-                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
                                CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
                        }
                } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
                        Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
                } else if (Z_TYPE_P(class_name) == IS_STRING) {
-                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value TSRMLS_CC);
+                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), 0 TSRMLS_CC);
                } else {
                        if (UNEXPECTED(EG(exception) != NULL)) {
                                HANDLE_EXCEPTION();
@@ -1809,13 +1809,13 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
                        if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
                                Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
                        } else {
-                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
                                CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
                        }
                } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
                        Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
                } else if (Z_TYPE_P(class_name) == IS_STRING) {
-                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value TSRMLS_CC);
+                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), 0 TSRMLS_CC);
                } else {
                        if (UNEXPECTED(EG(exception) != NULL)) {
                                HANDLE_EXCEPTION();
@@ -1995,13 +1995,13 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
                        if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
                                Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
                        } else {
-                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
                                CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
                        }
                } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
                        Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
                } else if (Z_TYPE_P(class_name) == IS_STRING) {
-                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value TSRMLS_CC);
+                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), 0 TSRMLS_CC);
                } else {
                        if (UNEXPECTED(EG(exception) != NULL)) {
                                HANDLE_EXCEPTION();
@@ -2181,13 +2181,13 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
                        if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
                                Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
                        } else {
-                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
                                CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
                        }
                } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
                        Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
                } else if (Z_TYPE_P(class_name) == IS_STRING) {
-                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value TSRMLS_CC);
+                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), 0 TSRMLS_CC);
                } else {
                        if (UNEXPECTED(EG(exception) != NULL)) {
                                HANDLE_EXCEPTION();
@@ -2220,13 +2220,13 @@ static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
                        if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
                                Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
                        } else {
-                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+                               Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
                                CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
                        }
                } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
                        Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
                } else if (Z_TYPE_P(class_name) == IS_STRING) {
-                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->extended_value TSRMLS_CC);
+                       Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), 0 TSRMLS_CC);
                } else {
                        if (UNEXPECTED(EG(exception) != NULL)) {
                                HANDLE_EXCEPTION();
@@ -10159,27 +10159,6 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
        ZEND_VM_NEXT_OPCODE();
 }
 
-static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-       USE_OPLINE
-       zend_free_op free_op1;
-       zval *expr;
-       zend_bool result;
-
-       SAVE_OPLINE();
-       expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-
-       if (Z_TYPE_P(expr) == IS_OBJECT) {
-               result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
-       } else {
-               result = 0;
-       }
-       ZVAL_BOOL(EX_VAR(opline->result.var), result);
-       zval_ptr_dtor_nogc(free_op1.var);
-       CHECK_EXCEPTION();
-       ZEND_VM_NEXT_OPCODE();
-}
-
 static int ZEND_FASTCALL  ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -11457,6 +11436,45 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEN
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1;
+       zval *expr;
+       zend_bool result;
+
+       SAVE_OPLINE();
+       expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+       if (Z_TYPE_P(expr) == IS_OBJECT) {
+               zend_class_entry *ce;
+
+               if (IS_CONST == IS_CONST) {
+                       if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+                               ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                       } else {
+                               ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+                               if (UNEXPECTED(ce == NULL)) {
+                                       ZVAL_FALSE(EX_VAR(opline->result.var));
+                                       zval_ptr_dtor_nogc(free_op1.var);
+                                       CHECK_EXCEPTION();
+                                       ZEND_VM_NEXT_OPCODE();
+                               }
+                               CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+                       }
+               } else {
+                       ce = Z_CE_P(EX_VAR(opline->op2.var));
+               }
+               result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+       } else {
+               result = 0;
+       }
+       ZVAL_BOOL(EX_VAR(opline->result.var), result);
+       zval_ptr_dtor_nogc(free_op1.var);
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -13788,6 +13806,45 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1;
+       zval *expr;
+       zend_bool result;
+
+       SAVE_OPLINE();
+       expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+       if (Z_TYPE_P(expr) == IS_OBJECT) {
+               zend_class_entry *ce;
+
+               if (IS_VAR == IS_CONST) {
+                       if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+                               ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                       } else {
+                               ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+                               if (UNEXPECTED(ce == NULL)) {
+                                       ZVAL_FALSE(EX_VAR(opline->result.var));
+                                       zval_ptr_dtor_nogc(free_op1.var);
+                                       CHECK_EXCEPTION();
+                                       ZEND_VM_NEXT_OPCODE();
+                               }
+                               CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+                       }
+               } else {
+                       ce = Z_CE_P(EX_VAR(opline->op2.var));
+               }
+               result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+       } else {
+               result = 0;
+       }
+       ZVAL_BOOL(EX_VAR(opline->result.var), result);
+       zval_ptr_dtor_nogc(free_op1.var);
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -17092,27 +17149,6 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
        ZEND_VM_NEXT_OPCODE();
 }
 
-static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-       USE_OPLINE
-       zend_free_op free_op1;
-       zval *expr;
-       zend_bool result;
-
-       SAVE_OPLINE();
-       expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-
-       if (Z_TYPE_P(expr) == IS_OBJECT) {
-               result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
-       } else {
-               result = 0;
-       }
-       ZVAL_BOOL(EX_VAR(opline->result.var), result);
-       zval_ptr_dtor_nogc(free_op1.var);
-       CHECK_EXCEPTION();
-       ZEND_VM_NEXT_OPCODE();
-}
-
 static int ZEND_FASTCALL  ZEND_STRLEN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -19449,6 +19485,45 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1;
+       zval *expr;
+       zend_bool result;
+
+       SAVE_OPLINE();
+       expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+       if (Z_TYPE_P(expr) == IS_OBJECT) {
+               zend_class_entry *ce;
+
+               if (IS_CONST == IS_CONST) {
+                       if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+                               ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                       } else {
+                               ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+                               if (UNEXPECTED(ce == NULL)) {
+                                       ZVAL_FALSE(EX_VAR(opline->result.var));
+                                       zval_ptr_dtor_nogc(free_op1.var);
+                                       CHECK_EXCEPTION();
+                                       ZEND_VM_NEXT_OPCODE();
+                               }
+                               CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+                       }
+               } else {
+                       ce = Z_CE_P(EX_VAR(opline->op2.var));
+               }
+               result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+       } else {
+               result = 0;
+       }
+       ZVAL_BOOL(EX_VAR(opline->result.var), result);
+       zval_ptr_dtor_nogc(free_op1.var);
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -23780,6 +23855,45 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1;
+       zval *expr;
+       zend_bool result;
+
+       SAVE_OPLINE();
+       expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+       if (Z_TYPE_P(expr) == IS_OBJECT) {
+               zend_class_entry *ce;
+
+               if (IS_VAR == IS_CONST) {
+                       if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+                               ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                       } else {
+                               ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+                               if (UNEXPECTED(ce == NULL)) {
+                                       ZVAL_FALSE(EX_VAR(opline->result.var));
+                                       zval_ptr_dtor_nogc(free_op1.var);
+                                       CHECK_EXCEPTION();
+                                       ZEND_VM_NEXT_OPCODE();
+                               }
+                               CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+                       }
+               } else {
+                       ce = Z_CE_P(EX_VAR(opline->op2.var));
+               }
+               result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+       } else {
+               result = 0;
+       }
+       ZVAL_BOOL(EX_VAR(opline->result.var), result);
+       zval_ptr_dtor_nogc(free_op1.var);
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -34164,27 +34278,6 @@ static int ZEND_FASTCALL  ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
        ZEND_VM_NEXT_OPCODE();
 }
 
-static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-       USE_OPLINE
-
-       zval *expr;
-       zend_bool result;
-
-       SAVE_OPLINE();
-       expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-
-       if (Z_TYPE_P(expr) == IS_OBJECT) {
-               result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
-       } else {
-               result = 0;
-       }
-       ZVAL_BOOL(EX_VAR(opline->result.var), result);
-
-       CHECK_EXCEPTION();
-       ZEND_VM_NEXT_OPCODE();
-}
-
 static int ZEND_FASTCALL  ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -36297,6 +36390,45 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval *expr;
+       zend_bool result;
+
+       SAVE_OPLINE();
+       expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+       if (Z_TYPE_P(expr) == IS_OBJECT) {
+               zend_class_entry *ce;
+
+               if (IS_CONST == IS_CONST) {
+                       if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+                               ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                       } else {
+                               ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+                               if (UNEXPECTED(ce == NULL)) {
+                                       ZVAL_FALSE(EX_VAR(opline->result.var));
+
+                                       CHECK_EXCEPTION();
+                                       ZEND_VM_NEXT_OPCODE();
+                               }
+                               CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+                       }
+               } else {
+                       ce = Z_CE_P(EX_VAR(opline->op2.var));
+               }
+               result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+       } else {
+               result = 0;
+       }
+       ZVAL_BOOL(EX_VAR(opline->result.var), result);
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -40427,6 +40559,45 @@ static int ZEND_FASTCALL  ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval *expr;
+       zend_bool result;
+
+       SAVE_OPLINE();
+       expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+       if (Z_TYPE_P(expr) == IS_OBJECT) {
+               zend_class_entry *ce;
+
+               if (IS_VAR == IS_CONST) {
+                       if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+                               ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                       } else {
+                               ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+                               if (UNEXPECTED(ce == NULL)) {
+                                       ZVAL_FALSE(EX_VAR(opline->result.var));
+
+                                       CHECK_EXCEPTION();
+                                       ZEND_VM_NEXT_OPCODE();
+                               }
+                               CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+                       }
+               } else {
+                       ce = Z_CE_P(EX_VAR(opline->op2.var));
+               }
+               result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+       } else {
+               result = 0;
+       }
+       ZVAL_BOOL(EX_VAR(opline->result.var), result);
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -46972,26 +47143,26 @@ void zend_init_opcodes_handlers(void)
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
-       ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
-       ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
-       ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
-       ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
-       ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
-       ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
-       ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
-       ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
-       ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
-       ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
+       ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
+       ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER,
        ZEND_NULL_HANDLER,
+       ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
-       ZEND_INSTANCEOF_SPEC_CV_HANDLER,
-       ZEND_INSTANCEOF_SPEC_CV_HANDLER,
-       ZEND_INSTANCEOF_SPEC_CV_HANDLER,
-       ZEND_INSTANCEOF_SPEC_CV_HANDLER,
-       ZEND_INSTANCEOF_SPEC_CV_HANDLER,
        ZEND_DECLARE_CLASS_SPEC_HANDLER,
        ZEND_DECLARE_CLASS_SPEC_HANDLER,
        ZEND_DECLARE_CLASS_SPEC_HANDLER,
index 091437e11908f9fbd7581ca66fdeaab3bd6a79dd..79f3c0435242184718ef5c205450110ac9ebd2f5 100644 (file)
@@ -227,6 +227,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
                                case ZEND_FETCH_CLASS:
                                case ZEND_ADD_INTERFACE:
                                case ZEND_ADD_TRAIT:
+                               case ZEND_INSTANCEOF:
                                        if (ZEND_OP2_TYPE(opline) == IS_CONST) {
                                                LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 1, 1, 2);
                                        }
index 70e58f5695b6d07b78abb3d553f5aad41c6fc7e5..fb40349d27ab3bffd0d9e611fa12621b395b5264 100644 (file)
@@ -173,6 +173,7 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
                        case ZEND_ISSET_ISEMPTY_VAR:
                        case ZEND_ADD_INTERFACE:
                        case ZEND_ADD_TRAIT:
+                       case ZEND_INSTANCEOF:
                                Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++;
                                zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
                                zend_optimizer_add_literal(op_array, val TSRMLS_CC);