com php-src: Improve "instanceof". Interfaces of the left operand should be checked only if the right operand is interafce itself.:
Zend/zend_operators.c Zend/zend_vm_def.h Zend/zen d_vm_execute.h

From: Date: Wed, 14 Jan 2015 12:06:26 +0000
Subject: com php-src: Improve "instanceof". Interfaces of the left operand should be checked only if the right operand is interafce itself.:
Zend/zend_operators.c Zend/zend_vm_def.h Zend/zen d_vm_execute.h
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-84089@lists.php.net to get a copy of this message
Commit: 232575862427e5e4a42665596773cac709e9275b Author: Dmitry Stogov <dmitry@zend.com> Wed, 14 Jan 2015 15:06:26 +0300 Parents: 588e803e8522434d769315fecf309ad12c9bfd69 Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=232575862427e5e4a42665596773cac709e9275b Log: Improve "instanceof". Interfaces of the left operand should be checked only if the right operand is interafce itself. Changed paths: M Zend/zend_operators.c M Zend/zend_vm_def.h M Zend/zend_vm_execute.h Diff: diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 7ce8664..e726f57 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 fb49a49..6642eee 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 8936f79..6f9d745 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;

« previous php.cvs (#84089) next »