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