cvs: ZendEngine2 / zend_API.c zend_compile.c zend_vm_def.h

From: Date: Wed, 07 Jun 2006 09:20:02 +0000
Subject: cvs: ZendEngine2 / zend_API.c zend_compile.c zend_vm_def.h
Groups: php.zend-engine.cvs 
Request: Send a blank email to php-zend-engine-cvs+get-4990@lists.php.net to get a copy of this message
helly Wed Jun 7 09:20:02 2006 UTC Modified files: /ZendEngine2 zend_API.c zend_vm_def.h zend_compile.c Log: - Fix issue with interfaces being inherited multiple times http://cvs.php.net/viewcvs.cgi/ZendEngine2/zend_API.c?r1=1.369&r2=1.370&diff_format=u Index: ZendEngine2/zend_API.c diff -u ZendEngine2/zend_API.c:1.369 ZendEngine2/zend_API.c:1.370 --- ZendEngine2/zend_API.c:1.369 Sun Jun 4 10:23:25 2006 +++ ZendEngine2/zend_API.c Wed Jun 7 09:20:02 2006 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.c,v 1.369 2006/06/04 10:23:25 helly Exp $ */ +/* $Id: zend_API.c,v 1.370 2006/06/07 09:20:02 helly Exp $ */ #include "zend.h" #include "zend_execute.h" @@ -2428,24 +2428,14 @@ ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...) { zend_class_entry *interface_entry; - int ce_num = class_entry->num_interfaces, impl_num; va_list interface_list; va_start(interface_list, num_interfaces); - if (class_entry->type & ZEND_INTERNAL_CLASS) { - class_entry->interfaces = realloc(class_entry->interfaces, sizeof(zend_class_entry*) * (class_entry->num_interfaces+num_interfaces)); - } else { - class_entry->interfaces = erealloc(class_entry->interfaces, sizeof(zend_class_entry*) * (class_entry->num_interfaces+num_interfaces)); - } - while (num_interfaces--) { interface_entry = va_arg(interface_list, zend_class_entry *); - class_entry->interfaces[class_entry->num_interfaces++] = interface_entry; - } - impl_num = class_entry->num_interfaces; - while(ce_num < impl_num) { - zend_do_implement_interface(class_entry, class_entry->interfaces[ce_num++] TSRMLS_CC); + zend_do_implement_interface(class_entry, interface_entry TSRMLS_CC); } + va_end(interface_list); } http://cvs.php.net/viewcvs.cgi/ZendEngine2/zend_vm_def.h?r1=1.115&r2=1.116&diff_format=u Index: ZendEngine2/zend_vm_def.h diff -u ZendEngine2/zend_vm_def.h:1.115 ZendEngine2/zend_vm_def.h:1.116 --- ZendEngine2/zend_vm_def.h:1.115 Sun May 28 19:45:02 2006 +++ ZendEngine2/zend_vm_def.h Wed Jun 7 09:20:02 2006 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_vm_def.h,v 1.115 2006/05/28 19:45:02 johannes Exp $ */ +/* $Id: zend_vm_def.h,v 1.116 2006/06/07 09:20:02 helly Exp $ */ /* If you change this file, please regenerate the zend_vm_execute.h and * zend_vm_opcodes.h files by running: @@ -3740,8 +3740,6 @@ zend_error_noreturn(E_ERROR, "%v cannot implement %v - it is not an interface", ce->name, iface->name); } - ce->interfaces[opline->extended_value] = iface; - zend_do_implement_interface(ce, iface TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); http://cvs.php.net/viewcvs.cgi/ZendEngine2/zend_compile.c?r1=1.714&r2=1.715&diff_format=u Index: ZendEngine2/zend_compile.c diff -u ZendEngine2/zend_compile.c:1.714 ZendEngine2/zend_compile.c:1.715 --- ZendEngine2/zend_compile.c:1.714 Tue Jun 6 14:16:53 2006 +++ ZendEngine2/zend_compile.c Wed Jun 7 09:20:02 2006 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.c,v 1.714 2006/06/06 14:16:53 tony2001 Exp $ */ +/* $Id: zend_compile.c,v 1.715 2006/06/07 09:20:02 helly Exp $ */ #include <zend_language_parser.h> #include "zend.h" @@ -2382,11 +2382,38 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) { - zend_hash_merge_ex(&ce->constants_table, &iface->constants_table, (copy_ctor_func_t) zval_add_ref, sizeof(zval *), (merge_checker_func_t) do_inherit_constant_check, iface); - 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); - - do_implement_interface(ce, iface TSRMLS_CC); - zend_do_inherit_interfaces(ce, iface TSRMLS_CC); + zend_uint i, ignore = 0; + zend_uint current_iface_num = ce->num_interfaces; + zend_uint parent_iface_num = ce->parent ? ce->parent->num_interfaces : 0; + + for (i = 0; i < ce->num_interfaces; i++) { + if (ce->interfaces[i] == NULL) { + memmove(ce->interfaces + i, ce->interfaces + i + 1, sizeof(zend_class_entry*) * (--ce->num_interfaces - i)); + i--; + } else if (ce->interfaces[i] == iface) { + if (i < parent_iface_num) { + ignore = 1; + } else { + zend_error(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name); + } + } + } + if (!ignore) { + if (ce->num_interfaces >= current_iface_num) { + if (ce->type == ZEND_INTERNAL_CLASS) { + ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num)); + } else { + ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num)); + } + } + ce->interfaces[ce->num_interfaces++] = iface; + + zend_hash_merge_ex(&ce->constants_table, &iface->constants_table, (copy_ctor_func_t) zval_add_ref, sizeof(zval *), (merge_checker_func_t) do_inherit_constant_check, iface); + 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); + + do_implement_interface(ce, iface TSRMLS_CC); + zend_do_inherit_interfaces(ce, iface TSRMLS_CC); + } } @@ -2965,11 +2992,6 @@ ce->line_end = zend_get_compiled_lineno(TSRMLS_C); - /* Inherit interfaces */ - if (ce->num_interfaces > 0) { - ce->interfaces = (zend_class_entry **) emalloc(sizeof(zend_class_entry *)*ce->num_interfaces); - memset(ce->interfaces, 0, sizeof(zend_class_entry *)*ce->num_interfaces); - } if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) && ((parent_token->op_type != IS_UNUSED) || (ce->num_interfaces > 0))) { zend_verify_abstract_class(ce TSRMLS_CC); @@ -2977,6 +2999,12 @@ do_verify_abstract_class(TSRMLS_C); } } + /* Inherit interfaces; reset number to zero, we need it for above check and + * will restore it during actual implementation. */ + if (ce->num_interfaces > 0) { + ce->interfaces = NULL; + ce->num_interfaces = 0; + } CG(active_class_entry) = NULL; }

« previous php.zend-engine.cvs (#4990) next »