cvs: ZendEngine2 / zend_API.c zend_compile.c zend_vm_def.h
| From: | Marcus Boerger | 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;
}