summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_compile.c24
-rw-r--r--Zend/zend_vm_def.h2
-rw-r--r--Zend/zend_vm_execute.h6
-rw-r--r--ext/opcache/Optimizer/zend_dump.c3
-rw-r--r--ext/opcache/Optimizer/zend_ssa.c2
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc2
6 files changed, 30 insertions, 9 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 982becce4b..fbbb5163f4 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -7385,8 +7385,28 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
break;
}
}
- }
- if (opcode == ZEND_CONCAT) {
+ } else if (opcode == ZEND_IS_IDENTICAL || opcode == ZEND_IS_NOT_IDENTICAL) {
+ /* convert $x === null to is_null($x) (i.e. ZEND_TYPE_CHECK opcode). Do the same thing for false/true. (covers IS_NULL, IS_FALSE, and IS_TRUE) */
+ if (left_node.op_type == IS_CONST) {
+ if (Z_TYPE(left_node.u.constant) <= IS_TRUE && Z_TYPE(left_node.u.constant) >= IS_NULL) {
+ zend_op *opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &right_node, NULL);
+ opline->extended_value =
+ (opcode == ZEND_IS_IDENTICAL) ?
+ (1 << Z_TYPE(left_node.u.constant)) :
+ (MAY_BE_ANY - (1 << Z_TYPE(left_node.u.constant)));
+ return;
+ }
+ } else if (right_node.op_type == IS_CONST) {
+ if (Z_TYPE(right_node.u.constant) <= IS_TRUE && Z_TYPE(right_node.u.constant) >= IS_NULL) {
+ zend_op *opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &left_node, NULL);
+ opline->extended_value =
+ (opcode == ZEND_IS_IDENTICAL) ?
+ (1 << Z_TYPE(right_node.u.constant)) :
+ (MAY_BE_ANY - (1 << Z_TYPE(right_node.u.constant)));
+ return;
+ }
+ }
+ } else if (opcode == ZEND_CONCAT) {
/* convert constant operands to strings at compile-time */
if (left_node.op_type == IS_CONST) {
if (Z_TYPE(left_node.u.constant) == IS_ARRAY) {
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 01b3bcf9f2..a8ab1ff375 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -7848,7 +7848,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMPVAR|CV, ANY, TYPE_MAS
value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
ZEND_VM_C_LABEL(type_check_resource):
- if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
+ if (opline->extended_value != MAY_BE_RESOURCE
|| EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
result = 1;
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index a5b1e2e752..5da5452b69 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4436,7 +4436,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_C
value = RT_CONSTANT(opline, opline->op1);
if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
type_check_resource:
- if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
+ if (opline->extended_value != MAY_BE_RESOURCE
|| EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
result = 1;
}
@@ -13254,7 +13254,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TM
value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
type_check_resource:
- if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
+ if (opline->extended_value != MAY_BE_RESOURCE
|| EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
result = 1;
}
@@ -36407,7 +36407,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_CV
value = EX_VAR(opline->op1.var);
if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) {
type_check_resource:
- if (EXPECTED(Z_TYPE_P(value) != IS_RESOURCE)
+ if (opline->extended_value != MAY_BE_RESOURCE
|| EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) {
result = 1;
}
diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c
index 68b3d4a99f..515532b3b4 100644
--- a/ext/opcache/Optimizer/zend_dump.c
+++ b/ext/opcache/Optimizer/zend_dump.c
@@ -516,7 +516,8 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
fprintf(stderr, " (bool)");
break;
default:
- fprintf(stderr, " (\?\?\?)");
+ fprintf(stderr, " TYPE");
+ zend_dump_type_info(opline->extended_value, NULL, 0, dump_flags);
break;
}
} else if (ZEND_VM_EXT_EVAL == (flags & ZEND_VM_EXT_MASK)) {
diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c
index 5fd4ccbd9d..14d88bc39b 100644
--- a/ext/opcache/Optimizer/zend_ssa.c
+++ b/ext/opcache/Optimizer/zend_ssa.c
@@ -161,7 +161,7 @@ static inline void pi_not_type_mask(zend_ssa_phi *phi, uint32_t type_mask) {
}
static inline uint32_t mask_for_type_check(uint32_t type) {
if (type & MAY_BE_ARRAY) {
- return MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF;
+ return type | (MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF);
} else {
return type;
}
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index dc40387c1b..568dab3f01 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -8003,7 +8003,7 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, int b, i
zend_bool smart_branch = 0;
zend_jit_addr op1_addr = zend_jit_decode_op(op_array, opline->op1_type, opline->op1, opline, NULL, -1);
- if (opline->extended_value & MAY_BE_RESOURCE) {
+ if (opline->extended_value == MAY_BE_RESOURCE) {
// TODO: support for is_resource() ???
goto fallback;
}