diff options
| -rw-r--r-- | Zend/zend_compile.c | 39 | ||||
| -rw-r--r-- | Zend/zend_compile.h | 2 | ||||
| -rw-r--r-- | Zend/zend_operators.c | 11 | 
3 files changed, 38 insertions, 14 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e9b21ce0dc..c26c8455df 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1826,6 +1826,22 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro  } +ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, zend_class_entry *ce2) +{ +	int num = ce2->num_interfaces; + +	if (num) { +		if (ce->type == ZEND_INTERNAL_CLASS) { +			ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (ce->num_interfaces + num)); +		} else { +			ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (ce->num_interfaces + num)); +		} +		memcpy(&ce->interfaces[ce->num_interfaces], ce2->interfaces, num * sizeof(zend_class_entry*)); +		ce->num_interfaces += num; +	} +} + +  void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce)  {  	if ((ce->ce_flags & ZEND_ACC_INTERFACE) @@ -1834,6 +1850,8 @@ void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce)  	}  	ce->parent = parent_ce; +	/* Inherit interfaces */ +	zend_do_inherit_interfaces(ce, parent_ce);  	/* Inherit properties */  	zend_hash_merge(&ce->default_properties, &parent_ce->default_properties, (void (*)(void *)) zval_add_ref, NULL, sizeof(zval *), 0); @@ -1847,10 +1865,12 @@ void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce)  } -void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface) +ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface)  {  	zend_hash_merge(&ce->constants_table, &iface->constants_table, (void (*)(void *)) zval_add_ref, NULL, sizeof(zval *), 0);  	zend_hash_merge_ex(&ce->function_table, &iface->function_table, (copy_ctor_func_t) do_inherit_method, sizeof(zend_function), (merge_checker_func_t) do_inherit_method_check, ce); + +	zend_do_inherit_interfaces(ce, iface);  } @@ -2305,16 +2325,19 @@ static void do_verify_abstract_class(TSRMLS_D)  void zend_do_end_class_declaration(znode *class_token, znode *parent_token TSRMLS_DC)  { -	do_inherit_parent_constructor(CG(active_class_entry)); +	zend_class_entry *ce = CG(active_class_entry); + +	do_inherit_parent_constructor(ce); -	CG(active_class_entry)->line_end = zend_get_compiled_lineno(TSRMLS_C); +	ce->line_end = zend_get_compiled_lineno(TSRMLS_C); -	if (CG(active_class_entry)->num_interfaces > 0) { -		CG(active_class_entry)->interfaces = (zend_class_entry **) emalloc(sizeof(zend_class_entry *)*CG(active_class_entry)->num_interfaces); +	/* Inherit interfaces */ +	if (ce->num_interfaces > 0) { +		ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *)*ce->num_interfaces);  	} -	if (!(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) -		&& !(CG(active_class_entry)->ce_flags & ZEND_ACC_ABSTRACT_CLASS) -		&& ((parent_token->op_type != IS_UNUSED) || (CG(active_class_entry)->num_interfaces > 0))) { +	if (!(ce->ce_flags & ZEND_ACC_INTERFACE) +		&& !(ce->ce_flags & ZEND_ACC_ABSTRACT_CLASS) +		&& ((parent_token->op_type != IS_UNUSED) || (ce->num_interfaces > 0))) {  		do_verify_abstract_class(TSRMLS_C);  	}  	CG(active_class_entry) = NULL; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index b0cec1e7df..b1eb2e6d26 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -347,6 +347,8 @@ void zend_do_throw(znode *expr TSRMLS_DC);  ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, HashTable *class_table, int compile_time);  ZEND_API zend_class_entry *do_bind_class(zend_op *opline, HashTable *function_table, HashTable *class_table TSRMLS_DC);  ZEND_API zend_class_entry *do_bind_inherited_class(zend_op *opline, HashTable *function_table, HashTable *class_table, zend_class_entry *parent_ce TSRMLS_DC); +ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, zend_class_entry *ce2); +ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface);  void zend_do_implements_interface(znode *interface_znode TSRMLS_DC);  void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce); diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 20a967197d..9238857be0 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1431,16 +1431,15 @@ ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce, zend_class  {  	zend_uint i; +	for (i=0; i<instance_ce->num_interfaces; i++) { +		if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) { +			return 1; +		} +	}  	while (instance_ce) {  		if (instance_ce == ce) {  			return 1;  		} -		for (i=0; i<instance_ce->num_interfaces; i++) { - -			if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) { -				return 1; -			} -		}  		instance_ce = instance_ce->parent;  	}  | 
