On Tue, 2002-06-11 at 00:04, Timm Friebe wrote: > ZE2 has a bug... Well, replying to myself:-) I took some time to have a look at where the bugs occur (see my original email to [EMAIL PROTECTED], sent 11 Jun 2002 00:04:09 +0200) and think I got rid of them.
> concerning the keyword "parent" and the way it behaves
> erroneously in a situation like this:
[...Source...]
> thekid@friebes:~/devel/php-4.3.0-dev-zend2-alpha1 > ./php -q
> test.ze2.php
> int(2039)
> string(9) "2.0.0-dev"
> string(9) "4.3.0-dev"
> <br />
> <b>Warning</b>: Missing argument 1 for __construct()
> in
> <b>/usr/home/thekid/devel/php-4.3.0-dev-zend2-alpha1/test.ze2.php</b> on
> line <b>12</b><br />
> NULL
> ===> Result: object(ioexception)(1) {
> ["message"]=>
> NULL
> }
The problem was the usage of the keyword "parent" and extending classes
while not overwriting - say - the constructor (or any other function) -
which then gets called for each inheritance. The problem had been fixed
in Zend Engine 1 in Version 1.200 - but since now scopes have been
introduced and everything works quite different,
CG(active_ce_parent_class_name) of course will not do.
http://cvs.php.net/diff.php/Zend/zend_compile.c?r1=1.199&r2=1.200&ty=u
Attached is a patch to zend_execute.c which does the job.
[...Source...]
> Moving the contents of C.class.php into test-2.ze2.php will work:
[...whereas if require()'d, it won't...]
> I believe this is exactly the same as described in
> http://bugs.php.net/bug.php?id=12313 - maybe the patches made to ZE1
> then never made it to the ZE2 branch?
Well, sort of:-) The problem was with runtime inheritance which is
performed when classes extend classes in require()'d files, realized in
do_inherit_parent_constructor(zend_class_entry *ce) - searching for the
constructor by the name of the class only and not for __construct.
The hashtable lookups can be replaced by simply checking on and using
the much neater "constructor" field in zend_class_entry, I guess.
Last but not least, the runtime inheritance of the destructor was
completely forgotten, the attached patch to zend_compile.c solves both
issues.
Hope it helps & keep up the good work:-)
--
Timm Friebe
--- php-4.3.0-dev-zend2-alpha1/Zend/zend_compile.c Tue Apr 23 20:06:53 2002
+++ php-4.3.0-dev-zend2-alpha1pl2/Zend/zend_compile.c Sat Jun 22 21:16:00 2002
@@ -1475,19 +1476,19 @@
}
}
-
-static void do_inherit_parent_constructor(zend_class_entry *ce)
+
+static void do_inherit_parent_special_methods(zend_class_entry *ce)
{
- if (ce->parent
- && !zend_hash_exists(&ce->function_table, ce->name, ce->name_length+1)) {
- zend_function *function;
-
- if (zend_hash_find(&ce->parent->function_table, ce->parent->name, ce->parent->name_length+1, (void **) &function)==SUCCESS) {
- /* inherit parent's constructor */
- zend_hash_update(&ce->function_table, ce->name, ce->name_length+1, function, sizeof(zend_function), NULL);
- function_add_ref(function);
- }
- }
+
+ if (ce->parent) {
+ if (!ce->constructor)
+ ce->constructor = ce->parent->constructor;
+
+ if (!ce->destructor)
+ ce->destructor = ce->parent->destructor;
+
+ /* FIXME: What to do with clone? */
+ }
}
void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce)
@@ -1508,7 +1509,7 @@
ce->handle_property_set = parent_ce->handle_property_set;
if (!ce->handle_function_call)
ce->handle_function_call = parent_ce->handle_function_call;
- do_inherit_parent_constructor(ce);
+ do_inherit_parent_special_methods(ce);
}
static void create_class(HashTable *class_table, char *name, int name_length, zend_class_entry **ce)
@@ -2129,7 +2130,7 @@
void zend_do_end_class_declaration(znode *class_token TSRMLS_DC)
{
- do_inherit_parent_constructor(CG(active_class_entry));
+ do_inherit_parent_special_methods(CG(active_class_entry));
CG(active_class_entry) = class_token->u.previously_active_class_entry;
if (CG(active_ce_parent_class_name).value.str.val) {
efree(CG(active_ce_parent_class_name).value.str.val);
--- php-4.3.0-dev-zend2-alpha1/Zend/zend_execute.c Wed May 8 20:43:19 2002
+++ php-4.3.0-dev-zend2-alpha1pl2/Zend/zend_execute.c Sat Jun 22 21:15:51 2002
@@ -1818,7 +1818,9 @@
if (!EG(scope)->parent) {
zend_error(E_ERROR, "Cannot fetch parent:: as current class scope has no parent");
}
- EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EG(scope)->parent;
+ EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EX(function_state).function->common.scope->parent;
+
NEXT_OPCODE();
}
test-1.ze2.php
Description: application/php
test-2.ze2.php
Description: application/php
-- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php
