if (zend_optimizer_update_op2_const(ctx->scdf.op_array, opline, &zv)) {
return 1;
} else {
+ switch (opline->opcode) {
+ case ZEND_FETCH_CLASS:
+ if (Z_TYPE(zv) == IS_STRING) {
+ ZEND_ASSERT((opline + 1)->opcode == ZEND_INSTANCEOF);
+ ZEND_ASSERT((opline + 1)->op2.var == opline->result.var);
+ if (zend_optimizer_update_op2_const(ctx->scdf.op_array, opline + 1, &zv)) {
+ zend_ssa_op *next_op = ssa_op + 1;
+ zend_optimizer_remove_live_range_ex(ctx->scdf.op_array, opline->result.var, ssa_op - ctx->scdf.ssa->ops);
+ zend_ssa_unlink_use_chain(ctx->scdf.ssa, next_op - ctx->scdf.ssa->ops, next_op->op2_use);
+ next_op->op2_use = -1;
+ next_op->op2_use_chain = -1;
+ zend_ssa_remove_result_def(ctx->scdf.ssa, ssa_op);
+ MAKE_NOP(opline);
+ return 1;
+ }
+ }
+ default:
+ break;
+ }
zval_ptr_dtor_nogc(&zv);
}
}
case ZEND_FAST_CALL:
return 0;
case ZEND_FETCH_CLASS:
+ if ((opline + 1)->opcode == ZEND_INSTANCEOF &&
+ (opline + 1)->op2.var == opline->result.var) {
+ return 0;
+ }
case ZEND_INIT_FCALL_BY_NAME:
/*case ZEND_INIT_NS_FCALL_BY_NAME:*/
case ZEND_ADD_INTERFACE:
--- /dev/null
+--TEST--
+SCCP 024: Const replacing to op2 of INSTANCEOF
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.opt_debug_level=0x20000
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+class A {
+ function t($obj) {
+ $a = "A";
+ $b = "self";
+ $c = 1;
+ echo ($obj instanceof $a);
+ echo ($obj instanceof $b);
+ echo ($obj instanceof $c);
+ }
+}
+?>
+--EXPECTF--
+$_main: ; (lines=1, args=0, vars=0, tmps=0)
+ ; (after optimizer)
+ ; %ssccp_024.php:1-13
+L0 (13): RETURN int(1)
+
+A::t: ; (lines=10, args=1, vars=2, tmps=2)
+ ; (after optimizer)
+ ; %ssccp_024.php:3-10
+L0 (3): CV0($obj) = RECV 1
+L1 (6): CV1($c) = QM_ASSIGN int(1)
+L2 (7): T2 = INSTANCEOF CV0($obj) string("A")
+L3 (7): ECHO T2
+L4 (8): T2 = INSTANCEOF CV0($obj) string("self")
+L5 (8): ECHO T2
+L6 (9): V3 = FETCH_CLASS (no-autolod) (exception) CV1($c)
+L7 (9): T2 = INSTANCEOF CV0($obj) V3
+L8 (9): ECHO T2
+L9 (10): RETURN null