dmitry          Thu Jul 24 09:42:21 2008 UTC

  Added files:                 (Branch: PHP_5_3)
    /ZendEngine2/tests  lsb_021.phpt lsb_022.phpt 

  Modified files:              
    /ZendEngine2        zend_API.c zend_API.h zend_execute_API.c 
                        zend_interfaces.c zend_vm_def.h zend_vm_execute.h 
    /ZendEngine2/tests  bug45186.phpt bug45186_2.phpt lsb_015.phpt 
                        lsb_019.phpt lsb_020.phpt objects_027.phpt 
    /php-src/ext/spl    php_spl.c 
    /php-src/ext/standard       basic_functions.c 
    /php-src/ext/standard/tests/array   array_map_object2.phpt 
  Log:
  LSB parent/self forwarding
  
  
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_API.c?r1=1.296.2.27.2.34.2.40&r2=1.296.2.27.2.34.2.41&diff_format=u
Index: ZendEngine2/zend_API.c
diff -u ZendEngine2/zend_API.c:1.296.2.27.2.34.2.40 
ZendEngine2/zend_API.c:1.296.2.27.2.34.2.41
--- ZendEngine2/zend_API.c:1.296.2.27.2.34.2.40 Mon Jul 14 12:18:20 2008
+++ ZendEngine2/zend_API.c      Thu Jul 24 09:42:15 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_API.c,v 1.296.2.27.2.34.2.40 2008/07/14 12:18:20 dmitry Exp $ */
+/* $Id: zend_API.c,v 1.296.2.27.2.34.2.41 2008/07/24 09:42:15 dmitry Exp $ */
 
 #include "zend.h"
 #include "zend_execute.h"
@@ -2305,21 +2305,69 @@
 }
 /* }}} */
 
-static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, 
zend_class_entry *ce_org, zval *callable, zend_class_entry **ce_ptr, 
zend_function **fptr_ptr, char **error TSRMLS_DC) /* {{{ */
+static int zend_is_callable_check_class(char *name, int name_len, 
zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
 {
+       int ret = 0;
+       zend_class_entry **pce;
+       char *lcname = zend_str_tolower_dup(name, name_len);
+
+       if (name_len == sizeof("self") - 1 &&
+           !memcmp(lcname, "self", sizeof("self") - 1)) {
+               if (!EG(scope)) {
+                       if (error) *error = estrdup("cannot access self:: when 
no class scope is active");
+               } else {
+                       fcc->called_scope = EG(called_scope);
+                       fcc->calling_scope = EG(scope);
+                       ret = 1;
+               }
+       } else if (name_len == sizeof("parent") - 1 && 
+                      !memcmp(lcname, "parent", sizeof("parent") - 1)) {
+               if (!EG(scope)) {
+                       if (error) *error = estrdup("cannot access parent:: 
when no class scope is active");
+               } else if (!EG(scope)->parent) {
+                       if (error) *error = estrdup("cannot access parent:: 
when current class scope has no parent");
+               } else {
+                       fcc->called_scope = EG(called_scope);
+                       fcc->calling_scope = EG(scope)->parent;
+                       ret = 1;
+               }
+       } else if (name_len == sizeof("static") - 1 &&
+                  !memcmp(lcname, "static", sizeof("static") - 1)) {
+               if (!EG(called_scope)) {
+                       if (error) *error = estrdup("cannot access static:: 
when no class scope is active");
+               } else {
+                       fcc->called_scope = EG(called_scope);
+                       fcc->calling_scope = EG(called_scope);
+                       ret = 1;
+               }
+       } else if (zend_lookup_class_ex(name, name_len, 1, &pce TSRMLS_CC) == 
SUCCESS) {
+               fcc->called_scope = fcc->calling_scope = *pce;
+               ret = 1;
+       } else {
+               if (error) zend_spprintf(error, 0, "class '%.*s' not found", 
name_len, name);
+       }
+       efree(lcname);
+       return ret;
+}
+/* }}} */
+
+
+static int zend_is_callable_check_func(int check_flags, zval *callable, 
zend_fcall_info_cache *fcc, char **error TSRMLS_DC) /* {{{ */
+{
+       zend_class_entry *ce_org = fcc->calling_scope;
        int retval;
        char *lmname, *colon;
        int clen, mlen;
-       zend_function *fptr;
        zend_class_entry *last_scope;
        HashTable *ftable;
+       int call_via_handler = 0;
 
        if (error) {
                *error = NULL;
        }
 
-       *ce_ptr = NULL;
-       *fptr_ptr = NULL;
+       fcc->calling_scope = NULL;
+       fcc->function_handler = NULL;
 
        if (!ce_org) {
                /* Skip leading :: */
@@ -2334,8 +2382,7 @@
                }
                /* Check if function with given name exists.
                 * This may be a compound name that includes namespace name */
-               if (zend_hash_find(EG(function_table), lmname, mlen+1, 
(void**)&fptr) == SUCCESS) {
-                       *fptr_ptr = fptr;
+               if (zend_hash_find(EG(function_table), lmname, mlen+1, 
(void**)&fcc->function_handler) == SUCCESS) {
                        efree(lmname);
                        return 1;
                }
@@ -2363,15 +2410,16 @@
                if (ce_org) {
                        EG(scope) = ce_org;
                }
-               *ce_ptr = zend_fetch_class(Z_STRVAL_P(callable), clen, 
ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_SILENT TSRMLS_CC);
-               EG(scope) = last_scope;
-               if (!*ce_ptr) {
-                       if (error) zend_spprintf(error, 0, "class '%.*Z' not 
found", clen, callable);
+
+               if (!zend_is_callable_check_class(Z_STRVAL_P(callable), clen, 
fcc, error TSRMLS_CC)) {
+                       EG(scope) = last_scope;
                        return 0;
                }
-               ftable = &(*ce_ptr)->function_table;
-               if (ce_org && !instanceof_function(ce_org, *ce_ptr TSRMLS_CC)) {
-                       if (error) zend_spprintf(error, 0, "class '%s' is not a 
subclass of '%s'", ce_org->name, (*ce_ptr)->name);
+               EG(scope) = last_scope;
+
+               ftable = &fcc->calling_scope->function_table;
+               if (ce_org && !instanceof_function(ce_org, fcc->calling_scope 
TSRMLS_CC)) {
+                       if (error) zend_spprintf(error, 0, "class '%s' is not a 
subclass of '%s'", ce_org->name, fcc->calling_scope->name);
                        return 0;
                }
                lmname = zend_str_tolower_dup(Z_STRVAL_P(callable) + clen + 2, 
mlen);
@@ -2380,49 +2428,51 @@
                mlen = Z_STRLEN_P(callable);
                lmname = zend_str_tolower_dup(Z_STRVAL_P(callable), 
Z_STRLEN_P(callable));
                ftable = &ce_org->function_table;
-               *ce_ptr = ce_org;
+               fcc->calling_scope = ce_org;
        } else {
                /* We already checked for plain function before. */
                if (error) zend_spprintf(error, 0, "function '%s' not found or 
invalid function name", Z_STRVAL_P(callable));
                return 0;
        }
 
-       retval = zend_hash_find(ftable, lmname, mlen+1, (void**)&fptr) == 
SUCCESS ? 1 : 0;
+       retval = zend_hash_find(ftable, lmname, mlen+1, 
(void**)&fcc->function_handler) == SUCCESS ? 1 : 0;
 
        if (!retval) {
-               if (*zobj_ptr_ptr && *ce_ptr && (*ce_ptr)->__call != 0) {
-                       retval = (*ce_ptr)->__call != NULL;
-                       *fptr_ptr = (*ce_ptr)->__call;
+               if (fcc->object_pp && fcc->calling_scope && 
fcc->calling_scope->__call != 0) {
+                       retval = 1;
+                       call_via_handler = 1;
+                       fcc->function_handler = fcc->calling_scope->__call;
                } else {
-                       if (!*zobj_ptr_ptr && *ce_ptr && 
((*ce_ptr)->__callstatic || (*ce_ptr)->__call)) {
-                               if ((*ce_ptr)->__call &&
+                       if (!fcc->object_pp && fcc->calling_scope && 
(fcc->calling_scope->__callstatic || fcc->calling_scope->__call)) {
+                               if (fcc->calling_scope->__call &&
                                        EG(This) &&
                                Z_OBJ_HT_P(EG(This))->get_class_entry &&
-                               instanceof_function(Z_OBJCE_P(EG(This)), 
*ce_ptr TSRMLS_CC)) {
+                               instanceof_function(Z_OBJCE_P(EG(This)), 
fcc->calling_scope TSRMLS_CC)) {
                                        retval = 1;
-                                       *fptr_ptr = (*ce_ptr)->__call;
-                                       *zobj_ptr_ptr = &EG(This);
-                               } else if ((*ce_ptr)->__callstatic) {
+                                       call_via_handler = 1;
+                                       fcc->function_handler = 
fcc->calling_scope->__call;
+                                       fcc->object_pp = &EG(This);
+                               } else if (fcc->calling_scope->__callstatic) {
                                        retval = 1;
-                                       *fptr_ptr = (*ce_ptr)->__callstatic;
+                                       call_via_handler = 1;
+                                       fcc->function_handler = 
fcc->calling_scope->__callstatic;
                                }
                        }
 
                        if (retval == 0) {
-                               if (*ce_ptr) {
-                                       if (error) zend_spprintf(error, 0, 
"class '%s' does not have a method '%s'", (*ce_ptr)->name, lmname);
+                               if (fcc->calling_scope) {
+                                       if (error) zend_spprintf(error, 0, 
"class '%s' does not have a method '%s'", fcc->calling_scope->name, lmname);
                                } else {
                                        if (error) zend_spprintf(error, 0, 
"function '%s' does not exist", lmname);
                                }
                        }
                }
        } else {
-               *fptr_ptr = fptr;
-               if (*ce_ptr) {
-                       if (!*zobj_ptr_ptr && !(fptr->common.fn_flags & 
ZEND_ACC_STATIC)) {
+               if (fcc->calling_scope) {
+                       if (!fcc->object_pp && 
!(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) {
                                int severity;
                                char *verb;
-                               if (fptr->common.fn_flags & 
ZEND_ACC_ALLOW_STATIC) {
+                               if (fcc->function_handler->common.fn_flags & 
ZEND_ACC_ALLOW_STATIC) {
                                        severity = E_STRICT;
                                        verb = "should not";
                                } else {
@@ -2433,39 +2483,39 @@
                                if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) 
!= 0) {
                                        retval = 0;
                                }
-                               if (EG(This) && 
instanceof_function(Z_OBJCE_P(EG(This)), *ce_ptr TSRMLS_CC)) {
-                                       *zobj_ptr_ptr = &EG(This);
+                               if (EG(This) && 
instanceof_function(Z_OBJCE_P(EG(This)), fcc->calling_scope TSRMLS_CC)) {
+                                       fcc->object_pp = &EG(This);
                                        if (error) {
-                                               zend_spprintf(error, 0, 
"non-static method %s::%s() %s be called statically, assuming $this from 
compatible context %s", (*ce_ptr)->name, fptr->common.function_name, verb, 
Z_OBJCE_P(EG(This))->name);
+                                               zend_spprintf(error, 0, 
"non-static method %s::%s() %s be called statically, assuming $this from 
compatible context %s", fcc->calling_scope->name, 
fcc->function_handler->common.function_name, verb, Z_OBJCE_P(EG(This))->name);
                                        } else if (retval) {
-                                               zend_error(severity, 
"Non-static method %s::%s() %s be called statically, assuming $this from 
compatible context %s", (*ce_ptr)->name, fptr->common.function_name, verb, 
Z_OBJCE_P(EG(This))->name);
+                                               zend_error(severity, 
"Non-static method %s::%s() %s be called statically, assuming $this from 
compatible context %s", fcc->calling_scope->name, 
fcc->function_handler->common.function_name, verb, Z_OBJCE_P(EG(This))->name);
                                        }
                                } else {
                                        if (error) {
-                                               zend_spprintf(error, 0, 
"non-static method %s::%s() %s be called statically", (*ce_ptr)->name, 
fptr->common.function_name, verb);
+                                               zend_spprintf(error, 0, 
"non-static method %s::%s() %s be called statically", fcc->calling_scope->name, 
fcc->function_handler->common.function_name, verb);
                                        } else if (retval) {
-                                               zend_error(severity, 
"Non-static method %s::%s() %s be called statically", (*ce_ptr)->name, 
fptr->common.function_name, verb);
+                                               zend_error(severity, 
"Non-static method %s::%s() %s be called statically", fcc->calling_scope->name, 
fcc->function_handler->common.function_name, verb);
                                        }
                                }
                        }
                        if (retval && (check_flags & 
IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
-                               if (fptr->op_array.fn_flags & ZEND_ACC_PRIVATE) 
{
-                                       if (!zend_check_private(fptr, 
*zobj_ptr_ptr ? Z_OBJCE_PP(*zobj_ptr_ptr) : EG(scope), lmname, mlen TSRMLS_CC)) 
{
+                               if (fcc->function_handler->op_array.fn_flags & 
ZEND_ACC_PRIVATE) {
+                                       if 
(!zend_check_private(fcc->function_handler, fcc->object_pp ? 
Z_OBJCE_PP(fcc->object_pp) : EG(scope), lmname, mlen TSRMLS_CC)) {
                                                if (error) {
                                                        if (*error) {
                                                                efree(*error);
                                                        }
-                                                       zend_spprintf(error, 0, 
"cannot access private method %s::%s()", (*ce_ptr)->name, 
fptr->common.function_name);
+                                                       zend_spprintf(error, 0, 
"cannot access private method %s::%s()", fcc->calling_scope->name, 
fcc->function_handler->common.function_name);
                                                }
                                                retval = 0;
                                        }
-                               } else if ((fptr->common.fn_flags & 
ZEND_ACC_PROTECTED)) {
-                                       if 
(!zend_check_protected(fptr->common.scope, EG(scope))) {
+                               } else if 
((fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED)) {
+                                       if 
(!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
                                                if (error) {
                                                        if (*error) {
                                                                efree(*error);
                                                        }
-                                                       zend_spprintf(error, 0, 
"cannot access protected method %s::%s()", (*ce_ptr)->name, 
fptr->common.function_name);
+                                                       zend_spprintf(error, 0, 
"cannot access protected method %s::%s()", fcc->calling_scope->name, 
fcc->function_handler->common.function_name);
                                                }
                                                retval = 0;
                                        }
@@ -2473,18 +2523,21 @@
                        }
                }
        }
+       if (fcc->object_pp) {
+               fcc->called_scope = Z_OBJCE_PP(fcc->object_pp);
+       }
        efree(lmname);
+       if (retval && !call_via_handler) {
+               fcc->initialized = 1;
+       }
        return retval;
 }
 /* }}} */
 
-ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char 
**callable_name, int *callable_name_len, zend_class_entry **ce_ptr, 
zend_function **fptr_ptr, zval ***zobj_ptr_ptr, char **error TSRMLS_DC) /* {{{ 
*/
+ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char 
**callable_name, int *callable_name_len, zend_fcall_info_cache *fcc, char 
**error TSRMLS_DC) /* {{{ */
 {
-       char *lcname;
        int callable_name_len_local;
-       zend_class_entry *ce_local, **pce;
-       zend_function *fptr_local;
-       zval **zobj_ptr_local;
+       zend_fcall_info_cache fcc_local;
 
        if (callable_name) {
                *callable_name = NULL;
@@ -2492,21 +2545,19 @@
        if (callable_name_len == NULL) {
                callable_name_len = &callable_name_len_local;
        }
-       if (ce_ptr == NULL) {
-               ce_ptr = &ce_local;
-       }
-       if (fptr_ptr == NULL) {
-               fptr_ptr = &fptr_local;
-       }
-       if (zobj_ptr_ptr == NULL) {
-               zobj_ptr_ptr = &zobj_ptr_local;
+       if (fcc == NULL) {
+               fcc = &fcc_local;
        }
        if (error) {
                *error = NULL;
        }
-       *ce_ptr = NULL;
-       *fptr_ptr = NULL;
-       *zobj_ptr_ptr = NULL;
+       
+       fcc->initialized = 0;
+       fcc->calling_scope = NULL;
+       fcc->called_scope = NULL;
+       fcc->function_handler = NULL;
+       fcc->calling_scope = NULL;
+       fcc->object_pp = NULL;
 
        switch (Z_TYPE_P(callable)) {
                case IS_STRING:
@@ -2518,11 +2569,10 @@
                                return 1;
                        }
 
-                       return zend_is_callable_check_func(check_flags, 
zobj_ptr_ptr, NULL, callable, ce_ptr, fptr_ptr, error TSRMLS_CC);
+                       return zend_is_callable_check_func(check_flags, 
callable, fcc, error TSRMLS_CC);
 
                case IS_ARRAY:
                        {
-                               zend_class_entry *ce = NULL;
                                zval **method = NULL;
                                zval **obj = NULL;
 
@@ -2552,51 +2602,34 @@
                                                        return 1;
                                                }
 
-                                               lcname = 
zend_str_tolower_dup(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj));
-
-                                               if (EG(active_op_array) &&
-                                                       Z_STRLEN_PP(obj) == 
sizeof("self") - 1 &&
-                                                       !memcmp(lcname, "self", 
sizeof("self") - 1)) {
-                                                       ce = 
EG(active_op_array)->scope;
-                                               } else if (EG(active_op_array) 
&& EG(active_op_array)->scope &&
-                                                       Z_STRLEN_PP(obj) == 
sizeof("parent") - 1 && 
-                                                       !memcmp(lcname, 
"parent", sizeof("parent") - 1)) {
-                                                       ce = 
EG(active_op_array)->scope->parent;
-                                               } else if (Z_STRLEN_PP(obj) == 
sizeof("static") - 1 &&
-                                                       !memcmp(lcname, 
"static", sizeof("static") - 1)) {
-                                                       ce = EG(called_scope);
-                                               } else if 
(zend_lookup_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), &pce TSRMLS_CC) == 
SUCCESS) {
-                                                       ce = *pce;
+                                               if 
(!zend_is_callable_check_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), fcc, error 
TSRMLS_CC)) {
+                                                       return 0;
                                                }
-                                               efree(lcname);
+
                                        } else {
-                                               ce = Z_OBJCE_PP(obj); /* 
TBFixed: what if it's overloaded? */
+                                               fcc->calling_scope = 
Z_OBJCE_PP(obj); /* TBFixed: what if it's overloaded? */
 
-                                               *zobj_ptr_ptr = obj;
+                                               fcc->object_pp = obj;
 
                                                if (callable_name) {
                                                        char *ptr;
 
-                                                       *callable_name_len = 
ce->name_length + Z_STRLEN_PP(method) + sizeof("::") - 1;
+                                                       *callable_name_len = 
fcc->calling_scope->name_length + Z_STRLEN_PP(method) + sizeof("::") - 1;
                                                        ptr = *callable_name = 
emalloc(*callable_name_len + 1);
-                                                       memcpy(ptr, ce->name, 
ce->name_length);
-                                                       ptr += ce->name_length;
+                                                       memcpy(ptr, 
fcc->calling_scope->name, fcc->calling_scope->name_length);
+                                                       ptr += 
fcc->calling_scope->name_length;
                                                        memcpy(ptr, "::", 
sizeof("::") - 1);
                                                        ptr += sizeof("::") - 1;
                                                        memcpy(ptr, 
Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1);
                                                }
 
                                                if (check_flags & 
IS_CALLABLE_CHECK_SYNTAX_ONLY) {
-                                                       *ce_ptr = ce;
+                                                       fcc->called_scope = 
fcc->calling_scope;
                                                        return 1;
                                                }
                                        }
 
-                                       if (ce) {
-                                               return 
zend_is_callable_check_func(check_flags, zobj_ptr_ptr, ce, *method, ce_ptr, 
fptr_ptr, error TSRMLS_CC);
-                                       } else {
-                                               if (error) zend_spprintf(error, 
0, "first array member is not a valid %s", Z_TYPE_PP(obj) == IS_STRING ? "class 
name" : "object");
-                                       }
+                                       return 
zend_is_callable_check_func(check_flags, *method, fcc, error TSRMLS_CC);
                                } else {
                                        if 
(zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
                                                if (!obj || (Z_TYPE_PP(obj) != 
IS_STRING && Z_TYPE_PP(obj) != IS_OBJECT)) {
@@ -2612,12 +2645,12 @@
                                                *callable_name_len = 
sizeof("Array") - 1;
                                        }
                                }
-                               *ce_ptr = ce;
                        }
                        return 0;
 
                case IS_OBJECT:
-                       if (zend_get_closure(callable, ce_ptr, fptr_ptr, NULL, 
zobj_ptr_ptr TSRMLS_CC) == SUCCESS) {
+                       if (zend_get_closure(callable, &fcc->calling_scope, 
&fcc->function_handler, NULL, &fcc->object_pp TSRMLS_CC) == SUCCESS) {
+                               fcc->called_scope = fcc->calling_scope;
                                if (callable_name) {
                                        zend_class_entry *ce = 
Z_OBJCE_P(callable); /* TBFixed: what if it's overloaded? */
 
@@ -2650,22 +2683,20 @@
 {
        TSRMLS_FETCH();
 
-       return zend_is_callable_ex(callable, check_flags, callable_name, NULL, 
NULL, NULL, NULL, NULL TSRMLS_CC);
+       return zend_is_callable_ex(callable, check_flags, callable_name, NULL, 
NULL, NULL TSRMLS_CC);
 }
 /* }}} */
 
 ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name 
TSRMLS_DC) /* {{{ */
 {
-       zend_class_entry *ce;
-       zend_function *fptr;
-       zval **zobj_ptr;
+       zend_fcall_info_cache fcc;
 
-       if (zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, 
NULL, &ce, &fptr, &zobj_ptr, NULL TSRMLS_CC)) {
-               if (Z_TYPE_P(callable) == IS_STRING && ce) {
+       if (zend_is_callable_ex(callable, IS_CALLABLE_STRICT, callable_name, 
NULL, &fcc, NULL TSRMLS_CC)) {
+               if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) {
                        zval_dtor(callable);
                        array_init(callable);
-                       add_next_index_string(callable, ce->name, 1);
-                       add_next_index_string(callable, 
fptr->common.function_name, 1);
+                       add_next_index_string(callable, 
fcc.calling_scope->name, 1);
+                       add_next_index_string(callable, 
fcc.function_handler->common.function_name, 1);
                }
                return 1;
        }
@@ -2675,18 +2706,13 @@
 
 ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, 
zend_fcall_info *fci, zend_fcall_info_cache *fcc, char **callable_name, char 
**error TSRMLS_DC) /* {{{ */
 {
-       int len;
-       zend_class_entry *ce;
-       zend_function *func;
-       zval **obj;
-
-       if (!zend_is_callable_ex(callable, check_flags, callable_name, NULL, 
&ce, &func, &obj, error TSRMLS_CC)) {
+       if (!zend_is_callable_ex(callable, check_flags, callable_name, NULL, 
fcc, error TSRMLS_CC)) {
                return FAILURE;
        }
 
        fci->size = sizeof(*fci);
-       fci->function_table = ce ? &ce->function_table : EG(function_table);
-       fci->object_pp = obj;
+       fci->function_table = fcc->calling_scope ? 
&fcc->calling_scope->function_table : EG(function_table);
+       fci->object_pp = fcc->object_pp;
        fci->function_name = callable;
        fci->retval_ptr_ptr = NULL;
        fci->param_count = 0;
@@ -2694,24 +2720,6 @@
        fci->no_separation = 1;
        fci->symbol_table = NULL;
 
-       if (ce) {
-               len = strlen(func->common.function_name);
-               if ((len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && 
!zend_binary_strcasecmp(func->common.function_name, len, ZEND_CALL_FUNC_NAME, 
sizeof(ZEND_CALL_FUNC_NAME) - 1)) ||
-                       (len == sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1 && 
!zend_binary_strcasecmp(func->common.function_name, len, 
ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1))
-               ) {
-                       fcc->initialized = 0;
-                       fcc->function_handler = NULL;
-                       fcc->calling_scope = NULL;
-                       fcc->object_pp = NULL;
-                       return SUCCESS;
-               }
-       }
-
-       fcc->initialized = 1;
-       fcc->function_handler = func;
-       fcc->calling_scope = ce;
-       fcc->object_pp = obj;
-
        return SUCCESS;
 }
 /* }}} */
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_API.h?r1=1.207.2.8.2.8.2.13&r2=1.207.2.8.2.8.2.14&diff_format=u
Index: ZendEngine2/zend_API.h
diff -u ZendEngine2/zend_API.h:1.207.2.8.2.8.2.13 
ZendEngine2/zend_API.h:1.207.2.8.2.8.2.14
--- ZendEngine2/zend_API.h:1.207.2.8.2.8.2.13   Fri Jun 27 21:16:41 2008
+++ ZendEngine2/zend_API.h      Thu Jul 24 09:42:15 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_API.h,v 1.207.2.8.2.8.2.13 2008/06/27 21:16:41 stas Exp $ */
+/* $Id: zend_API.h,v 1.207.2.8.2.8.2.14 2008/07/24 09:42:15 dmitry Exp $ */
 
 #ifndef ZEND_API_H
 #define ZEND_API_H
@@ -40,6 +40,26 @@
        zend_uint flags;
 } zend_function_entry;
 
+typedef struct _zend_fcall_info {
+       size_t size;
+       HashTable *function_table;
+       zval *function_name;
+       HashTable *symbol_table;
+       zval **retval_ptr_ptr;
+       zend_uint param_count;
+       zval ***params;
+       zval **object_pp;
+       zend_bool no_separation;
+} zend_fcall_info;
+
+typedef struct _zend_fcall_info_cache {
+       zend_bool initialized;
+       zend_function *function_handler;
+       zend_class_entry *calling_scope;
+       zend_class_entry *called_scope;
+       zval **object_pp;
+} zend_fcall_info_cache;
+
 #define ZEND_NS_NAME(ns, name)                 ns"::"name
 
 #define ZEND_FN(name) zif_##name
@@ -256,7 +276,7 @@
 
 #define IS_CALLABLE_STRICT  (IS_CALLABLE_CHECK_IS_STATIC)
 
-ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char 
**callable_name, int *callable_name_len, zend_class_entry **ce_ptr, 
zend_function **fptr_ptr, zval ***zobj_ptr_ptr, char **error TSRMLS_DC);
+ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char 
**callable_name, int *callable_name_len, zend_fcall_info_cache *fcc, char 
**error TSRMLS_DC);
 ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char 
**callable_name);
 ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name 
TSRMLS_DC);
 ZEND_API const char *zend_get_module_version(const char *module_name);
@@ -405,28 +425,7 @@
 
 ZEND_API int call_user_function(HashTable *function_table, zval **object_pp, 
zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] 
TSRMLS_DC);
 ZEND_API int call_user_function_ex(HashTable *function_table, zval 
**object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, 
zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC);
-END_EXTERN_C()
 
-typedef struct _zend_fcall_info {
-       size_t size;
-       HashTable *function_table;
-       zval *function_name;
-       HashTable *symbol_table;
-       zval **retval_ptr_ptr;
-       zend_uint param_count;
-       zval ***params;
-       zval **object_pp;
-       zend_bool no_separation;
-} zend_fcall_info;
-
-typedef struct _zend_fcall_info_cache {
-       zend_bool initialized;
-       zend_function *function_handler;
-       zend_class_entry *calling_scope;
-       zval **object_pp;
-} zend_fcall_info_cache;
-
-BEGIN_EXTERN_C()
 ZEND_API extern zend_fcall_info empty_fcall_info;
 ZEND_API extern zend_fcall_info_cache empty_fcall_info_cache;
 
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_execute_API.c?r1=1.331.2.20.2.24.2.43&r2=1.331.2.20.2.24.2.44&diff_format=u
Index: ZendEngine2/zend_execute_API.c
diff -u ZendEngine2/zend_execute_API.c:1.331.2.20.2.24.2.43 
ZendEngine2/zend_execute_API.c:1.331.2.20.2.24.2.44
--- ZendEngine2/zend_execute_API.c:1.331.2.20.2.24.2.43 Mon Jul 14 09:49:00 2008
+++ ZendEngine2/zend_execute_API.c      Thu Jul 24 09:42:15 2008
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_execute_API.c,v 1.331.2.20.2.24.2.43 2008/07/14 09:49:00 dmitry 
Exp $ */
+/* $Id: zend_execute_API.c,v 1.331.2.20.2.24.2.44 2008/07/24 09:42:15 dmitry 
Exp $ */
 
 #include <stdio.h>
 #include <signal.h>
@@ -41,7 +41,7 @@
 
 /* true globals */
 ZEND_API zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, 
NULL, NULL, 0 };
-ZEND_API zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL 
};
+ZEND_API zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, 
NULL };
 
 #ifdef ZEND_WIN32
 #include <process.h>
@@ -684,6 +684,7 @@
        zend_class_entry *current_scope;
        zend_class_entry *current_called_scope;
        zend_class_entry *calling_scope = NULL;
+       zend_class_entry *called_scope = NULL;
        zend_class_entry *check_scope_or_static = NULL;
        zval *current_this;
        zend_execute_data execute_data;
@@ -758,24 +759,26 @@
                                        return FAILURE;
                                }
 
-                               calling_scope = Z_OBJCE_PP(fci->object_pp);
+                               calling_scope = called_scope = 
Z_OBJCE_PP(fci->object_pp);
                                fci->function_table = 
&calling_scope->function_table;
                                EX(object) = *fci->object_pp;
                        } else if (Z_TYPE_PP(fci->object_pp) == IS_STRING) {
                                zend_class_entry **ce;
                                int found = FAILURE;
 
-                               if (EG(active_op_array) && 
strcmp(Z_STRVAL_PP(fci->object_pp), "self") == 0) {
-                                       if (!EG(active_op_array)->scope) {
+                               if (strcmp(Z_STRVAL_PP(fci->object_pp), "self") 
== 0) {
+                                       if (!EG(active_op_array) || 
!EG(active_op_array)->scope) {
                                                zend_error(E_ERROR, "Cannot 
access self:: when no class scope is active");
                                        }
                                        ce = &(EG(active_op_array)->scope);
                                        found = (*ce != NULL?SUCCESS:FAILURE);
                                        fci->object_pp = 
EG(This)?&EG(This):NULL;
                                        EX(object) = EG(This);
+                                       calling_scope = *ce;
+                                       called_scope = EG(called_scope) ? 
EG(called_scope) : calling_scope;
                                } else if (strcmp(Z_STRVAL_PP(fci->object_pp), 
"parent") == 0 && EG(active_op_array)) {
 
-                                       if (!EG(active_op_array)->scope) {
+                                       if (!EG(active_op_array) || 
!EG(active_op_array)->scope) {
                                                zend_error(E_ERROR, "Cannot 
access parent:: when no class scope is active");
                                        }
                                        if 
(!EG(active_op_array)->scope->parent) {
@@ -785,6 +788,8 @@
                                        found = (*ce != NULL?SUCCESS:FAILURE);
                                        fci->object_pp = 
EG(This)?&EG(This):NULL;
                                        EX(object) = EG(This);
+                                       calling_scope = *ce;
+                                       called_scope = EG(called_scope) ? 
EG(called_scope) : calling_scope;
                                } else if (Z_STRLEN_PP(fci->object_pp) == 
sizeof("static") - 1 &&
                                        !memcmp(Z_STRVAL_PP(fci->object_pp), 
"static", sizeof("static") - 1)
                                ) {
@@ -792,9 +797,10 @@
                                                zend_error(E_ERROR, "Cannot 
access static:: when no class scope is active");
                                        }
                                        ce = &(EG(called_scope));
-                                       found = (*ce != NULL?SUCCESS:FAILURE);
+                                       found = (EG(called_scope) != 
NULL?SUCCESS:FAILURE);
                                        fci->object_pp = 
EG(This)?&EG(This):NULL;
                                        EX(object) = EG(This);
+                                       calling_scope = called_scope = 
EG(called_scope);
                                } else {
                                        zend_class_entry *scope;
                                        scope = EG(active_op_array) ? 
EG(active_op_array)->scope : NULL;
@@ -811,12 +817,12 @@
                                        } else {
                                                fci->object_pp = NULL;
                                        }
+                                       calling_scope = called_scope = *ce;
                                }
                                if (found == FAILURE)
                                        return FAILURE;
 
                                fci->function_table = &(*ce)->function_table;
-                               calling_scope = *ce;
                        } else {
                                zend_error(E_NOTICE, "Non-callable array passed 
to zend_call_function()");
                                return FAILURE;
@@ -829,6 +835,7 @@
 
                if (Z_TYPE_P(fci->function_name) == IS_OBJECT) {
                        if (zend_get_closure(fci->function_name, 
&calling_scope, &EX(function_state).function, NULL, &fci->object_pp TSRMLS_CC) 
== SUCCESS) {
+                               called_scope = calling_scope;
                                goto init_fci_cache;
                        }
                } else if (Z_TYPE_P(fci->function_name) != IS_STRING) {
@@ -865,20 +872,34 @@
                
                                lcname = zend_str_tolower_dup(cname, clen);
                                /* caution: lcname is not '\0' terminated */
-                               if (calling_scope && clen == sizeof("self") - 1 
&&
+                               if (clen == sizeof("self") - 1 &&
                                        memcmp(lcname, "self", sizeof("self") - 
1) == 0
                                ) {
+                                       if (!EG(active_op_array) || 
!EG(active_op_array)->scope) {
+                                               zend_error(E_ERROR, "Cannot 
access self:: when no class scope is active");
+                                       }
                                        ce_child = EG(active_op_array) ? 
EG(active_op_array)->scope : NULL;
-                               } else if (calling_scope && clen == 
sizeof("parent") - 1 &&
+                                       called_scope = EG(called_scope) ? 
EG(called_scope) : ce_child;
+                               } else if (clen == sizeof("parent") - 1 &&
                                        memcmp(lcname, "parent", 
sizeof("parent") - 1) == 0
                                ) {
-                                       ce_child = EG(active_op_array) && 
EG(active_op_array)->scope ? EG(scope)->parent : NULL;
+                                       if (!EG(active_op_array) || 
!EG(active_op_array)->scope) {
+                                               zend_error(E_ERROR, "Cannot 
access parent:: when no class scope is active");
+                                       }
+                                       if 
(!EG(active_op_array)->scope->parent) {
+                                               zend_error(E_ERROR, "Cannot 
access parent:: when current class scope has no parent");
+                                       }
+                                       ce_child = EG(active_op_array) && 
EG(active_op_array)->scope ? EG(active_op_array)->scope->parent : NULL;
+                                       called_scope = EG(called_scope) ? 
EG(called_scope) : ce_child;
                                } else if (clen == sizeof("static") - 1 &&
                                        memcmp(lcname, "static", 
sizeof("static") - 1)
                                ) {
-                                       ce_child = EG(called_scope);
+                                       if (!EG(called_scope)) {
+                                               zend_error(E_ERROR, "Cannot 
access static:: when no class scope is active");
+                                       }
+                                       called_scope = ce_child = 
EG(called_scope);
                                } else if (zend_lookup_class(lcname, clen, &pce 
TSRMLS_CC) == SUCCESS) {
-                                       ce_child = *pce;
+                                       called_scope = ce_child = *pce;
                                }
                                efree(lcname);
                                
@@ -949,11 +970,13 @@
                        fci_cache->function_handler = 
EX(function_state).function;
                        fci_cache->object_pp = fci->object_pp;
                        fci_cache->calling_scope = calling_scope;
+                       fci_cache->called_scope = called_scope;
                        fci_cache->initialized = 1;
                }
        } else {
                EX(function_state).function = fci_cache->function_handler;
                calling_scope = fci_cache->calling_scope;
+               called_scope = fci_cache->called_scope;
                fci->object_pp = fci_cache->object_pp;
                EX(object) = fci->object_pp ? *fci->object_pp : NULL;
                if (fci->object_pp && *fci->object_pp && 
Z_TYPE_PP(fci->object_pp) == IS_OBJECT
@@ -1048,8 +1071,8 @@
        current_this = EG(This);
 
        current_called_scope = EG(called_scope);
-       if (calling_scope) {
-               EG(called_scope) = calling_scope;
+       if (called_scope) {
+               EG(called_scope) = called_scope;
        } else if (EX(function_state).function->type != ZEND_INTERNAL_FUNCTION) 
{
                EG(called_scope) = NULL;
        }
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_interfaces.c?r1=1.33.2.4.2.6.2.4&r2=1.33.2.4.2.6.2.5&diff_format=u
Index: ZendEngine2/zend_interfaces.c
diff -u ZendEngine2/zend_interfaces.c:1.33.2.4.2.6.2.4 
ZendEngine2/zend_interfaces.c:1.33.2.4.2.6.2.5
--- ZendEngine2/zend_interfaces.c:1.33.2.4.2.6.2.4      Thu Jan 24 18:07:45 2008
+++ ZendEngine2/zend_interfaces.c       Thu Jul 24 09:42:15 2008
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_interfaces.c,v 1.33.2.4.2.6.2.4 2008/01/24 18:07:45 dmitry Exp $ 
*/
+/* $Id: zend_interfaces.c,v 1.33.2.4.2.6.2.5 2008/07/24 09:42:15 dmitry Exp $ 
*/
 
 #include "zend.h"
 #include "zend_API.h"
@@ -84,6 +84,7 @@
                        fcic.function_handler = *fn_proxy;
                }
                fcic.calling_scope = obj_ce;
+               fcic.called_scope = object_pp ? obj_ce : EG(called_scope);
                fcic.object_pp = object_pp;
                result = zend_call_function(&fci, &fcic TSRMLS_CC);
        }
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.59.2.29.2.48.2.60&r2=1.59.2.29.2.48.2.61&diff_format=u
Index: ZendEngine2/zend_vm_def.h
diff -u ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.60 
ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.61
--- ZendEngine2/zend_vm_def.h:1.59.2.29.2.48.2.60       Mon Jul 14 12:18:20 2008
+++ ZendEngine2/zend_vm_def.h   Thu Jul 24 09:42:15 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.60 2008/07/14 12:18:20 dmitry Exp $ */
+/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.61 2008/07/24 09:42:15 dmitry Exp $ */
 
 /* If you change this file, please regenerate the zend_vm_execute.h and
  * zend_vm_opcodes.h files by running:
@@ -1937,8 +1937,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+               
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(OP2_TYPE != IS_UNUSED) {
                char *function_name_strval;
@@ -1980,8 +1987,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.49.2.60&r2=1.62.2.30.2.49.2.61&diff_format=u
Index: ZendEngine2/zend_vm_execute.h
diff -u ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.60 
ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.61
--- ZendEngine2/zend_vm_execute.h:1.62.2.30.2.49.2.60   Mon Jul 14 12:18:20 2008
+++ ZendEngine2/zend_vm_execute.h       Thu Jul 24 09:42:15 2008
@@ -2606,8 +2606,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_CONST != IS_UNUSED) {
                char *function_name_strval;
@@ -2649,8 +2656,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -3194,8 +3199,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_TMP_VAR != IS_UNUSED) {
                char *function_name_strval;
@@ -3237,8 +3249,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -3662,8 +3672,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_VAR != IS_UNUSED) {
                char *function_name_strval;
@@ -3705,8 +3722,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -3886,8 +3901,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_UNUSED != IS_UNUSED) {
                char *function_name_strval;
@@ -3929,8 +3951,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -4322,8 +4342,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_CV != IS_UNUSED) {
                char *function_name_strval;
@@ -4365,8 +4392,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -10260,8 +10285,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_CONST != IS_UNUSED) {
                char *function_name_strval;
@@ -10303,8 +10335,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -12092,8 +12122,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_TMP_VAR != IS_UNUSED) {
                char *function_name_strval;
@@ -12135,8 +12172,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -13894,8 +13929,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_VAR != IS_UNUSED) {
                char *function_name_strval;
@@ -13937,8 +13979,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -14799,8 +14839,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_UNUSED != IS_UNUSED) {
                char *function_name_strval;
@@ -14842,8 +14889,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
@@ -16302,8 +16347,15 @@
                if (!ce) {
                        zend_error(E_ERROR, "Class '%s' not found", 
Z_STRVAL(opline->op1.u.constant));
                }
+               EX(called_scope) = ce;
        } else {
                ce = EX_T(opline->op1.u.var).class_entry;
+
+               if (opline->op1.u.EA.type == ZEND_FETCH_CLASS_PARENT || 
opline->op1.u.EA.type == ZEND_FETCH_CLASS_SELF) {
+                       EX(called_scope) = EG(called_scope);
+               } else {
+                       EX(called_scope) = ce;
+               }
        }
        if(IS_CV != IS_UNUSED) {
                char *function_name_strval;
@@ -16345,8 +16397,6 @@
                EX(fbc) = ce->constructor;
        }
 
-       EX(called_scope) = ce;
-
        if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
                EX(object) = NULL;
        } else {
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug45186.phpt?r1=1.1.2.1&r2=1.1.2.2&diff_format=u
Index: ZendEngine2/tests/bug45186.phpt
diff -u ZendEngine2/tests/bug45186.phpt:1.1.2.1 
ZendEngine2/tests/bug45186.phpt:1.1.2.2
--- ZendEngine2/tests/bug45186.phpt:1.1.2.1     Thu Jun  5 18:33:00 2008
+++ ZendEngine2/tests/bug45186.phpt     Thu Jul 24 09:42:18 2008
@@ -51,4 +51,4 @@
 __callstatic:
 string(3) "www"
 
-Fatal error: Cannot access self:: when no class scope is active in %s on line 
%d
+Warning: call_user_func() expects parameter 1 to be a valid callback, cannot 
access self:: when no class scope is active in %sbug45186.php on line 31
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug45186_2.phpt?r1=1.1.2.1&r2=1.1.2.2&diff_format=u
Index: ZendEngine2/tests/bug45186_2.phpt
diff -u ZendEngine2/tests/bug45186_2.phpt:1.1.2.1 
ZendEngine2/tests/bug45186_2.phpt:1.1.2.2
--- ZendEngine2/tests/bug45186_2.phpt:1.1.2.1   Thu Jun  5 18:33:00 2008
+++ ZendEngine2/tests/bug45186_2.phpt   Thu Jul 24 09:42:18 2008
@@ -47,4 +47,4 @@
 
 Warning: call_user_func() expects parameter 1 to be a valid callback, class 
'bar' does not have a method 'www' in %s on line %d
 
-Fatal error: Cannot access self:: when no class scope is active in %s on line 
%d
+Warning: call_user_func() expects parameter 1 to be a valid callback, cannot 
access self:: when no class scope is active in %sbug45186_2.php on line 27
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/lsb_015.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u
Index: ZendEngine2/tests/lsb_015.phpt
diff -u ZendEngine2/tests/lsb_015.phpt:1.1.2.2 
ZendEngine2/tests/lsb_015.phpt:1.1.2.3
--- ZendEngine2/tests/lsb_015.phpt:1.1.2.2      Sat Sep 29 07:28:34 2007
+++ ZendEngine2/tests/lsb_015.phpt      Thu Jul 24 09:42:18 2008
@@ -86,7 +86,7 @@
 B
 B
 B
-A
-A
+B
+B
 B
 ==DONE==
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/lsb_019.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u
Index: ZendEngine2/tests/lsb_019.phpt
diff -u ZendEngine2/tests/lsb_019.phpt:1.1.2.2 
ZendEngine2/tests/lsb_019.phpt:1.1.2.3
--- ZendEngine2/tests/lsb_019.phpt:1.1.2.2      Mon Mar  3 15:07:04 2008
+++ ZendEngine2/tests/lsb_019.phpt      Thu Jul 24 09:42:18 2008
@@ -1,5 +1,5 @@
 --TEST--
-Test LSB of properties and methods declared as protected and overridden as 
public. 
+ZE2 Late Static Binding properties and methods declared as protected and 
overridden as public. 
 --FILE--
 <?php
 class TestClass {
@@ -45,4 +45,4 @@
 ChildClassStatic
 ChildClassFunction
 TestClassStatic
-TestClassFunction
\ No newline at end of file
+TestClassFunction
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/lsb_020.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u
Index: ZendEngine2/tests/lsb_020.phpt
diff -u ZendEngine2/tests/lsb_020.phpt:1.1.2.2 
ZendEngine2/tests/lsb_020.phpt:1.1.2.3
--- ZendEngine2/tests/lsb_020.phpt:1.1.2.2      Mon Mar  3 15:07:04 2008
+++ ZendEngine2/tests/lsb_020.phpt      Thu Jul 24 09:42:18 2008
@@ -1,5 +1,5 @@
 --TEST--
-Test LSB of properties and methods declared as public and overridden as 
public. 
+ZE2 Late Static Binding properties and methods declared as public and 
overridden as public. 
 --FILE--
 <?php
 class TestClass {
@@ -45,4 +45,4 @@
 ChildClassStatic
 ChildClassFunction
 TestClassStatic
-TestClassFunction
\ No newline at end of file
+TestClassFunction
http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/objects_027.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u
Index: ZendEngine2/tests/objects_027.phpt
diff -u ZendEngine2/tests/objects_027.phpt:1.1.2.2 
ZendEngine2/tests/objects_027.phpt:1.1.2.3
--- ZendEngine2/tests/objects_027.phpt:1.1.2.2  Sun May 11 22:44:56 2008
+++ ZendEngine2/tests/objects_027.phpt  Thu Jul 24 09:42:18 2008
@@ -30,7 +30,7 @@
 Strict Standards: Non-static method foo::test() should not be called 
statically in %s on line %d
 
 Strict Standards: Non-static method bar::show() should not be called 
statically in %s on line %d
-object(bar)#%d (0) {
+object(foo)#%d (0) {
 }
 object(foo)#%d (0) {
 }
@@ -40,7 +40,7 @@
 Strict Standards: Non-static method foo::test() should not be called 
statically in %s on line %d
 
 Strict Standards: Non-static method bar::show() should not be called 
statically in %s on line %d
-object(bar)#%d (0) {
+object(foo)#%d (0) {
 }
 
 
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/php_spl.c?r1=1.52.2.28.2.17.2.23&r2=1.52.2.28.2.17.2.24&diff_format=u
Index: php-src/ext/spl/php_spl.c
diff -u php-src/ext/spl/php_spl.c:1.52.2.28.2.17.2.23 
php-src/ext/spl/php_spl.c:1.52.2.28.2.17.2.24
--- php-src/ext/spl/php_spl.c:1.52.2.28.2.17.2.23       Tue Jul 22 22:54:35 2008
+++ php-src/ext/spl/php_spl.c   Thu Jul 24 09:42:18 2008
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: php_spl.c,v 1.52.2.28.2.17.2.23 2008/07/22 22:54:35 helly Exp $ */
+/* $Id: php_spl.c,v 1.52.2.28.2.17.2.24 2008/07/24 09:42:18 dmitry Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -433,6 +433,7 @@
        zend_function *spl_func_ptr;
        autoload_func_info alfi;
        zval **obj_ptr;
+       zend_fcall_info_cache fcc;
 
        if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() 
TSRMLS_CC, "|zbb", &zcallable, &do_throw, &prepend) == FAILURE) {
                return;
@@ -450,7 +451,10 @@
                        }
                }
        
-               if (!zend_is_callable_ex(zcallable, IS_CALLABLE_STRICT, 
&func_name, &func_name_len, &alfi.ce, &alfi.func_ptr, &obj_ptr, &error 
TSRMLS_CC)) {
+               if (!zend_is_callable_ex(zcallable, IS_CALLABLE_STRICT, 
&func_name, &func_name_len, &fcc, &error TSRMLS_CC)) {
+                       alfi.ce = fcc.calling_scope;
+                       alfi.func_ptr = fcc.function_handler;
+                       obj_ptr = fcc.object_pp;
                        if (Z_TYPE_P(zcallable) == IS_ARRAY) {
                                if (!obj_ptr && alfi.func_ptr && 
!(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
                                        if (do_throw) {
@@ -490,6 +494,9 @@
                                RETURN_FALSE;
                        }
                }
+               alfi.ce = fcc.calling_scope;
+               alfi.func_ptr = fcc.function_handler;
+               obj_ptr = fcc.object_pp;
                if (error) {
                        efree(error);
                }
@@ -560,12 +567,13 @@
        int success = FAILURE;
        zend_function *spl_func_ptr;
        zval **obj_ptr;
+       zend_fcall_info_cache fcc;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zcallable) 
== FAILURE) {
                return;
        }
 
-       if (!zend_is_callable_ex(zcallable, IS_CALLABLE_CHECK_SYNTAX_ONLY, 
&func_name, &func_name_len, NULL, NULL, &obj_ptr, &error TSRMLS_CC)) {
+       if (!zend_is_callable_ex(zcallable, IS_CALLABLE_CHECK_SYNTAX_ONLY, 
&func_name, &func_name_len, &fcc, &error TSRMLS_CC)) {
                zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, 
"Unable to unregister invalid function (%s)", error);
                if (error) {
                        efree(error);
@@ -575,6 +583,7 @@
                }
                RETURN_FALSE;
        }
+       obj_ptr = fcc.object_pp;
        if (error) {
                efree(error);
        }
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.725.2.31.2.64.2.39&r2=1.725.2.31.2.64.2.40&diff_format=u
Index: php-src/ext/standard/basic_functions.c
diff -u php-src/ext/standard/basic_functions.c:1.725.2.31.2.64.2.39 
php-src/ext/standard/basic_functions.c:1.725.2.31.2.64.2.40
--- php-src/ext/standard/basic_functions.c:1.725.2.31.2.64.2.39 Wed Jul 23 
19:34:35 2008
+++ php-src/ext/standard/basic_functions.c      Thu Jul 24 09:42:18 2008
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: basic_functions.c,v 1.725.2.31.2.64.2.39 2008/07/23 19:34:35 felipe 
Exp $ */
+/* $Id: basic_functions.c,v 1.725.2.31.2.64.2.40 2008/07/24 09:42:18 dmitry 
Exp $ */
 
 #include "php.h"
 #include "php_streams.h"
@@ -5204,7 +5204,7 @@
 
        if (EG(called_scope) &&
                instanceof_function(EG(called_scope), fci_cache.calling_scope 
TSRMLS_CC)) {
-                       fci_cache.calling_scope = EG(called_scope);
+                       fci_cache.called_scope = EG(called_scope);
        }
        
        if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && 
fci.retval_ptr_ptr && *fci.retval_ptr_ptr) {
@@ -5234,7 +5234,7 @@
 
        if (EG(called_scope) &&
                instanceof_function(EG(called_scope), fci_cache.calling_scope 
TSRMLS_CC)) {
-                       fci_cache.calling_scope = EG(called_scope);
+                       fci_cache.called_scope = EG(called_scope);
        }
 
        if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && 
fci.retval_ptr_ptr && *fci.retval_ptr_ptr) {
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/array/array_map_object2.phpt?r1=1.1.2.3&r2=1.1.2.4&diff_format=u
Index: php-src/ext/standard/tests/array/array_map_object2.phpt
diff -u php-src/ext/standard/tests/array/array_map_object2.phpt:1.1.2.3 
php-src/ext/standard/tests/array/array_map_object2.phpt:1.1.2.4
--- php-src/ext/standard/tests/array/array_map_object2.phpt:1.1.2.3     Sat Feb 
 2 01:51:17 2008
+++ php-src/ext/standard/tests/array/array_map_object2.phpt     Thu Jul 24 
09:42:18 2008
@@ -37,7 +37,7 @@
 *** Testing array_map() :  with non-existent class and method ***
 -- with non-existent class --
 
-Warning: array_map() expects parameter 1 to be a valid callback, first array 
member is not a valid class name in %s on line %d
+Warning: array_map() expects parameter 1 to be a valid callback, class 
'non-existent' not found in %s on line %d
 NULL
 -- with existent class and non-existent method --
 

http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/lsb_021.phpt?view=markup&rev=1.1
Index: ZendEngine2/tests/lsb_021.phpt
+++ ZendEngine2/tests/lsb_021.phpt

http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/lsb_022.phpt?view=markup&rev=1.1
Index: ZendEngine2/tests/lsb_022.phpt
+++ ZendEngine2/tests/lsb_022.phpt

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to