Wez noticed the patch cannot handle

<?php
class A { function foo() {} }
class B extends A {}
class C extends B { function foo() {} }
?>

since class entry's function(method) table does not store
inherited functions.

(it seems it's better to store method in class at compile
time, rahter than resolving at run time. e.g. better
performance with cache products)

Anyway, here is new patch that checks all parents.

Tested scripts are

<?php
class A {
  function foo() { echo 'A';}
}
class B {
  function foo() { echo 'B';}
  function foo() { echo 'C';}
}
$A = new A;
$B = new B;
$A->foo();
$B->foo();
?>

<?php
class A { function foo() {} }
class B extends A {}
class C extends B { function foo() {} }
?>

<?php
class A { function foo() { echo 'A';}}
class B extends A {function foo() { echo 'B';}}
$A = new A;
$B = new B;
$A->foo();
$B->foo();
?>

--
Yasuo Ohgaki
/usr/bin/diff: conflicting specifications of output style
--- zend_compile.c.~1.226.~     Tue Mar 26 17:48:18 2002
+++ zend_compile.c      Thu Mar 28 10:33:11 2002
@@ -732,8 +732,23 @@
        op_array.return_reference = return_reference;
 
        if (is_method) {
-               if (zend_hash_add(&CG(active_class_entry)->function_table, name, 
name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == 
FAILURE) {
-                       zend_error(E_ERROR, "Cannot redeclare method %s()", name);
+               zend_class_entry *tmp;
+               void *dummy;
+               int overload = 0;
+               tmp = CG(active_class_entry)->parent;
+               while (tmp) {
+                       if (zend_hash_find(&(tmp->function_table), name, name_len+1, 
+(void **) &dummy) == SUCCESS) {
+                               overload = 1;
+                       }
+                       tmp = tmp->parent;
+               }
+               if (overload) {
+                       zend_hash_update(&CG(active_class_entry)->function_table, 
+name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array));
+               }
+               else {
+                       if (zend_hash_add(&CG(active_class_entry)->function_table, 
+name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) 
+== FAILURE) {
+                               zend_error(E_ERROR, "Cannot redeclare method %s()", 
+name);
+                       }
                }
        } else {
                zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to