diff options
-rw-r--r-- | Zend/zend_operators.c | 56 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 4 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 10 |
3 files changed, 54 insertions, 16 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 7ce8664232..e726f57b05 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2004,31 +2004,69 @@ ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2) /* } /* }}} */ -ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only) /* {{{ */ +static zend_bool instanceof_inerface_only(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */ { uint32_t i; - for (i=0; i<instance_ce->num_interfaces; i++) { - if (instanceof_function(instance_ce->interfaces[i], ce)) { + for (i = 0; i < instance_ce->num_interfaces; i++) { + if (instanceof_inerface_only(instance_ce->interfaces[i], ce)) { return 1; } } - if (!interfaces_only) { - while (instance_ce) { - if (instance_ce == ce) { + return 0; +} +/* }}} */ + +static zend_always_inline zend_bool instanceof_class(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */ +{ + while (instance_ce) { + if (instance_ce == ce) { + return 1; + } + instance_ce = instance_ce->parent; + } + return 0; +} +/* }}} */ + +static zend_bool instanceof_interface(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */ +{ + uint32_t i; + + for (i = 0; i < instance_ce->num_interfaces; i++) { + if (instanceof_interface(instance_ce->interfaces[i], ce)) { + return 1; + } + } + return instanceof_class(instance_ce, ce); +} +/* }}} */ + +ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only) /* {{{ */ +{ + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + if (!interfaces_only) { + if (instanceof_inerface_only(instance_ce, ce)) { return 1; } - instance_ce = instance_ce->parent; + } else { + return instanceof_interface(instance_ce, ce); } } - + if (!interfaces_only) { + return instanceof_class(instance_ce, ce); + } return 0; } /* }}} */ ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */ { - return instanceof_function_ex(instance_ce, ce, 0); + if (ce->ce_flags & ZEND_ACC_INTERFACE) { + return instanceof_interface(instance_ce, ce); + } else { + return instanceof_class(instance_ce, ce); + } } /* }}} */ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index fb49a49faf..6642eee7bb 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3119,7 +3119,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) #endif /* HAVE_DTRACE */ if (ce != catch_ce) { - if (!instanceof_function(ce, catch_ce)) { + if (!catch_ce || !instanceof_function(ce, catch_ce)) { if (opline->result.num) { zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); @@ -5597,7 +5597,7 @@ ZEND_VM_C_LABEL(try_instanceof): } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - result = instanceof_function(Z_OBJCE_P(expr), ce); + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { expr = Z_REFVAL_P(expr); ZEND_VM_C_GOTO(try_instanceof); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 8936f79e90..6f9d7456dc 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7248,7 +7248,7 @@ static int ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A #endif /* HAVE_DTRACE */ if (ce != catch_ce) { - if (!instanceof_function(ce, catch_ce)) { + if (!catch_ce || !instanceof_function(ce, catch_ce)) { if (opline->result.num) { zend_throw_exception_internal(NULL); HANDLE_EXCEPTION(); @@ -26681,7 +26681,7 @@ try_instanceof: } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - result = instanceof_function(Z_OBJCE_P(expr), ce); + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { expr = Z_REFVAL_P(expr); goto try_instanceof; @@ -27599,7 +27599,7 @@ try_instanceof: } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - result = instanceof_function(Z_OBJCE_P(expr), ce); + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { expr = Z_REFVAL_P(expr); goto try_instanceof; @@ -34243,7 +34243,7 @@ try_instanceof: } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - result = instanceof_function(Z_OBJCE_P(expr), ce); + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { expr = Z_REFVAL_P(expr); goto try_instanceof; @@ -34649,7 +34649,7 @@ try_instanceof: } else { ce = Z_CE_P(EX_VAR(opline->op2.var)); } - result = instanceof_function(Z_OBJCE_P(expr), ce); + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { expr = Z_REFVAL_P(expr); goto try_instanceof; |